diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/alpha/kernel/alpha_ksyms.c linux.21pre4-ac6/arch/alpha/kernel/alpha_ksyms.c --- linux.21pre4/arch/alpha/kernel/alpha_ksyms.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/alpha/kernel/alpha_ksyms.c 2003-02-06 17:37:03.000000000 +0000 @@ -121,7 +121,7 @@ EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__delay); -EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(ndelay); EXPORT_SYMBOL(udelay); EXPORT_SYMBOL(__direct_map_base); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/alpha/kernel/process.c linux.21pre4-ac6/arch/alpha/kernel/process.c --- linux.21pre4/arch/alpha/kernel/process.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/alpha/kernel/process.c 2003-01-29 17:10:04.000000000 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -74,9 +75,6 @@ cpu_idle(void) { /* An endless idle loop with no priority at all. */ - current->nice = 20; - current->counter = -100; - while (1) { /* FIXME -- EV6 and LCA45 know how to power down the CPU. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/alpha/kernel/smp.c linux.21pre4-ac6/arch/alpha/kernel/smp.c --- linux.21pre4/arch/alpha/kernel/smp.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/alpha/kernel/smp.c 2003-01-29 17:10:04.000000000 +0000 @@ -81,6 +81,7 @@ int smp_num_probed; /* Internal processor count */ int smp_num_cpus = 1; /* Number that came online. */ int smp_threads_ready; /* True once the per process idle is forked. */ +unsigned long cache_decay_ticks; int __cpu_number_map[NR_CPUS]; int __cpu_logical_map[NR_CPUS]; @@ -155,11 +156,6 @@ { int cpuid = hard_smp_processor_id(); - if (current != init_tasks[cpu_number_map(cpuid)]) { - printk("BUG: smp_calling: cpu %d current %p init_tasks[cpu_number_map(cpuid)] %p\n", - cpuid, current, init_tasks[cpu_number_map(cpuid)]); - } - DBGS(("CALLIN %d state 0x%lx\n", cpuid, current->state)); /* Turn on machine checks. */ @@ -217,9 +213,6 @@ DBGS(("smp_callin: commencing CPU %d current %p\n", cpuid, current)); - /* Setup the scheduler for this processor. */ - init_idle(); - /* ??? This should be in init_idle. */ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; @@ -449,14 +442,11 @@ if (idle == &init_task) panic("idle process is init_task for CPU %d", cpuid); - idle->processor = cpuid; - idle->cpus_runnable = 1 << cpuid; /* we schedule the first task manually */ + init_idle(idle, cpuid); + unhash_process(idle); + __cpu_logical_map[cpunum] = cpuid; __cpu_number_map[cpuid] = cpunum; - - del_from_runqueue(idle); - unhash_process(idle); - init_tasks[cpunum] = idle; DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n", cpuid, idle->state, idle->flags)); @@ -563,13 +553,10 @@ __cpu_number_map[boot_cpuid] = 0; __cpu_logical_map[0] = boot_cpuid; - current->processor = boot_cpuid; smp_store_cpu_info(boot_cpuid); smp_setup_percpu_timer(boot_cpuid); - init_idle(); - /* ??? This should be in init_idle. */ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/alpha/lib/udelay.c linux.21pre4-ac6/arch/alpha/lib/udelay.c --- linux.21pre4/arch/alpha/lib/udelay.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/alpha/lib/udelay.c 2003-02-06 17:37:03.000000000 +0000 @@ -18,7 +18,8 @@ * a 1GHz box, that's about 2 seconds. */ -void __delay(int loops) +void +__delay(int loops) { int tmp; __asm__ __volatile__( @@ -30,18 +31,22 @@ : "=&r" (tmp), "=r" (loops) : "1"(loops)); } -void __udelay(unsigned long usecs, unsigned long lpj) -{ - usecs *= (((unsigned long)HZ << 32) / 1000000) * lpj; - __delay((long)usecs >> 32); -} - -void udelay(unsigned long usecs) -{ #ifdef CONFIG_SMP - __udelay(usecs, cpu_data[smp_processor_id()].loops_per_jiffy); +#define LPJ cpu_data[smp_processor_id()].loops_per_jiffy #else - __udelay(usecs, loops_per_jiffy); +#define LPJ loops_per_jiffy #endif + +void +ndelay(unsigned long nsecs) +{ + nsecs *= (((unsigned long)HZ << 32) / 1000000000) * LPJ; + __delay((long)nsecs >> 32); } +void +udelay(unsigned long usecs) +{ + usecs *= (((unsigned long)HZ << 32) / 1000000) * LPJ; + __delay((long)usecs >> 32); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/alpha/mm/fault.c linux.21pre4-ac6/arch/alpha/mm/fault.c --- linux.21pre4/arch/alpha/mm/fault.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/alpha/mm/fault.c 2003-01-06 19:10:18.000000000 +0000 @@ -122,8 +122,6 @@ goto bad_area; if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (expand_stack(vma, address)) goto bad_area; /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/arm/config.in linux.21pre4-ac6/arch/arm/config.in --- linux.21pre4/arch/arm/config.in 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/arm/config.in 2003-01-06 15:41:35.000000000 +0000 @@ -646,6 +646,7 @@ bool 'Kernel debugging' CONFIG_DEBUG_KERNEL dep_bool ' Debug memory allocations' CONFIG_DEBUG_SLAB $CONFIG_DEBUG_KERNEL dep_bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_DEBUG_KERNEL +dep_bool ' Morse code panics' CONFIG_PANIC_MORSE $CONFIG_DEBUG_KERNEL $CONFIG_PC_KEYB dep_bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK $CONFIG_DEBUG_KERNEL dep_bool ' Wait queue debugging' CONFIG_DEBUG_WAITQ $CONFIG_DEBUG_KERNEL dep_bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE $CONFIG_DEBUG_KERNEL diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/arm/mm/fault-common.c linux.21pre4-ac6/arch/arm/mm/fault-common.c --- linux.21pre4/arch/arm/mm/fault-common.c 2003-01-29 16:27:15.000000000 +0000 +++ linux.21pre4-ac6/arch/arm/mm/fault-common.c 2003-01-06 19:10:18.000000000 +0000 @@ -229,7 +229,7 @@ goto survive; check_stack: - if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) + if (!expand_stack(vma, addr)) goto good_area; out: return fault; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/cris/drivers/eeprom.c linux.21pre4-ac6/arch/cris/drivers/eeprom.c --- linux.21pre4/arch/cris/drivers/eeprom.c 2003-01-29 16:27:20.000000000 +0000 +++ linux.21pre4-ac6/arch/cris/drivers/eeprom.c 2003-02-06 22:31:53.000000000 +0000 @@ -808,7 +808,7 @@ i2c_outbyte( eeprom.select_cmd | 1 ); } - if(i2c_getack()); + if(i2c_getack()) { break; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/boot/setup.S linux.21pre4-ac6/arch/i386/boot/setup.S --- linux.21pre4/arch/i386/boot/setup.S 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/boot/setup.S 2003-01-08 15:33:39.000000000 +0000 @@ -45,6 +45,10 @@ * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes * by Robert Schwebel, December 2001 * + * BIOS Enhanced Disk Drive support + * by Matt Domsch October 2002 + * conformant to T13 Committee www.t13.org + * projects 1572D, 1484D, 1386D, 1226DT */ #include @@ -53,6 +57,7 @@ #include #include #include +#include #include /* Signature words to ensure LILO loaded us right */ @@ -543,6 +548,70 @@ done_apm_bios: #endif +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +# Do the BIOS Enhanced Disk Drive calls +# This consists of two calls: +# int 13h ah=41h "Check Extensions Present" +# int 13h ah=48h "Get Device Parameters" +# +# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use +# in the empty_zero_page at EDDBUF. The first four bytes of which are +# used to store the device number, interface support map and version +# results from fn41. The following 74 bytes are used to store +# the results from fn48. Starting from device 80h, fn41, then fn48 +# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE). +# Then the pointer is incremented to store the data for the next call. +# This repeats until either a device doesn't exist, or until EDDMAXNR +# devices have been stored. +# The one tricky part is that ds:si always points four bytes into +# the structure, and the fn41 results are stored at offsets +# from there. This removes the need to increment the pointer for +# every store, and leaves it ready for the fn48 call. +# A second one-byte buffer, EDDNR, in the empty_zero_page stores +# the number of BIOS devices which exist, up to EDDMAXNR. +# In setup.c, copy_edd() stores both empty_zero_page buffers away +# for later use, as they would get overwritten otherwise. +# This code is sensitive to the size of the structs in edd.h +edd_start: + # %ds points to the bootsector + # result buffer for fn48 + movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results + # kept just before that + movb $0, (EDDNR) # zero value at EDDNR + movb $0x80, %dl # BIOS device 0x80 + +edd_check_ext: + movb $CHECKEXTENSIONSPRESENT, %ah # Function 41 + movw $EDDMAGIC1, %bx # magic + int $0x13 # make the call + jc edd_done # no more BIOS devices + + cmpw $EDDMAGIC2, %bx # is magic right? + jne edd_next # nope, next... + + movb %dl, %ds:-4(%si) # store device number + movb %ah, %ds:-3(%si) # store version + movw %cx, %ds:-2(%si) # store extensions + incb (EDDNR) # note that we stored something + +edd_get_device_params: + movw $EDDPARMSIZE, %ds:(%si) # put size + movb $GETDEVICEPARAMETERS, %ah # Function 48 + int $0x13 # make the call + # Don't check for fail return + # it doesn't matter. + movw %si, %ax # increment si + addw $EDDPARMSIZE+EDDEXTSIZE, %ax + movw %ax, %si + +edd_next: + incb %dl # increment to next device + cmpb $EDDMAXNR, (EDDNR) # Out of space? + jb edd_check_ext # keep looping + +edd_done: +#endif + # Now we want to move to protected mode ... cmpw $0, %cs:realmode_swtch jz rmodeswtch_normal diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/config.in linux.21pre4-ac6/arch/i386/config.in --- linux.21pre4/arch/i386/config.in 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/config.in 2003-01-29 17:11:02.000000000 +0000 @@ -185,6 +185,23 @@ bool 'Machine Check Exception' CONFIG_X86_MCE +mainmenu_option next_comment +comment 'CPU Frequency scaling' +dep_bool 'CPU Frequency scaling (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL +if [ "$CONFIG_CPU_FREQ" = "y" ]; then + bool ' /proc/sys/cpu/ interface (2.4. / OLD)' CONFIG_CPU_FREQ_24_API + tristate ' AMD Mobile K6-2/K6-3 PowerNow!' CONFIG_X86_POWERNOW_K6 + if [ "$CONFIG_MELAN" = "y" ]; then + tristate ' AMD Elan' CONFIG_ELAN_CPUFREQ + fi + tristate ' VIA Cyrix III Longhaul' CONFIG_X86_LONGHAUL + tristate ' Intel Speedstep' CONFIG_X86_SPEEDSTEP + tristate ' Intel Pentium 4 clock modulation' CONFIG_X86_P4_CLOCKMOD + tristate ' Transmeta LongRun' CONFIG_X86_LONGRUN + tristate ' Cyrix MediaGX/NatSemi Geode Suspend Modulation' CONFIG_X86_GX_SUSPMOD +fi +endmenu + tristate 'Toshiba Laptop support' CONFIG_TOSHIBA tristate 'Dell laptop support' CONFIG_I8K @@ -192,6 +209,10 @@ tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD +fi + choice 'High Memory Support' \ "off CONFIG_NOHIGHMEM \ 4GB CONFIG_HIGHMEM4G \ @@ -283,6 +304,8 @@ bool 'ISA bus support' CONFIG_ISA fi +tristate 'NatSemi SCx200 support' CONFIG_SCx200 + source drivers/pci/Config.in bool 'EISA support' CONFIG_EISA @@ -315,6 +338,8 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Kernel .config support' CONFIG_IKCONFIG + bool 'Power Management support' CONFIG_PM if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then @@ -465,12 +490,13 @@ bool 'Kernel debugging' CONFIG_DEBUG_KERNEL if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then bool ' Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW + bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER bool ' Debug high memory support' CONFIG_DEBUG_HIGHMEM bool ' Debug memory allocations' CONFIG_DEBUG_SLAB bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ + bool ' Morse code panics' CONFIG_PANIC_MORSE bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK - bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER fi endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/defconfig linux.21pre4-ac6/arch/i386/defconfig --- linux.21pre4/arch/i386/defconfig 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/defconfig 2003-01-08 15:33:39.000000000 +0000 @@ -56,6 +56,7 @@ # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set # CONFIG_X86_CPUID is not set +# CONFIG_EDD is not set CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/dmi_scan.c linux.21pre4-ac6/arch/i386/kernel/dmi_scan.c --- linux.21pre4/arch/i386/kernel/dmi_scan.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/dmi_scan.c 2003-01-29 17:11:37.000000000 +0000 @@ -427,17 +427,6 @@ } /* - * ASUS K7V-RM has broken ACPI table defining sleep modes - */ - -static __init int broken_acpi_Sx(struct dmi_blacklist *d) -{ - printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n"); - dmi_broken |= BROKEN_ACPI_Sx; - return 0; -} - -/* * Toshiba keyboard likes to repeat keys when they are not repeated. */ @@ -764,12 +753,6 @@ NO_MATCH, NO_MATCH, NO_MATCH } }, - { broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */ - MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"), - MATCH(DMI_BOARD_NAME, ""), - NO_MATCH, NO_MATCH - } }, - { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), NO_MATCH, NO_MATCH, NO_MATCH diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/edd.c linux.21pre4-ac6/arch/i386/kernel/edd.c --- linux.21pre4/arch/i386/kernel/edd.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/edd.c 2003-01-28 16:15:24.000000000 +0000 @@ -0,0 +1,672 @@ +/* + * linux/arch/i386/kernel/edd.c + * Copyright (C) 2002 Dell Computer Corporation + * by Matt Domsch + * + * BIOS Enhanced Disk Drive Services (EDD) + * conformant to T13 Committee www.t13.org + * projects 1572D, 1484D, 1386D, 1226DT + * + * This code takes information provided by BIOS EDD calls + * fn41 - Check Extensions Present and + * fn48 - Get Device Parametes with EDD extensions + * made in setup.S, copied to safe structures in setup.c, + * and presents it in /proc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by + * the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* + * TODO: + * - move edd.[ch] to better locations if/when one is decided + * - keep current with 2.5 EDD code changes + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Matt Domsch "); +MODULE_DESCRIPTION("proc interface to BIOS EDD information"); +MODULE_LICENSE("GPL"); + +#define EDD_VERSION "0.09 2003-Jan-22" +#define EDD_DEVICE_NAME_SIZE 16 +#define REPORT_URL "http://domsch.com/linux/edd30/results.html" + +#define left (count - (p - page) - 1) + +static struct proc_dir_entry *bios_dir; + +struct attr_entry { + struct proc_dir_entry *entry; + struct list_head node; +}; + +struct edd_device { + char name[EDD_DEVICE_NAME_SIZE]; + struct edd_info *info; + struct proc_dir_entry *dir; + struct list_head attr_list; +}; + +static struct edd_device *edd_devices[EDDMAXNR]; + +struct edd_attribute { + char *name; + int (*show)(char *page, char **start, off_t off, + int count, int *eof, void *data); + int (*test) (struct edd_device * edev); +}; + +#define EDD_DEVICE_ATTR(_name,_show,_test) \ +struct edd_attribute edd_attr_##_name = { \ + .name = __stringify(_name), \ + .show = _show, \ + .test = _test, \ +}; + +static inline struct edd_info * +edd_dev_get_info(struct edd_device *edev) +{ + return edev->info; +} + +static inline void +edd_dev_set_info(struct edd_device *edev, struct edd_info *info) +{ + edev->info = info; +} + +static int +proc_calc_metrics(char *page, char **start, off_t off, + int count, int *eof, int len) +{ + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static int +edd_dump_raw_data(char *b, int count, void *data, int length) +{ + char *orig_b = b; + char hexbuf[80], ascbuf[20], *h, *a, c; + unsigned char *p = data; + unsigned long column = 0; + int length_printed = 0, d; + const char maxcolumn = 16; + while (length_printed < length && count > 0) { + h = hexbuf; + a = ascbuf; + for (column = 0; + column < maxcolumn && length_printed < length; column++) { + h += sprintf(h, "%02x ", (unsigned char) *p); + if (!isprint(*p)) + c = '.'; + else + c = *p; + a += sprintf(a, "%c", c); + p++; + length_printed++; + } + /* pad out the line */ + for (; column < maxcolumn; column++) { + h += sprintf(h, " "); + a += sprintf(a, " "); + } + d = snprintf(b, count, "%s\t%s\n", hexbuf, ascbuf); + b += d; + count -= d; + } + return (b - orig_b); +} + +static int +edd_show_host_bus(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + int i; + + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + for (i = 0; i < 4; i++) { + if (isprint(info->params.host_bus_type[i])) { + p += snprintf(p, left, "%c", info->params.host_bus_type[i]); + } else { + p += snprintf(p, left, " "); + } + } + + if (!strncmp(info->params.host_bus_type, "ISA", 3)) { + p += snprintf(p, left, "\tbase_address: %x\n", + info->params.interface_path.isa.base_address); + } else if (!strncmp(info->params.host_bus_type, "PCIX", 4) || + !strncmp(info->params.host_bus_type, "PCI", 3)) { + p += snprintf(p, left, + "\t%02x:%02x.%d channel: %u\n", + info->params.interface_path.pci.bus, + info->params.interface_path.pci.slot, + info->params.interface_path.pci.function, + info->params.interface_path.pci.channel); + } else if (!strncmp(info->params.host_bus_type, "IBND", 4) || + !strncmp(info->params.host_bus_type, "XPRS", 4) || + !strncmp(info->params.host_bus_type, "HTPT", 4)) { + p += snprintf(p, left, + "\tTBD: %llx\n", + info->params.interface_path.ibnd.reserved); + + } else { + p += snprintf(p, left, "\tunknown: %llx\n", + info->params.interface_path.unknown.reserved); + } + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_interface(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + int i; + + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + for (i = 0; i < 8; i++) { + if (isprint(info->params.interface_type[i])) { + p += snprintf(p, left, "%c", info->params.interface_type[i]); + } else { + p += snprintf(p, left, " "); + } + } + if (!strncmp(info->params.interface_type, "ATAPI", 5)) { + p += snprintf(p, left, "\tdevice: %u lun: %u\n", + info->params.device_path.atapi.device, + info->params.device_path.atapi.lun); + } else if (!strncmp(info->params.interface_type, "ATA", 3)) { + p += snprintf(p, left, "\tdevice: %u\n", + info->params.device_path.ata.device); + } else if (!strncmp(info->params.interface_type, "SCSI", 4)) { + p += snprintf(p, left, "\tid: %u lun: %llu\n", + info->params.device_path.scsi.id, + info->params.device_path.scsi.lun); + } else if (!strncmp(info->params.interface_type, "USB", 3)) { + p += snprintf(p, left, "\tserial_number: %llx\n", + info->params.device_path.usb.serial_number); + } else if (!strncmp(info->params.interface_type, "1394", 4)) { + p += snprintf(p, left, "\teui: %llx\n", + info->params.device_path.i1394.eui); + } else if (!strncmp(info->params.interface_type, "FIBRE", 5)) { + p += snprintf(p, left, "\twwid: %llx lun: %llx\n", + info->params.device_path.fibre.wwid, + info->params.device_path.fibre.lun); + } else if (!strncmp(info->params.interface_type, "I2O", 3)) { + p += snprintf(p, left, "\tidentity_tag: %llx\n", + info->params.device_path.i2o.identity_tag); + } else if (!strncmp(info->params.interface_type, "RAID", 4)) { + p += snprintf(p, left, "\tidentity_tag: %x\n", + info->params.device_path.raid.array_number); + } else if (!strncmp(info->params.interface_type, "SATA", 4)) { + p += snprintf(p, left, "\tdevice: %u\n", + info->params.device_path.sata.device); + } else { + p += snprintf(p, left, "\tunknown: %llx %llx\n", + info->params.device_path.unknown.reserved1, + info->params.device_path.unknown.reserved2); + } + + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +/** + * edd_show_raw_data() - unparses EDD information, returned to user-space + * + * Returns: number of bytes written, or 0 on failure + */ +static int +edd_show_raw_data(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + int i, warn_padding = 0, nonzero_path = 0, + len = sizeof (*info) - 4; + uint8_t checksum = 0, c = 0; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) + len = info->params.length; + + p += snprintf(p, left, "int13 fn48 returned data:\n\n"); + p += edd_dump_raw_data(p, left, ((char *) info) + 4, len); + + /* Spec violation. Adaptec AIC7899 returns 0xDDBE + here, when it should be 0xBEDD. + */ + p += snprintf(p, left, "\n"); + if (info->params.key == 0xDDBE) { + p += snprintf(p, left, + "Warning: Spec violation. Key should be 0xBEDD, is 0xDDBE\n"); + } + + if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { + goto out; + } + + for (i = 30; i <= 73; i++) { + c = *(((uint8_t *) info) + i + 4); + if (c) + nonzero_path++; + checksum += c; + } + + if (checksum) { + p += snprintf(p, left, + "Warning: Spec violation. Device Path checksum invalid.\n"); + } + + if (!nonzero_path) { + p += snprintf(p, left, "Error: Spec violation. Empty device path.\n"); + goto out; + } + + for (i = 0; i < 4; i++) { + if (!isprint(info->params.host_bus_type[i])) { + warn_padding++; + } + } + for (i = 0; i < 8; i++) { + if (!isprint(info->params.interface_type[i])) { + warn_padding++; + } + } + + if (warn_padding) { + p += snprintf(p, left, + "Warning: Spec violation. Padding should be 0x20.\n"); + } + +out: + p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL); + p += snprintf(p, left, "to see if this device has been reported. If not,\n"); + p += snprintf(p, left, "please send the information requested there.\n"); + + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_version(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + p += snprintf(p, left, "0x%02x\n", info->version); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_extensions(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) { + p += snprintf(p, left, "Fixed disk access\n"); + } + if (info->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) { + p += snprintf(p, left, "Device locking and ejecting\n"); + } + if (info->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) { + p += snprintf(p, left, "Enhanced Disk Drive support\n"); + } + if (info->interface_support & EDD_EXT_64BIT_EXTENSIONS) { + p += snprintf(p, left, "64-bit extensions\n"); + } + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_info_flags(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + if (info->params.info_flags & EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT) + p += snprintf(p, left, "DMA boundry error transparent\n"); + if (info->params.info_flags & EDD_INFO_GEOMETRY_VALID) + p += snprintf(p, left, "geometry valid\n"); + if (info->params.info_flags & EDD_INFO_REMOVABLE) + p += snprintf(p, left, "removable\n"); + if (info->params.info_flags & EDD_INFO_WRITE_VERIFY) + p += snprintf(p, left, "write verify\n"); + if (info->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION) + p += snprintf(p, left, "media change notification\n"); + if (info->params.info_flags & EDD_INFO_LOCKABLE) + p += snprintf(p, left, "lockable\n"); + if (info->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT) + p += snprintf(p, left, "no media present\n"); + if (info->params.info_flags & EDD_INFO_USE_INT13_FN50) + p += snprintf(p, left, "use int13 fn50\n"); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_default_cylinders(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + p += snprintf(p, left, "0x%x\n", info->params.num_default_cylinders); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_default_heads(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + p += snprintf(p, left, "0x%x\n", info->params.num_default_heads); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_default_sectors_per_track(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + p += snprintf(p, left, "0x%x\n", info->params.sectors_per_track); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_show_sectors(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct edd_info *info = data; + char *p = page; + if (!info || !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + p += snprintf(p, left, "0x%llx\n", info->params.number_of_sectors); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int +edd_has_default_cylinders(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return 0; + return info->params.num_default_cylinders > 0; +} + +static int +edd_has_default_heads(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return 0; + return info->params.num_default_heads > 0; +} + +static int +edd_has_default_sectors_per_track(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return 0; + return info->params.sectors_per_track > 0; +} + +static int +edd_has_edd30(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + int i, nonzero_path = 0; + char c; + + if (!edev || !info) + return 0; + + if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { + return 0; + } + + for (i = 30; i <= 73; i++) { + c = *(((uint8_t *) info) + i + 4); + if (c) { + nonzero_path++; + break; + } + } + if (!nonzero_path) { + return 0; + } + + return 1; +} + +static EDD_DEVICE_ATTR(raw_data, edd_show_raw_data, NULL); +static EDD_DEVICE_ATTR(version, edd_show_version, NULL); +static EDD_DEVICE_ATTR(extensions, edd_show_extensions, NULL); +static EDD_DEVICE_ATTR(info_flags, edd_show_info_flags, NULL); +static EDD_DEVICE_ATTR(sectors, edd_show_sectors, NULL); +static EDD_DEVICE_ATTR(default_cylinders, edd_show_default_cylinders, + edd_has_default_cylinders); +static EDD_DEVICE_ATTR(default_heads, edd_show_default_heads, + edd_has_default_heads); +static EDD_DEVICE_ATTR(default_sectors_per_track, + edd_show_default_sectors_per_track, + edd_has_default_sectors_per_track); +static EDD_DEVICE_ATTR(interface, edd_show_interface,edd_has_edd30); +static EDD_DEVICE_ATTR(host_bus, edd_show_host_bus, edd_has_edd30); + +static struct edd_attribute *def_attrs[] = { + &edd_attr_raw_data, + &edd_attr_version, + &edd_attr_extensions, + &edd_attr_info_flags, + &edd_attr_sectors, + &edd_attr_default_cylinders, + &edd_attr_default_heads, + &edd_attr_default_sectors_per_track, + &edd_attr_interface, + &edd_attr_host_bus, + NULL, +}; + +static inline void +edd_device_unregister(struct edd_device *edev) +{ + struct list_head *pos, *next; + struct attr_entry *ae; + + list_for_each_safe(pos, next, &edev->attr_list) { + ae = list_entry(pos, struct attr_entry, node); + remove_proc_entry(ae->entry->name, edev->dir); + list_del(&ae->node); + kfree(ae); + } + + remove_proc_entry(edev->dir->name, bios_dir); +} + +static int +edd_populate_dir(struct edd_device *edev) +{ + struct edd_attribute *attr; + struct attr_entry *ae; + int i; + int error = 0; + + for (i = 0; (attr=def_attrs[i]); i++) { + if (!attr->test || (attr->test && attr->test(edev))) { + ae = kmalloc(sizeof (*ae), GFP_KERNEL); + if (ae == NULL) { + error = 1; + break; + } + INIT_LIST_HEAD(&ae->node); + ae->entry = + create_proc_read_entry(attr->name, 0444, + edev->dir, attr->show, + edd_dev_get_info(edev)); + if (ae->entry == NULL) { + error = 1; + break; + } + list_add(&ae->node, &edev->attr_list); + } + } + + if (error) + return error; + + return 0; +} + +static int +edd_make_dir(struct edd_device *edev) +{ + int error=1; + + edev->dir = proc_mkdir(edev->name, bios_dir); + if (edev->dir != NULL) { + edev->dir->mode = (S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO); + error = edd_populate_dir(edev); + } + return error; +} + +static int +edd_device_register(struct edd_device *edev, int i) +{ + int error; + + if (!edev) + return 1; + memset(edev, 0, sizeof (*edev)); + INIT_LIST_HEAD(&edev->attr_list); + edd_dev_set_info(edev, &edd[i]); + snprintf(edev->name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x", + edd[i].device); + error = edd_make_dir(edev); + return error; +} + +/** + * edd_init() - creates /proc tree of EDD data + * + * This assumes that eddnr and edd were + * assigned in setup.c already. + */ +static int __init +edd_init(void) +{ + unsigned int i; + int rc = 0; + struct edd_device *edev; + + printk(KERN_INFO "BIOS EDD facility v%s, %d devices found\n", + EDD_VERSION, eddnr); + + if (!eddnr) { + printk(KERN_INFO "EDD information not available.\n"); + return 1; + } + + bios_dir = proc_mkdir("bios", NULL); + if (bios_dir == NULL) + return 1; + + for (i = 0; i < eddnr && i < EDDMAXNR && !rc; i++) { + edev = kmalloc(sizeof (*edev), GFP_KERNEL); + if (!edev) { + rc = 1; + break; + } + + rc = edd_device_register(edev, i); + if (rc) { + break; + } + edd_devices[i] = edev; + } + + if (rc) { + for (i = 0; i < eddnr && i < EDDMAXNR; i++) { + if ((edev = edd_devices[i])) { + edd_device_unregister(edev); + kfree(edev); + } + } + + remove_proc_entry(bios_dir->name, NULL); + } + + return rc; +} + +static void __exit +edd_exit(void) +{ + int i; + struct edd_device *edev; + + for (i = 0; i < eddnr && i < EDDMAXNR; i++) { + if ((edev = edd_devices[i])) { + edd_device_unregister(edev); + kfree(edev); + } + } + + remove_proc_entry(bios_dir->name, NULL); +} + +module_init(edd_init); +module_exit(edd_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/elanfreq.c linux.21pre4-ac6/arch/i386/kernel/elanfreq.c --- linux.21pre4/arch/i386/kernel/elanfreq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/elanfreq.c 2003-01-10 16:27:32.000000000 +0000 @@ -0,0 +1,297 @@ +/* + * elanfreq: cpufreq driver for the AMD ELAN family + * + * (c) Copyright 2002 Robert Schwebel + * + * Parts of this code are (c) Sven Geggus + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * 2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ +#define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ + +static struct cpufreq_driver *elanfreq_driver; + +/* Module parameter */ +static int max_freq; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Robert Schwebel , Sven Geggus "); +MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs"); + +struct s_elan_multiplier { + int clock; /* frequency in kHz */ + int val40h; /* PMU Force Mode register */ + int val80h; /* CPU Clock Speed Register */ +}; + +/* + * It is important that the frequencies + * are listed in ascending order here! + */ +struct s_elan_multiplier elan_multiplier[] = { + {1000, 0x02, 0x18}, + {2000, 0x02, 0x10}, + {4000, 0x02, 0x08}, + {8000, 0x00, 0x00}, + {16000, 0x00, 0x02}, + {33000, 0x00, 0x04}, + {66000, 0x01, 0x04}, + {99000, 0x01, 0x05} +}; + +static struct cpufreq_frequency_table elanfreq_table[] = { + {0, 1000}, + {1, 2000}, + {2, 4000}, + {3, 8000}, + {4, 16000}, + {5, 33000}, + {6, 66000}, + {7, 99000}, + {0, CPUFREQ_TABLE_END}, +}; + + +/** + * elanfreq_get_cpu_frequency: determine current cpu speed + * + * Finds out at which frequency the CPU of the Elan SOC runs + * at the moment. Frequencies from 1 to 33 MHz are generated + * the normal way, 66 and 99 MHz are called "Hyperspeed Mode" + * and have the rest of the chip running with 33 MHz. + */ + +static unsigned int elanfreq_get_cpu_frequency(void) +{ + u8 clockspeed_reg; /* Clock Speed Register */ + + local_irq_disable(); + outb_p(0x80,REG_CSCIR); + clockspeed_reg = inb_p(REG_CSCDR); + local_irq_enable(); + + if ((clockspeed_reg & 0xE0) == 0xE0) { return 0; } + + /* Are we in CPU clock multiplied mode (66/99 MHz)? */ + if ((clockspeed_reg & 0xE0) == 0xC0) { + if ((clockspeed_reg & 0x01) == 0) { + return 66000; + } else { + return 99000; + } + } + + /* 33 MHz is not 32 MHz... */ + if ((clockspeed_reg & 0xE0)==0xA0) + return 33000; + + return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000); +} + + +/** + * elanfreq_set_cpu_frequency: Change the CPU core frequency + * @cpu: cpu number + * @freq: frequency in kHz + * + * This function takes a frequency value and changes the CPU frequency + * according to this. Note that the frequency has to be checked by + * elanfreq_validatespeed() for correctness! + * + * There is no return value. + */ + +static void elanfreq_set_cpu_state (unsigned int state) { + + struct cpufreq_freqs freqs; + + if (!elanfreq_driver) { + printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n"); + return; + } + + freqs.old = elanfreq_get_cpu_frequency(); + freqs.new = elan_multiplier[state].clock; + freqs.cpu = 0; /* elanfreq.c is UP only driver */ + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n",elan_multiplier[state].clock); + + + /* + * Access to the Elan's internal registers is indexed via + * 0x22: Chip Setup & Control Register Index Register (CSCI) + * 0x23: Chip Setup & Control Register Data Register (CSCD) + * + */ + + /* + * 0x40 is the Power Management Unit's Force Mode Register. + * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency) + */ + + local_irq_disable(); + outb_p(0x40,REG_CSCIR); /* Disable hyperspeed mode */ + outb_p(0x00,REG_CSCDR); + local_irq_enable(); /* wait till internal pipelines and */ + udelay(1000); /* buffers have cleaned up */ + + local_irq_disable(); + + /* now, set the CPU clock speed register (0x80) */ + outb_p(0x80,REG_CSCIR); + outb_p(elan_multiplier[state].val80h,REG_CSCDR); + + /* now, the hyperspeed bit in PMU Force Mode Register (0x40) */ + outb_p(0x40,REG_CSCIR); + outb_p(elan_multiplier[state].val40h,REG_CSCDR); + udelay(10000); + local_irq_enable(); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +}; + + +/** + * elanfreq_validatespeed: test if frequency range is valid + * + * This function checks if a given frequency range in kHz is valid + * for the hardware supported by the driver. + */ + +static int elanfreq_verify (struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); +} + +static int elanfreq_setpolicy (struct cpufreq_policy *policy) +{ + unsigned int newstate = 0; + + if (cpufreq_frequency_table_setpolicy(policy, &elanfreq_table[0], &newstate)) + return -EINVAL; + + elanfreq_set_cpu_state(newstate); + + return 0; +} + + +/* + * Module init and exit code + */ + +#ifndef MODULE +/** + * elanfreq_setup - elanfreq command line parameter parsing + * + * elanfreq command line parameter. Use: + * elanfreq=66000 + * to set the maximum CPU frequency to 66 MHz. Note that in + * case you do not give this boot parameter, the maximum + * frequency will fall back to _current_ CPU frequency which + * might be lower. If you build this as a module, use the + * max_freq module parameter instead. + */ +static int __init elanfreq_setup(char *str) +{ + max_freq = simple_strtoul(str, &str, 0); + return 1; +} +__setup("elanfreq=", elanfreq_setup); +#endif + +static int __init elanfreq_init(void) +{ + struct cpuinfo_x86 *c = cpu_data; + struct cpufreq_driver *driver; + int ret, i; + + /* Test if we have the right hardware */ + if ((c->x86_vendor != X86_VENDOR_AMD) || + (c->x86 != 4) || (c->x86_model!=10)) + { + printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); + return -ENODEV; + } + + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) + return -ENOMEM; + + driver->policy = (struct cpufreq_policy *) (driver + 1); + + if (!max_freq) + max_freq = elanfreq_get_cpu_frequency(); + + /* table init */ + for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { + if (elanfreq_table[i].frequency > max_freq) + elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; + } + +#ifdef CONFIG_CPU_FREQ_24_API + driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency(); +#endif + + driver->verify = &elanfreq_verify; + driver->setpolicy = &elanfreq_setpolicy; + + driver->policy[0].cpu = 0; + ret = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &elanfreq_table[0]); + if (ret) { + kfree(driver); + return ret; + } + driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + + elanfreq_driver = driver; + + ret = cpufreq_register(driver); + if (ret) { + elanfreq_driver = NULL; + kfree(driver); + } + + return ret; +} + + +static void __exit elanfreq_exit(void) +{ + if (elanfreq_driver) { + cpufreq_unregister(); + kfree(elanfreq_driver); + } +} + +module_init(elanfreq_init); +module_exit(elanfreq_exit); + +MODULE_PARM (max_freq, "i"); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/entry.S linux.21pre4-ac6/arch/i386/kernel/entry.S --- linux.21pre4/arch/i386/kernel/entry.S 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/entry.S 2003-01-30 16:46:44.000000000 +0000 @@ -79,7 +79,7 @@ exec_domain = 16 need_resched = 20 tsk_ptrace = 24 -processor = 52 +cpu = 32 ENOSYS = 38 @@ -184,9 +184,11 @@ ENTRY(ret_from_fork) +#if CONFIG_SMP pushl %ebx call SYMBOL_NAME(schedule_tail) addl $4, %esp +#endif GET_CURRENT(%ebx) testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS jne tracesys_exit @@ -643,10 +645,10 @@ .long SYMBOL_NAME(sys_lremovexattr) .long SYMBOL_NAME(sys_fremovexattr) .long SYMBOL_NAME(sys_tkill) - .long SYMBOL_NAME(sys_ni_syscall) /* reserved for sendfile64 */ + .long SYMBOL_NAME(sys_sendfile64) .long SYMBOL_NAME(sys_ni_syscall) /* 240 reserved for futex */ - .long SYMBOL_NAME(sys_ni_syscall) /* reserved for sched_setaffinity */ - .long SYMBOL_NAME(sys_ni_syscall) /* reserved for sched_getaffinity */ + .long SYMBOL_NAME(sys_sched_setaffinity) + .long SYMBOL_NAME(sys_sched_getaffinity) .long SYMBOL_NAME(sys_ni_syscall) /* sys_set_thread_area */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_get_thread_area */ .long SYMBOL_NAME(sys_ni_syscall) /* 245 sys_io_setup */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/gx-suspmod.c linux.21pre4-ac6/arch/i386/kernel/gx-suspmod.c --- linux.21pre4/arch/i386/kernel/gx-suspmod.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/gx-suspmod.c 2003-01-28 16:23:47.000000000 +0000 @@ -0,0 +1,514 @@ +/* + * Cyrix MediaGX and NatSemi Geode Suspend Modulation + * (C) 2002 Zwane Mwaikambo + * (C) 2002 Hiroshi Miura + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation + * + * The author(s) of this software shall not be held liable for damages + * of any nature resulting due to the use of this software. This + * software is provided AS-IS with no warranties. + * + * Theoritical note: + * + * (see Geode(tm) CS5530 manual (rev.4.1) page.56) + * + * CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0 + * are based on Suspend Moduration. + * + * Suspend Modulation works by asserting and de-asserting the SUSP# pin + * to CPU(GX1/GXLV) for configurable durations. When asserting SUSP# + * the CPU enters an idle state. GX1 stops its core clock when SUSP# is + * asserted then power consumption is reduced. + * + * Suspend Modulation's OFF/ON duration are configurable + * with 'Suspend Modulation OFF Count Register' + * and 'Suspend Modulation ON Count Register'. + * These registers are 8bit counters that represent the number of + * 32us intervals which the SUSP# pin is asserted/de-asserted to the + * processor. + * + * These counters define a ratio which is the effective frequency + * of operation of the system. + * + * On Count + * F_eff = Fgx * ---------------------- + * On Count + Off Count + * + * 0 <= On Count, Off Count <= 255 + * + * From these limits, we can get register values + * + * on_duration + off_duration <= MAX_DURATION + * off_duration = on_duration * (stock_freq - freq) / freq + * + * on_duration = (freq * DURATION) / stock_freq + * off_duration = DURATION - on_duration + * + * + *--------------------------------------------------------------------------- + * + * ChangeLog: + * Dec. 11, 2002 Hiroshi Miura + * - rewrite for Cyrix MediaGX Cx5510/5520 and + * NatSemi Geode Cs5530(A). + * + * Jul. ??, 2002 Zwane Mwaikambo + * - cs5530_mod patch for 2.4.19-rc1. + * + *--------------------------------------------------------------------------- + * + * Todo + * Test on machines with 5510, 5530, 5530A + */ + +/************************************************************************ + * Suspend Modulation - Definitions * + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PCI config registers, all at F0 */ +#define PCI_PMER1 0x80 /* power management enable register 1 */ +#define PCI_PMER2 0x81 /* power management enable register 2 */ +#define PCI_PMER3 0x82 /* power management enable register 3 */ +#define PCI_IRQTC 0x8c /* irq speedup timer counter register:typical 2 to 4ms */ +#define PCI_VIDTC 0x8d /* video speedup timer counter register: typical 50 to 100ms */ +#define PCI_MODOFF 0x94 /* suspend modulation OFF counter register, 1 = 32us */ +#define PCI_MODON 0x95 /* suspend modulation ON counter register */ +#define PCI_SUSCFG 0x96 /* suspend configuration register */ + +/* PMER1 bits */ +#define GPM (1<<0) /* global power management */ +#define GIT (1<<1) /* globally enable PM device idle timers */ +#define GTR (1<<2) /* globally enable IO traps */ +#define IRQ_SPDUP (1<<3) /* disable clock throttle during interrupt handling */ +#define VID_SPDUP (1<<4) /* disable clock throttle during vga video handling */ + +/* SUSCFG bits */ +#define SUSMOD (1<<0) /* enable/disable suspend modulation */ +/* the belows support only with cs5530 (after rev.1.2)/cs5530A */ +#define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */ + /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */ +#define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */ +/* the belows support only with cs5530A */ +#define PWRSVE_ISA (1<<3) /* stop ISA clock */ +#define PWRSVE (1<<4) /* active idle */ + +struct gxfreq_params { + u8 on_duration; + u8 off_duration; + u8 pci_suscfg; + u8 pci_pmer1; + u8 pci_pmer2; + u8 pci_rev; + struct pci_dev *cs55x0; +}; + +static struct cpufreq_driver *gx_driver; +static struct gxfreq_params *gx_params; +static int stock_freq; + +/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ +static int pci_busclk = 0; +MODULE_PARM(pci_busclk, "i"); + +/* maximum duration for which the cpu may be suspended + * (32us * MAX_DURATION). If no parameter is given, this defaults + * to 255. + * Note that this leads to a maximum of 8 ms(!) where the CPU clock + * is suspended -- processing power is just 0.39% of what it used to be, + * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ +static int max_duration = 255; +MODULE_PARM(max_duration, "i"); + +/* For the default policy, we want at least some processing power + * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV) + */ +#define POLICY_MIN_DIV 20 + + +/* DEBUG + * Define it if you want verbose debug output + */ + +#define SUSPMOD_DEBUG 1 + +#ifdef SUSPMOD_DEBUG +#define dprintk(msg...) printk(KERN_DEBUG "cpufreq:" msg) +#else +#define dprintk(msg...) do { } while(0); +#endif + +/** + * we can detect a core multipiler from dir0_lsb + * from GX1 datasheet p.56, + * MULT[3:0]: + * 0000 = SYSCLK multiplied by 4 (test only) + * 0001 = SYSCLK multiplied by 10 + * 0010 = SYSCLK multiplied by 4 + * 0011 = SYSCLK multiplied by 6 + * 0100 = SYSCLK multiplied by 9 + * 0101 = SYSCLK multiplied by 5 + * 0110 = SYSCLK multiplied by 7 + * 0111 = SYSCLK multiplied by 8 + * of 33.3MHz + **/ +static int gx_freq_mult[16] = { + 4, 10, 4, 6, 9, 5, 7, 8, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + + +/**************************************************************** + * Low Level chipset interface * + ****************************************************************/ +static struct pci_device_id gx_chipset_tbl[] __initdata = { + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, + { 0, }, +}; + +/** + * gx_detect_chipset: + * + **/ +static __init struct pci_dev *gx_detect_chipset(void) +{ + struct pci_dev *gx_pci; + + /* check if CPU is a MediaGX or a Geode. */ + if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && + (current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { + printk(KERN_INFO "gx-suspmod: error: no MediaGX/Geode processor found!\n"); + return NULL; + } + + /* detect which companion chip is used */ + pci_for_each_dev(gx_pci) { + if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { + return gx_pci; + } + } + + dprintk(KERN_INFO "gx-suspmod: error: no supported chipset found!\n"); + return NULL; +} + +/** + * gx_get_cpuspeed: + * + * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. + */ +static int gx_get_cpuspeed(void) +{ + if ((gx_params->pci_suscfg & SUSMOD) == 0) + return stock_freq; + + return (stock_freq * gx_params->on_duration) + / (gx_params->on_duration + gx_params->off_duration); +} + +/** + * gx_validate_speed: + * determine current cpu speed + * +**/ + +static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) +{ + unsigned int i; + u8 tmp_on, tmp_off; + int old_tmp_freq = stock_freq; + int tmp_freq; + + *on_duration=1; + *off_duration=0; + + for (i=max_duration; i>0; i--) { + tmp_on = ((khz * i) / stock_freq) & 0xff; + tmp_off = i - tmp_on; + tmp_freq = (stock_freq * tmp_on) / i; + /* if this relation is closer to khz, use this. If it's equal, + * prefer it, too - lower latency */ + if (abs(tmp_freq - khz) <= abs(old_tmp_freq - khz)) { + *on_duration = tmp_on; + *off_duration = tmp_off; + old_tmp_freq = tmp_freq; + } + } + + return old_tmp_freq; +} + + +/** + * gx_set_cpuspeed: + * set cpu speed in khz. + **/ + +static void gx_set_cpuspeed(unsigned int khz) +{ + u8 suscfg, pmer1; + unsigned int new_khz; + unsigned long flags; + struct cpufreq_freqs freqs; + + + freqs.cpu = 0; + freqs.old = gx_get_cpuspeed(); + + new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration); + + freqs.new = new_khz; + + if (new_khz == stock_freq) { /* if new khz == 100% of CPU speed, it is special case */ + local_irq_save(flags); + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, (gx_params->pci_suscfg & ~(SUSMOD))); + pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &(gx_params->pci_suscfg)); + local_irq_restore(flags); + dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n"); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + return; + } + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + local_irq_save(flags); + switch (gx_params->cs55x0->device) { + case PCI_DEVICE_ID_CYRIX_5530_LEGACY: + pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; + /* FIXME: need to test other values -- Zwane,Miura */ + pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */ + pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */ + pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1); + + if (gx_params->pci_rev < 0x10) { /* CS5530(rev 1.2, 1.3) */ + suscfg = gx_params->pci_suscfg | SUSMOD; + } else { /* CS5530A,B.. */ + suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE; + } + break; + case PCI_DEVICE_ID_CYRIX_5520: + case PCI_DEVICE_ID_CYRIX_5510: + suscfg = gx_params->pci_suscfg | SUSMOD; + break; + default: + local_irq_restore(flags); + dprintk("fatal: try to set unknown chipset.\n"); + return; + } + + pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); + pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); + + pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); + pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); + + local_irq_restore(flags); + + gx_params->pci_suscfg = suscfg; + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", + gx_params->on_duration * 32, gx_params->off_duration * 32); + dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); +} + +/**************************************************************** + * High level functions * + ****************************************************************/ + +/* + * cpufreq_gx_verify: test if frequency range is valid + * + * This function checks if a given frequency range in kHz is valid + * for the hardware supported by the driver. + */ + +static int cpufreq_gx_verify(struct cpufreq_policy *policy) +{ + unsigned int tmp_freq = 0; + u8 tmp1, tmp2; + + if (!gx_driver || !stock_freq || !policy) + return -EINVAL; + + policy->cpu = 0; + cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); + + /* it needs to be assured that at least one supported frequency is + * within policy->min and policy->max. If it is not, policy->max + * needs to be increased until one freuqency is supported. + * policy->min may not be decreased, though. This way we guarantee a + * specific processing capacity. + */ + tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2); + if (tmp_freq < policy->min) + tmp_freq += stock_freq / max_duration; + policy->min = tmp_freq; + if (policy->min > policy->max) + policy->max = tmp_freq; + tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2); + if (tmp_freq > policy->max) + tmp_freq -= stock_freq / max_duration; + policy->max = tmp_freq; + if (policy->max < policy->min) + policy->max = policy->min; + cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); + + return 0; +} + +/* + * cpufreq_gx_setpolicy: + * + */ +static int cpufreq_gx_setpolicy(struct cpufreq_policy *policy) +{ + + if (!gx_driver || !stock_freq || !policy) + return -EINVAL; + + policy->cpu = 0; + + if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { + /* here we need to make sure that we don't set the + * frequency below policy->min (see comment in + * cpufreq_gx_verify() - guarantee of processing + * capacity. + */ + u8 tmp1, tmp2; + unsigned int tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2); + while (tmp_freq < policy->min) { + tmp_freq += stock_freq / max_duration; + tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2); + } + gx_set_cpuspeed(tmp_freq); + } else { + gx_set_cpuspeed(policy->max); + } + return 0; +} + +/* + * cpufreq_gx_init: + * MediaGX/Geode GX initilize cpufreq driver + */ + +static int __init cpufreq_gx_init(void) +{ + int maxfreq,ret,curfreq; + struct cpufreq_driver *driver; + struct gxfreq_params *params; + struct pci_dev *gx_pci; + u32 class_rev; + + /* Test if we have the right hardware */ + if ((gx_pci = gx_detect_chipset()) == NULL) + return -ENODEV; + + /* check whether module parameters are sane */ + if (max_duration > 0xff) + max_duration = 0xff; + + dprintk("geode suspend modulation available.\n"); + + driver = kmalloc(sizeof(struct cpufreq_driver) + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (driver == NULL) + return -ENOMEM; + params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL); + if (params == NULL) { + kfree(driver); + return -ENOMEM; + } + + driver->policy = (struct cpufreq_policy *)(driver + 1); + params->cs55x0 = gx_pci; + + /* keep cs55x0 configurations */ + pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg)); + pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); + pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); + pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); + pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration)); + pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev); + params->pci_rev = class_rev && 0xff; + + gx_params = params; + + /* determine maximum frequency */ + if (pci_busclk) { + maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; + } else if (cpu_khz) { + maxfreq = cpu_khz; + } else { + maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; + } + stock_freq = maxfreq; + curfreq = gx_get_cpuspeed(); + + dprintk("cpu max frequency is %d.\n", maxfreq); + dprintk("cpu current frequency is %dkHz.\n",curfreq); + + /* setup basic struct for cpufreq API */ +#ifdef CONFIG_CPU_FREQ_24_API + driver->cpu_cur_freq[0] = curfreq; +#endif + driver->policy[0].cpu = 0; + + if (max_duration < POLICY_MIN_DIV) + driver->policy[0].min = maxfreq / max_duration; + else + driver->policy[0].min = maxfreq / POLICY_MIN_DIV; + driver->policy[0].max = maxfreq; + driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; + driver->policy[0].cpuinfo.min_freq = maxfreq / max_duration; + driver->policy[0].cpuinfo.max_freq = maxfreq; + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + driver->verify = &cpufreq_gx_verify; + driver->setpolicy = &cpufreq_gx_setpolicy; + + gx_driver = driver; + + if ((ret = cpufreq_register(driver))) { + kfree(driver); + kfree(params); + return ret; /* register error! */ + } + + return 0; +} + +static void __exit cpufreq_gx_exit(void) +{ + if (gx_driver) { + /* disable throttling */ + gx_set_cpuspeed(stock_freq); + cpufreq_unregister(); + kfree(gx_driver); + kfree(gx_params); + } +} + +MODULE_AUTHOR ("Hiroshi Miura "); +MODULE_DESCRIPTION ("Cpufreq driver for Cyrix MediaGX and NatSemi Geode"); +MODULE_LICENSE ("GPL"); + +module_init(cpufreq_gx_init); +module_exit(cpufreq_gx_exit); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/head.S linux.21pre4-ac6/arch/i386/kernel/head.S --- linux.21pre4/arch/i386/kernel/head.S 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/head.S 2003-01-06 15:43:53.000000000 +0000 @@ -445,4 +445,15 @@ .quad 0x00409a0000000000 /* 0x48 APM CS code */ .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */ .quad 0x0040920000000000 /* 0x58 APM DS data */ + /* Segments used for calling PnP BIOS */ + .quad 0x00c09a0000000000 /* 0x60 32-bit code */ + .quad 0x00809a0000000000 /* 0x68 16-bit code */ + .quad 0x0080920000000000 /* 0x70 16-bit data */ + .quad 0x0080920000000000 /* 0x78 16-bit data */ + .quad 0x0080920000000000 /* 0x80 16-bit data */ + .quad 0x0000000000000000 /* 0x88 not used */ + .quad 0x0000000000000000 /* 0x90 not used */ + .quad 0x0000000000000000 /* 0x98 not used */ + /* Per CPU segments */ .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/i386_ksyms.c linux.21pre4-ac6/arch/i386/kernel/i386_ksyms.c --- linux.21pre4/arch/i386/kernel/i386_ksyms.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/i386_ksyms.c 2003-01-12 01:03:46.000000000 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; @@ -49,6 +50,7 @@ EXPORT_SYMBOL(drive_info); #endif +extern unsigned long cpu_khz; extern unsigned long get_cmos_time(void); /* platform dependent support */ @@ -71,6 +73,7 @@ EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(get_cmos_time); +EXPORT_SYMBOL(cpu_khz); EXPORT_SYMBOL(apm_info); EXPORT_SYMBOL(gdt); EXPORT_SYMBOL(empty_zero_page); @@ -86,6 +89,7 @@ /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_generic); /* Delay loops */ +EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(__const_udelay); @@ -129,6 +133,7 @@ EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(kernel_flag_cacheline); EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(smp_num_siblings); EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL_NOVERS(__write_lock_failed); EXPORT_SYMBOL_NOVERS(__read_lock_failed); @@ -179,3 +184,8 @@ #ifdef CONFIG_MULTIQUAD EXPORT_SYMBOL(xquad_portio); #endif + +#ifdef CONFIG_EDD_MODULE +EXPORT_SYMBOL(edd); +EXPORT_SYMBOL(eddnr); +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/i387.c linux.21pre4-ac6/arch/i386/kernel/i387.c --- linux.21pre4/arch/i386/kernel/i387.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/i387.c 2003-01-06 15:38:26.000000000 +0000 @@ -248,7 +248,7 @@ * FXSR floating point environment conversions. */ -static inline int convert_fxsr_to_user( struct _fpstate *buf, +static int convert_fxsr_to_user( struct _fpstate *buf, struct i387_fxsave_struct *fxsave ) { unsigned long env[7]; @@ -270,13 +270,18 @@ to = &buf->_st[0]; from = (struct _fpxreg *) &fxsave->st_space[0]; for ( i = 0 ; i < 8 ; i++, to++, from++ ) { - if ( __copy_to_user( to, from, sizeof(*to) ) ) + unsigned long *t = (unsigned long *)to; + unsigned long *f = (unsigned long *)from; + + if (__put_user(*f, t) || + __put_user(*(f + 1), t + 1) || + __put_user(from->exponent, &to->exponent)) return 1; } return 0; } -static inline int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave, +static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave, struct _fpstate *buf ) { unsigned long env[7]; @@ -299,7 +304,12 @@ to = (struct _fpxreg *) &fxsave->st_space[0]; from = &buf->_st[0]; for ( i = 0 ; i < 8 ; i++, to++, from++ ) { - if ( __copy_from_user( to, from, sizeof(*from) ) ) + unsigned long *t = (unsigned long *)to; + unsigned long *f = (unsigned long *)from; + + if (__get_user(*f, t) || + __get_user(*(f + 1), t + 1) || + __get_user(from->exponent, &to->exponent)) return 1; } return 0; @@ -321,7 +331,7 @@ return 1; } -static inline int save_i387_fxsave( struct _fpstate *buf ) +static int save_i387_fxsave( struct _fpstate *buf ) { struct task_struct *tsk = current; int err = 0; @@ -371,7 +381,7 @@ sizeof(struct i387_fsave_struct) ); } -static inline int restore_i387_fxsave( struct _fpstate *buf ) +static int restore_i387_fxsave( struct _fpstate *buf ) { struct task_struct *tsk = current; clear_fpu( tsk ); @@ -389,7 +399,7 @@ if ( HAVE_HWFP ) { if ( cpu_has_fxsr ) { - err = restore_i387_fxsave( buf ); + err = restore_i387_fxsave( buf ); } else { err = restore_i387_fsave( buf ); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/io_apic.c linux.21pre4-ac6/arch/i386/kernel/io_apic.c --- linux.21pre4/arch/i386/kernel/io_apic.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/io_apic.c 2003-01-31 11:03:59.000000000 +0000 @@ -188,6 +188,86 @@ clear_IO_APIC_pin(apic, pin); } +static void set_ioapic_affinity (unsigned int irq, unsigned long mask) +{ + unsigned long flags; + + /* + * Only the first 8 bits are valid. + */ + mask = mask << 24; + spin_lock_irqsave(&ioapic_lock, flags); + __DO_ACTION(1, = mask, ) + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +#if CONFIG_SMP + +typedef struct { + unsigned int cpu; + unsigned long timestamp; +} ____cacheline_aligned irq_balance_t; + +static irq_balance_t irq_balance[NR_IRQS] __cacheline_aligned + = { [ 0 ... NR_IRQS-1 ] = { 0, 0 } }; + +extern unsigned long irq_affinity [NR_IRQS]; + +#endif + +#define IDLE_ENOUGH(cpu,now) \ + (idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1)) + +#define IRQ_ALLOWED(cpu,allowed_mask) \ + ((1 << cpu) & (allowed_mask)) + +static unsigned long move(int curr_cpu, unsigned long allowed_mask, unsigned long now, int direction) +{ + int search_idle = 1; + int cpu = curr_cpu; + + goto inside; + + do { + if (unlikely(cpu == curr_cpu)) + search_idle = 0; +inside: + if (direction == 1) { + cpu++; + if (cpu >= smp_num_cpus) + cpu = 0; + } else { + cpu--; + if (cpu == -1) + cpu = smp_num_cpus-1; + } + } while (!IRQ_ALLOWED(cpu,allowed_mask) || + (search_idle && !IDLE_ENOUGH(cpu,now))); + + return cpu; +} + +static inline void balance_irq(int irq) +{ +#if CONFIG_SMP + irq_balance_t *entry = irq_balance + irq; + unsigned long now = jiffies; + + if (unlikely(entry->timestamp != now)) { + unsigned long allowed_mask; + int random_number; + + rdtscl(random_number); + random_number &= 1; + + allowed_mask = cpu_online_map & irq_affinity[irq]; + entry->timestamp = now; + entry->cpu = move(entry->cpu, allowed_mask, now, random_number); + set_ioapic_affinity(irq, apicid_to_phys_cpu_present(entry->cpu)); + } +#endif +} + /* * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to * specific CPU-side IRQs. @@ -795,6 +875,7 @@ printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.version); if ( (reg_01.version != 0x01) && /* 82489DX IO-APICs */ (reg_01.version != 0x02) && /* VIA */ + (reg_01.version != 0x03) && /* later VIA */ (reg_01.version != 0x10) && /* oldest IO-APICs */ (reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */ (reg_01.version != 0x13) && /* Xeon IO-APICs */ @@ -1218,6 +1299,7 @@ */ static void ack_edge_ioapic_irq(unsigned int irq) { + balance_irq(irq); if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED)) mask_IO_APIC_irq(irq); @@ -1257,6 +1339,7 @@ unsigned long v; int i; + balance_irq(irq); /* * It appears there is an erratum which affects at least version 0x11 * of I/O APIC (that's the 82093AA and cores integrated into various @@ -1313,19 +1396,6 @@ static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } -static void set_ioapic_affinity (unsigned int irq, unsigned long mask) -{ - unsigned long flags; - /* - * Only the first 8 bits are valid. - */ - mask = mask << 24; - - spin_lock_irqsave(&ioapic_lock, flags); - __DO_ACTION(1, = mask, ) - spin_unlock_irqrestore(&ioapic_lock, flags); -} - /* * Level and edge triggered IO-APIC interrupts need different handling, * so we use two separate IRQ descriptors. Edge triggered IRQs can be diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/irq.c linux.21pre4-ac6/arch/i386/kernel/irq.c --- linux.21pre4/arch/i386/kernel/irq.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/irq.c 2003-01-06 21:42:11.000000000 +0000 @@ -1090,7 +1090,7 @@ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/ldt.c linux.21pre4-ac6/arch/i386/kernel/ldt.c --- linux.21pre4/arch/i386/kernel/ldt.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/ldt.c 2003-01-06 19:10:59.000000000 +0000 @@ -12,37 +12,139 @@ #include #include #include +#include #include #include #include #include +#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ +static void flush_ldt(void *mm) +{ + if (current->active_mm) + load_LDT(¤t->active_mm->context); +} +#endif + +static int alloc_ldt(mm_context_t *pc, int mincount, int reload) +{ + void *oldldt; + void *newldt; + int oldsize; + + if (mincount <= pc->size) + return 0; + oldsize = pc->size; + mincount = (mincount+511)&(~511); + if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE) + newldt = vmalloc(mincount*LDT_ENTRY_SIZE); + else + newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL); + + if (!newldt) + return -ENOMEM; + + if (oldsize) + memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE); + + oldldt = pc->ldt; + memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE); + wmb(); + pc->ldt = newldt; + pc->size = mincount; + if (reload) { + load_LDT(pc); +#ifdef CONFIG_SMP + if (current->mm->cpu_vm_mask != (1< PAGE_SIZE) + vfree(oldldt); + else + kfree(oldldt); + } + return 0; +} + +static inline int copy_ldt(mm_context_t *new, mm_context_t *old) +{ + int err = alloc_ldt(new, old->size, 0); + if (err < 0) { + printk(KERN_WARNING "ldt allocation failed\n"); + new->size = 0; + return err; + } + memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE); + return 0; +} + +/* + * we do not have to muck with descriptors here, that is + * done in switch_mm() as needed. + */ +int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + struct mm_struct * old_mm; + int retval = 0; + + init_MUTEX(&mm->context.sem); + mm->context.size = 0; + old_mm = current->mm; + if (old_mm && old_mm->context.size > 0) { + down(&old_mm->context.sem); + retval = copy_ldt(&mm->context, &old_mm->context); + up(&old_mm->context.sem); + } + return retval; +} + /* - * read_ldt() is not really atomic - this is not a problem since - * synchronization of reads and writes done to the LDT has to be - * assured by user-space anyway. Writes are atomic, to protect - * the security checks done on new descriptors. + * No need to lock the MM as we are the last user + * Do not touch the ldt register, we are already + * in the next thread. */ +void destroy_context(struct mm_struct *mm) +{ + if (mm->context.size) { + if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE) + vfree(mm->context.ldt); + else + kfree(mm->context.ldt); + mm->context.size = 0; + } +} + static int read_ldt(void * ptr, unsigned long bytecount) { int err; unsigned long size; struct mm_struct * mm = current->mm; - err = 0; - if (!mm->context.segments) - goto out; + if (!mm->context.size) + return 0; + if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) + bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - size = LDT_ENTRIES*LDT_ENTRY_SIZE; + down(&mm->context.sem); + size = mm->context.size*LDT_ENTRY_SIZE; if (size > bytecount) size = bytecount; - err = size; - if (copy_to_user(ptr, mm->context.segments, size)) + err = 0; + if (copy_to_user(ptr, mm->context.ldt, size)) err = -EFAULT; -out: - return err; + up(&mm->context.sem); + if (err < 0) + return err; + if (size != bytecount) { + /* zero-fill the rest */ + clear_user(ptr+size, bytecount-size); + } + return bytecount; } static int read_default_ldt(void * ptr, unsigned long bytecount) @@ -53,7 +155,7 @@ err = 0; address = &default_ldt[0]; - size = sizeof(struct desc_struct); + size = 5*sizeof(struct desc_struct); if (size > bytecount) size = bytecount; @@ -88,24 +190,14 @@ goto out; } - /* - * the GDT index of the LDT is allocated dynamically, and is - * limited by MAX_LDT_DESCRIPTORS. - */ - down_write(&mm->mmap_sem); - if (!mm->context.segments) { - void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - error = -ENOMEM; - if (!segments) + down(&mm->context.sem); + if (ldt_info.entry_number >= mm->context.size) { + error = alloc_ldt(¤t->mm->context, ldt_info.entry_number+1, 1); + if (error < 0) goto out_unlock; - memset(segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); - wmb(); - mm->context.segments = segments; - mm->context.cpuvalid = 1UL << smp_processor_id(); - load_LDT(mm); } - lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.segments); + lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt); /* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { @@ -143,7 +235,7 @@ error = 0; out_unlock: - up_write(&mm->mmap_sem); + up(&mm->context.sem); out: return error; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/longhaul.c linux.21pre4-ac6/arch/i386/kernel/longhaul.c --- linux.21pre4/arch/i386/kernel/longhaul.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/longhaul.c 2003-01-10 16:25:37.000000000 +0000 @@ -0,0 +1,813 @@ +/* + * $Id: longhaul.c,v 1.83 2003/01/02 22:16:26 db Exp $ + * + * (C) 2001 Dave Jones. + * (C) 2002 Padraig Brady. + * + * Licensed under the terms of the GNU GPL License version 2. + * Based upon datasheets & sample CPUs kindly provided by VIA. + * + * VIA have currently 3 different versions of Longhaul. + * + * +---------------------+----------+---------------------------------+ + * | Marketing name | Codename | longhaul version / features. | + * +---------------------+----------+---------------------------------+ + * | Samuel/CyrixIII | C5A | v1 : multipliers only | + * | Samuel2/C3 | C3E/C5B | v1 : multiplier only | + * | Ezra | C5C | v2 : multipliers & voltage | + * | Ezra-T | C5M/C5N | v3 : multipliers, voltage & FSB | + * +---------------------+----------+---------------------------------+ + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define DEBUG + +#ifdef DEBUG +#define dprintk(msg...) printk(msg) +#else +#define dprintk(msg...) do { } while(0); +#endif + +static int numscales=16, numvscales; +static int minvid, maxvid; +static int can_scale_voltage; +static int can_scale_fsb; +static int vrmrev; + + +/* Module parameters */ +static int dont_scale_voltage; +static int dont_scale_fsb; +static int current_fsb; + +#define __hlt() __asm__ __volatile__("hlt": : :"memory") + +/* + * Clock ratio tables. + * The eblcr ones specify the ratio read from the CPU. + * The clock_ratio ones specify what to write to the CPU. + */ + +/* VIA C3 Samuel 1 & Samuel 2 (stepping 0)*/ +static int __initdata longhaul1_clock_ratio[16] = { + -1, /* 0000 -> RESERVED */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + -1, /* 0011 -> RESERVED */ + -1, /* 0100 -> RESERVED */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + 55, /* 0111 -> 5.5x */ + 60, /* 1000 -> 6.0x */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 50, /* 1011 -> 5.0x */ + 65, /* 1100 -> 6.5x */ + 75, /* 1101 -> 7.5x */ + -1, /* 1110 -> RESERVED */ + -1, /* 1111 -> RESERVED */ +}; + +static int __initdata samuel1_eblcr[16] = { + 50, /* 0000 -> RESERVED */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + -1, /* 0011 -> RESERVED */ + 55, /* 0100 -> 5.5x */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + -1, /* 0111 -> RESERVED */ + -1, /* 1000 -> RESERVED */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 60, /* 1011 -> 6.0x */ + -1, /* 1100 -> RESERVED */ + 75, /* 1101 -> 7.5x */ + -1, /* 1110 -> RESERVED */ + 65, /* 1111 -> 6.5x */ +}; + +/* VIA C3 Samuel2 Stepping 1->15 & VIA C3 Ezra */ +static int __initdata longhaul2_clock_ratio[16] = { + 100, /* 0000 -> 10.0x */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + 90, /* 0011 -> 9.0x */ + 95, /* 0100 -> 9.5x */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + 55, /* 0111 -> 5.5x */ + 60, /* 1000 -> 6.0x */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 50, /* 1011 -> 5.0x */ + 65, /* 1100 -> 6.5x */ + 75, /* 1101 -> 7.5x */ + 85, /* 1110 -> 8.5x */ + 120, /* 1111 -> 12.0x */ +}; + +static int __initdata samuel2_eblcr[16] = { + 50, /* 0000 -> 5.0x */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + 100, /* 0011 -> 10.0x */ + 55, /* 0100 -> 5.5x */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + 110, /* 0111 -> 11.0x */ + 90, /* 1000 -> 9.0x */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 60, /* 1011 -> 6.0x */ + 120, /* 1100 -> 12.0x */ + 75, /* 1101 -> 7.5x */ + 130, /* 1110 -> 13.0x */ + 65, /* 1111 -> 6.5x */ +}; + +static int __initdata ezra_eblcr[16] = { + 50, /* 0000 -> 5.0x */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + 100, /* 0011 -> 10.0x */ + 55, /* 0100 -> 5.5x */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + 95, /* 0111 -> 9.5x */ + 90, /* 1000 -> 9.0x */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 60, /* 1011 -> 6.0x */ + 120, /* 1100 -> 12.0x */ + 75, /* 1101 -> 7.5x */ + 85, /* 1110 -> 8.5x */ + 65, /* 1111 -> 6.5x */ +}; + +/* VIA C5M. */ +static int __initdata longhaul3_clock_ratio[32] = { + 100, /* 0000 -> 10.0x */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + 90, /* 0011 -> 9.0x */ + 95, /* 0100 -> 9.5x */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + 55, /* 0111 -> 5.5x */ + 60, /* 1000 -> 6.0x */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 50, /* 1011 -> 5.0x */ + 65, /* 1100 -> 6.5x */ + 75, /* 1101 -> 7.5x */ + 85, /* 1110 -> 8.5x */ + 120, /* 1111 -> 12.0x */ + + -1, /* 0000 -> RESERVED (10.0x) */ + 110, /* 0001 -> 11.0x */ + 120, /* 0010 -> 12.0x */ + -1, /* 0011 -> RESERVED (9.0x)*/ + 105, /* 0100 -> 10.5x */ + 115, /* 0101 -> 11.5x */ + 125, /* 0110 -> 12.5x */ + 135, /* 0111 -> 13.5x */ + 140, /* 1000 -> 14.0x */ + 150, /* 1001 -> 15.0x */ + 160, /* 1010 -> 16.0x */ + 130, /* 1011 -> 13.0x */ + 145, /* 1100 -> 14.5x */ + 155, /* 1101 -> 15.5x */ + -1, /* 1110 -> RESERVED (13.0x) */ + -1, /* 1111 -> RESERVED (12.0x) */ +}; + +static int __initdata c5m_eblcr[32] = { + 50, /* 0000 -> 5.0x */ + 30, /* 0001 -> 3.0x */ + 40, /* 0010 -> 4.0x */ + 100, /* 0011 -> 10.0x */ + 55, /* 0100 -> 5.5x */ + 35, /* 0101 -> 3.5x */ + 45, /* 0110 -> 4.5x */ + 95, /* 0111 -> 9.5x */ + 90, /* 1000 -> 9.0x */ + 70, /* 1001 -> 7.0x */ + 80, /* 1010 -> 8.0x */ + 60, /* 1011 -> 6.0x */ + 120, /* 1100 -> 12.0x */ + 75, /* 1101 -> 7.5x */ + 85, /* 1110 -> 8.5x */ + 65, /* 1111 -> 6.5x */ + + -1, /* 0000 -> RESERVED (9.0x) */ + 110, /* 0001 -> 11.0x */ + 120, /* 0010 -> 12.0x */ + -1, /* 0011 -> RESERVED (10.0x)*/ + 135, /* 0100 -> 13.5x */ + 115, /* 0101 -> 11.5x */ + 125, /* 0110 -> 12.5x */ + 105, /* 0111 -> 10.5x */ + 130, /* 1000 -> 13.0x */ + 150, /* 1001 -> 15.0x */ + 160, /* 1010 -> 16.0x */ + 140, /* 1011 -> 14.0x */ + -1, /* 1100 -> RESERVED (12.0x) */ + 155, /* 1101 -> 15.5x */ + -1, /* 1110 -> RESERVED (13.0x) */ + 145, /* 1111 -> 14.5x */ +}; + +/* fsb values as defined in CPU */ +static unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 }; +/* fsb values to favour low fsb speed (lower power) */ +static unsigned int power_fsb_table[] = { 66, 100, 133, -1 }; +/* fsb values to favour high fsb speed (for e.g. if lowering CPU + freq because of heat, but want to maintain highest performance possible) */ +static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 }; +static unsigned int *fsb_search_table; + +/* Voltage scales. Div by 1000 to get actual voltage. */ +static int __initdata vrm85scales[32] = { + 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700, + 1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300, + 1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725, + 1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325, +}; + +static int __initdata mobilevrmscales[32] = { + 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, + 1600, 1550, 1500, 1450, 1500, 1350, 1300, -1, + 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, + 1075, 1050, 1025, 1000, 975, 950, 925, -1, +}; + +/* Clock ratios multiplied by 10 */ +static int clock_ratio[32]; +static int eblcr_table[32]; +static int voltage_table[32]; +static int highest_speed, lowest_speed; /* kHz */ +static int longhaul; /* version. */ +static struct cpufreq_driver *longhaul_driver; + + +static int longhaul_get_cpu_fsb (void) +{ + unsigned long invalue=0,lo, hi; + + if (current_fsb == 0) { + rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); + invalue = (lo & (1<<18|1<<19)) >>18; + return eblcr_fsb_table[invalue]; + } else { + return current_fsb; + } +} + + +static int longhaul_get_cpu_mult (void) +{ + unsigned long invalue=0,lo, hi; + + rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); + invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22; + if (longhaul==3) { + if (lo & (1<<27)) + invalue+=16; + } + return eblcr_table[invalue]; +} + + +/** + * longhaul_set_cpu_frequency() + * @clock_ratio_index : index of clock_ratio[] for new frequency + * @newfsb: the new FSB + * + * Sets a new clock ratio, and -if applicable- a new Front Side Bus + */ + +static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newfsb) +{ + unsigned long lo, hi; + unsigned int bits; + int revkey; + int vidindex, i; + struct cpufreq_freqs freqs; + + if (!newfsb || (clock_ratio[clock_ratio_index] == -1)) + return; + + if ((!can_scale_fsb) && (newfsb != current_fsb)) + return; + + if (((clock_ratio[clock_ratio_index] * newfsb * 100) > highest_speed) || + ((clock_ratio[clock_ratio_index] * newfsb * 100) < lowest_speed)) + return; + + freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100; + freqs.new = clock_ratio[clock_ratio_index] * newfsb * 100; + freqs.cpu = 0; /* longhaul.c is UP only driver */ + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + dprintk (KERN_INFO "longhaul: New FSB:%d Mult(x10):%d\n", + newfsb, clock_ratio[clock_ratio_index]); + + bits = clock_ratio_index; + /* "bits" contains the bitpattern of the new multiplier. + we now need to transform it to the desired format. */ + + switch (longhaul) { + case 1: + rdmsr (MSR_VIA_BCR2, lo, hi); + revkey = (lo & 0xf)<<4; /* Rev key. */ + lo &= ~(1<<23|1<<24|1<<25|1<<26); + lo |= (1<<19); /* Enable software clock multiplier */ + lo |= (bits<<23); /* desired multiplier */ + lo |= revkey; + wrmsr (MSR_VIA_BCR2, lo, hi); + + __hlt(); + + /* Disable software clock multiplier */ + rdmsr (MSR_VIA_BCR2, lo, hi); + lo &= ~(1<<19); + lo |= revkey; + wrmsr (MSR_VIA_BCR2, lo, hi); + break; + + case 2: + rdmsr (MSR_VIA_LONGHAUL, lo, hi); + revkey = (lo & 0xf)<<4; /* Rev key. */ + lo &= 0xfff0bf0f; /* reset [19:16,14](bus ratio) and [7:4](rev key) to 0 */ + lo |= (bits<<16); + lo |= (1<<8); /* EnableSoftBusRatio */ + lo |= revkey; + + if (can_scale_voltage) { + if (can_scale_fsb==1) { + dprintk (KERN_INFO "longhaul: Voltage scaling + FSB scaling not done yet.\n"); + goto bad_voltage; + } else { + /* PB: TODO fix this up */ + vidindex = (((highest_speed-lowest_speed) / (newfsb/2)) - + ((highest_speed-((clock_ratio[clock_ratio_index] * newfsb * 100)/1000)) / (newfsb/2))); + } + for (i=0;i<32;i++) { + dprintk (KERN_INFO "VID hunting. Looking for %d, found %d\n", + minvid+(vidindex*25), voltage_table[i]); + if (voltage_table[i]==(minvid + (vidindex * 25))) + break; + } + if (i==32) + goto bad_voltage; + + dprintk (KERN_INFO "longhaul: Desired vid index=%d\n", i); +#if 0 + lo &= 0xfe0fffff;/* reset [24:20](voltage) to 0 */ + lo |= (i<<20); /* set voltage */ + lo |= (1<<9); /* EnableSoftVID */ +#endif + } + +bad_voltage: + wrmsr (MSR_VIA_LONGHAUL, lo, hi); + __hlt(); + + rdmsr (MSR_VIA_LONGHAUL, lo, hi); + lo &= ~(1<<8); + if (can_scale_voltage) + lo &= ~(1<<9); + lo |= revkey; + wrmsr (MSR_VIA_LONGHAUL, lo, hi); + break; + + case 3: + rdmsr (MSR_VIA_LONGHAUL, lo, hi); + revkey = (lo & 0xf)<<4; /* Rev key. */ + lo &= 0xfff0bf0f; /* reset longhaul[19:16,14] to 0 */ + lo |= (bits<<16); + lo |= (1<<8); /* EnableSoftBusRatio */ + lo |= revkey; + + /* Set FSB */ + if (can_scale_fsb==1) { + lo &= ~(1<<28|1<<29); + switch (newfsb) { + case 66: lo |= (1<<28|1<<29); /* 11 */ + break; + case 100: lo |= 1<<28; /* 01 */ + break; + case 133: break; /* 00*/ + } + } + wrmsr (MSR_VIA_LONGHAUL, lo, hi); + __hlt(); + + rdmsr (MSR_VIA_LONGHAUL, lo, hi); + lo &= ~(1<<8); + lo |= revkey; + wrmsr (MSR_VIA_LONGHAUL, lo, hi); + break; + } + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + + +static void __init longhaul_get_ranges (void) +{ + unsigned long lo, hi, invalue; + unsigned int minmult=0, maxmult=0, minfsb=0, maxfsb=0; + unsigned int multipliers[32]= { + 50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65, + -1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 }; + unsigned int fsb_table[4] = { 133, 100, -1, 66 }; + + switch (longhaul) { + case 1: + /* Ugh, Longhaul v1 didn't have the min/max MSRs. + Assume min=3.0x & max = whatever we booted at. */ + minmult = 30; + maxmult = longhaul_get_cpu_mult(); + minfsb = maxfsb = current_fsb; + break; + + case 2 ... 3: + rdmsr (MSR_VIA_LONGHAUL, lo, hi); + + invalue = (hi & (1<<0|1<<1|1<<2|1<<3)); + if (hi & (1<<11)) + invalue += 16; + maxmult=multipliers[invalue]; + +#if 0 /* This is MaxMhz @ Min Voltage. Ignore for now */ + invalue = (hi & (1<<16|1<<17|1<<18|1<<19)) >> 16; + if (hi & (1<<27)) + invalue += 16; + minmult = multipliers[invalue]; +#else + minmult = 30; /* as per spec */ +#endif + + if (can_scale_fsb==1) { + invalue = (hi & (1<<9|1<<10)) >> 9; + maxfsb = fsb_table[invalue]; + + invalue = (hi & (1<<25|1<<26)) >> 25; + minfsb = fsb_table[invalue]; + + dprintk (KERN_INFO "longhaul: Min FSB=%d Max FSB=%d\n", + minfsb, maxfsb); + } else { + minfsb = maxfsb = current_fsb; + } + break; + } + + highest_speed = maxmult * maxfsb * 100; + lowest_speed = minmult * minfsb * 100; + + dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n", + minmult, maxmult); + dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n", + lowest_speed, highest_speed); +} + + +static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned long hi) +{ + int revkey; + + can_scale_voltage = 1; + + minvid = (hi & (1<<20|1<<21|1<<22|1<<23|1<<24)) >> 20; /* 56:52 */ + maxvid = (hi & (1<<4|1<<5|1<<6|1<<7|1<<8)) >> 4; /* 40:36 */ + vrmrev = (lo & (1<<15))>>15; + + if (vrmrev==0) { + dprintk (KERN_INFO "longhaul: VRM 8.5 : "); + memcpy (voltage_table, vrm85scales, sizeof(voltage_table)); + numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25; + } else { + dprintk (KERN_INFO "longhaul: Mobile VRM : "); + memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table)); + numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5; + } + + /* Current voltage isn't readable at first, so we need to + set it to a known value. The spec says to use maxvid */ + revkey = (lo & 0xf)<<4; /* Rev key. */ + lo &= 0xfe0fff0f; /* Mask unneeded bits */ + lo |= (1<<9); /* EnableSoftVID */ + lo |= revkey; /* Reinsert key */ + lo |= maxvid << 20; + wrmsr (MSR_VIA_LONGHAUL, lo, hi); + minvid = voltage_table[minvid]; + maxvid = voltage_table[maxvid]; + dprintk ("Min VID=%d.%03d Max VID=%d.%03d, %d possible voltage scales\n", + maxvid/1000, maxvid%1000, minvid/1000, minvid%1000, numvscales); +} + + +static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy, unsigned int fsb) { + unsigned int i, count = 0; + + for(i=0; imax) && + ((clock_ratio[i] * fsb * 100) >= policy->min)) + count++; + } + + return count; +} + + +static int longhaul_verify(struct cpufreq_policy *policy) +{ + unsigned int number_states = 0; + unsigned int i; + unsigned int fsb_index = 0; + unsigned int tmpfreq = 0; + unsigned int newmax = -1; + + if (!policy || !longhaul_driver) + return -EINVAL; + + policy->cpu = 0; + cpufreq_verify_within_limits(policy, lowest_speed, highest_speed); + + if (can_scale_fsb==1) { + for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++) + number_states += longhaul_statecount_fsb(policy, fsb_search_table[fsb_index]); + } else + number_states = longhaul_statecount_fsb(policy, current_fsb); + + if (number_states) + return 0; + + /* get frequency closest above current policy->max */ + if (can_scale_fsb==1) { + for (fsb_index=0; fsb_search_table[fsb_index] != -1; fsb_index++) + for(i=0; i policy->max) && + (tmpfreq < newmax)) + newmax = tmpfreq; + } + } else { + for(i=0; i policy->max) && + (tmpfreq < newmax)) + newmax = tmpfreq; + } + } + + policy->max = newmax; + + cpufreq_verify_within_limits(policy, lowest_speed, highest_speed); + + return 0; +} + + +static int longhaul_get_best_freq_for_fsb(struct cpufreq_policy *policy, + unsigned int min_mult, + unsigned int max_mult, + unsigned int fsb, + unsigned int *new_mult) +{ + unsigned int optimal = 0; + unsigned int found_optimal = 0; + unsigned int i; + + switch(policy->policy) { + case CPUFREQ_POLICY_POWERSAVE: + optimal = max_mult; + break; + case CPUFREQ_POLICY_PERFORMANCE: + optimal = min_mult; + } + + for(i=0; i policy->max) || + (freq < policy->min)) + continue; + switch(policy->policy) { + case CPUFREQ_POLICY_POWERSAVE: + if (clock_ratio[i] < clock_ratio[optimal]) { + found_optimal = 1; + optimal = i; + } + break; + case CPUFREQ_POLICY_PERFORMANCE: + if (clock_ratio[i] > clock_ratio[optimal]) { + found_optimal = 1; + optimal = i; + } + break; + } + } + + if (found_optimal) { + *new_mult = optimal; + return 1; + } + return 0; +} + + +static int longhaul_setpolicy (struct cpufreq_policy *policy) +{ + unsigned int i; + unsigned int fsb_index = 0; + unsigned int new_fsb = 0; + unsigned int new_clock_ratio = 0; + unsigned int min_mult = 0; + unsigned int max_mult = 0; + + + if (!longhaul_driver) + return -EINVAL; + + if (policy->policy==CPUFREQ_POLICY_PERFORMANCE) + fsb_search_table = perf_fsb_table; + else + fsb_search_table = power_fsb_table; + + for(i=0;i clock_ratio[i]) + min_mult = i; + } + + if (can_scale_fsb==1) { + unsigned int found = 0; + for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++) + { + if (longhaul_get_best_freq_for_fsb(policy, + min_mult, max_mult, + fsb_search_table[fsb_index], + &new_clock_ratio)) { + new_fsb = fsb_search_table[fsb_index]; + break; + } + } + if (!found) + return -EINVAL; + } else { + new_fsb = current_fsb; + if (!longhaul_get_best_freq_for_fsb(policy, min_mult, + max_mult, new_fsb, &new_clock_ratio)) + return -EINVAL; + } + + longhaul_setstate(new_clock_ratio, new_fsb); + + return 0; +} + + +static int __init longhaul_init (void) +{ + struct cpuinfo_x86 *c = cpu_data; + unsigned int currentspeed; + static int currentmult; + unsigned long lo, hi; + int ret; + struct cpufreq_driver *driver; + + if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) ) + return -ENODEV; + + switch (c->x86_model) { + case 6: /* VIA C3 Samuel C5A */ + longhaul=1; + memcpy (clock_ratio, longhaul1_clock_ratio, sizeof(longhaul1_clock_ratio)); + memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr)); + break; + + case 7: /* C5B / C5C */ + switch (c->x86_mask) { + case 0: + longhaul=1; + memcpy (clock_ratio, longhaul1_clock_ratio, sizeof(longhaul1_clock_ratio)); + memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr)); + break; + case 1 ... 15: + longhaul=2; + memcpy (clock_ratio, longhaul2_clock_ratio, sizeof(longhaul2_clock_ratio)); + memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr)); + break; + } + break; + + case 8: /* C5M/C5N */ + return -ENODEV; // Waiting on updated docs from VIA before this is usable + longhaul=3; + numscales=32; + memcpy (clock_ratio, longhaul3_clock_ratio, sizeof(longhaul3_clock_ratio)); + memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr)); + break; + + default: + printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n"); + return -ENODEV; + } + + printk (KERN_INFO "longhaul: VIA CPU detected. Longhaul version %d supported\n", longhaul); + + current_fsb = longhaul_get_cpu_fsb(); + currentmult = longhaul_get_cpu_mult(); + currentspeed = currentmult * current_fsb * 100; + + dprintk (KERN_INFO "longhaul: CPU currently at %dMHz (%d x %d.%d)\n", + (currentspeed/1000), current_fsb, currentmult/10, currentmult%10); + + if (longhaul==2 || longhaul==3) { + rdmsr (MSR_VIA_LONGHAUL, lo, hi); + if ((lo & (1<<0)) && (dont_scale_voltage==0)) + longhaul_setup_voltagescaling (lo, hi); + + if ((lo & (1<<1)) && (dont_scale_fsb==0) && (current_fsb==0)) + can_scale_fsb = 1; + } + + longhaul_get_ranges(); + + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) + return -ENOMEM; + + driver->policy = (struct cpufreq_policy *) (driver + 1); + +#ifdef CONFIG_CPU_FREQ_24_API + driver->cpu_cur_freq[0] = currentspeed; +#endif + + driver->verify = &longhaul_verify; + driver->setpolicy = &longhaul_setpolicy; + + driver->policy[0].cpu = 0; + driver->policy[0].min = (unsigned int) lowest_speed; + driver->policy[0].max = (unsigned int) highest_speed; + driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; + driver->policy[0].cpuinfo.min_freq = (unsigned int) lowest_speed; + driver->policy[0].cpuinfo.max_freq = (unsigned int) highest_speed; + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + + longhaul_driver = driver; + + ret = cpufreq_register(driver); + if (ret) { + longhaul_driver = NULL; + kfree(driver); + } + + return ret; +} + + +static void __exit longhaul_exit (void) +{ + if (longhaul_driver) { + cpufreq_unregister(); + kfree(longhaul_driver); + } +} + +MODULE_PARM (dont_scale_fsb, "i"); +MODULE_PARM (dont_scale_voltage, "i"); +MODULE_PARM (current_fsb, "i"); + +MODULE_AUTHOR ("Dave Jones "); +MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); +MODULE_LICENSE ("GPL"); + +module_init(longhaul_init); +module_exit(longhaul_exit); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/longrun.c linux.21pre4-ac6/arch/i386/kernel/longrun.c --- linux.21pre4/arch/i386/kernel/longrun.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/longrun.c 2003-01-10 16:25:37.000000000 +0000 @@ -0,0 +1,292 @@ +/* + * $Id: longrun.c,v 1.18 2003/01/02 22:16:26 db Exp $ + * + * (C) 2002 Dominik Brodowski + * + * Licensed under the terms of the GNU GPL License version 2. + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct cpufreq_driver *longrun_driver; + +/** + * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz + * values into per cent values. In TMTA microcode, the following is valid: + * performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) + */ +static unsigned int longrun_low_freq, longrun_high_freq; + + +/** + * longrun_get_policy - get the current LongRun policy + * @policy: struct cpufreq_policy where current policy is written into + * + * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS + * and MSR_TMTA_LONGRUN_CTRL + */ +static void longrun_get_policy(struct cpufreq_policy *policy) +{ + u32 msr_lo, msr_hi; + + if (!longrun_driver) + return; + + rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); + if (msr_lo & 0x01) + policy->policy = CPUFREQ_POLICY_PERFORMANCE; + else + policy->policy = CPUFREQ_POLICY_POWERSAVE; + + rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); + msr_lo &= 0x0000007F; + msr_hi &= 0x0000007F; + + policy->min = longrun_low_freq + msr_lo * + ((longrun_high_freq - longrun_low_freq) / 100); + policy->min = longrun_low_freq + msr_hi * + ((longrun_high_freq - longrun_low_freq) / 100); + policy->cpu = 0; +} + + +/** + * longrun_set_policy - sets a new CPUFreq policy + * @policy - new policy + * + * Sets a new CPUFreq policy on LongRun-capable processors. This function + * has to be called with cpufreq_driver locked. + */ +static int longrun_set_policy(struct cpufreq_policy *policy) +{ + u32 msr_lo, msr_hi; + u32 pctg_lo, pctg_hi; + + if (!longrun_driver || !policy) + return -EINVAL; + + pctg_lo = (policy->min - longrun_low_freq) / + ((longrun_high_freq - longrun_low_freq) / 100); + pctg_hi = (policy->max - longrun_low_freq) / + ((longrun_high_freq - longrun_low_freq) / 100); + + if (pctg_hi > 100) + pctg_hi = 100; + if (pctg_lo > pctg_hi) + pctg_lo = pctg_hi; + + /* performance or economy mode */ + rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); + msr_lo &= 0xFFFFFFFE; + switch (policy->policy) { + case CPUFREQ_POLICY_PERFORMANCE: + msr_lo |= 0x00000001; + break; + case CPUFREQ_POLICY_POWERSAVE: + break; + } + wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); + + /* lower and upper boundary */ + rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); + msr_lo &= 0xFFFFFF80; + msr_hi &= 0xFFFFFF80; + msr_lo |= pctg_lo; + msr_hi |= pctg_hi; + wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); + + return 0; +} + + +/** + * longrun_verify_poliy - verifies a new CPUFreq policy + * + * Validates a new CPUFreq policy. This function has to be called with + * cpufreq_driver locked. + */ +static int longrun_verify_policy(struct cpufreq_policy *policy) +{ + if (!policy || !longrun_driver) + return -EINVAL; + + policy->cpu = 0; + cpufreq_verify_within_limits(policy, + longrun_driver->policy[0].cpuinfo.min_freq, + longrun_driver->policy[0].cpuinfo.max_freq); + + return 0; +} + + +/** + * longrun_determine_freqs - determines the lowest and highest possible core frequency + * + * Determines the lowest and highest possible core frequencies on this CPU. + * This is neccessary to calculate the performance percentage according to + * TMTA rules: + * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq) + */ +static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, + unsigned int *high_freq) +{ + u32 msr_lo, msr_hi; + u32 save_lo, save_hi; + u32 eax, ebx, ecx, edx; + struct cpuinfo_x86 *c = cpu_data; + + if (!low_freq || !high_freq) + return -EINVAL; + + if (cpu_has(c, X86_FEATURE_LRTI)) { + /* if the LongRun Table Interface is present, the + * detection is a bit easier: + * For minimum frequency, read out the maximum + * level (msr_hi), write that into "currently + * selected level", and read out the frequency. + * For maximum frequency, read out level zero. + */ + /* minimum */ + rdmsr(MSR_TMTA_LRTI_READOUT, msr_lo, msr_hi); + wrmsr(MSR_TMTA_LRTI_READOUT, msr_hi, msr_hi); + rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); + *low_freq = msr_lo * 1000; /* to kHz */ + + /* maximum */ + wrmsr(MSR_TMTA_LRTI_READOUT, 0, msr_hi); + rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); + *high_freq = msr_lo * 1000; /* to kHz */ + + if (*low_freq > *high_freq) + *low_freq = *high_freq; + return 0; + } + + /* set the upper border to the value determined during TSC init */ + *high_freq = (cpu_khz / 1000); + *high_freq = *high_freq * 1000; + + /* get current borders */ + rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); + save_lo = msr_lo & 0x0000007F; + save_hi = msr_hi & 0x0000007F; + + /* if current perf_pctg is larger than 90%, we need to decrease the + * upper limit to make the calculation more accurate. + */ + cpuid(0x80860007, &eax, &ebx, &ecx, &edx); + if (ecx > 90) { + /* set to 0 to 80 perf_pctg */ + msr_lo &= 0xFFFFFF80; + msr_hi &= 0xFFFFFF80; + msr_lo |= 0; + msr_hi |= 80; + wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); + + /* read out current core MHz and current perf_pctg */ + cpuid(0x80860007, &eax, &ebx, &ecx, &edx); + + /* restore values */ + wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi); + } + + /* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) + * eqals + * low_freq * ( 1 - perf_pctg) = (cur_freq - high_freq * perf_pctg) + * + * high_freq * perf_pctg is stored tempoarily into "ebx". + */ + ebx = (((cpu_khz / 1000) * ecx) / 100); /* to MHz */ + + if ((ecx > 95) || (ecx == 0) || (eax < ebx)) + return -EIO; + + edx = (eax - ebx) / (100 - ecx); + *low_freq = edx * 1000; /* back to kHz */ + + if (*low_freq > *high_freq) + *low_freq = *high_freq; + + return 0; +} + + +/** + * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver + * + * Initializes the LongRun support. + */ +static int __init longrun_init(void) +{ + int result; + struct cpufreq_driver *driver; + struct cpuinfo_x86 *c = cpu_data; + + if (c->x86_vendor != X86_VENDOR_TRANSMETA || + !cpu_has(c, X86_FEATURE_LONGRUN)) + return 0; + + /* initialization of main "cpufreq" code*/ + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) + return -ENOMEM; + + driver->policy = (struct cpufreq_policy *) (driver + 1); + + if (longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq)) { + kfree(driver); + return -EIO; + } + driver->policy[0].cpuinfo.min_freq = longrun_low_freq; + driver->policy[0].cpuinfo.max_freq = longrun_high_freq; + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + + longrun_get_policy(&driver->policy[0]); + +#ifdef CONFIG_CPU_FREQ_24_API + driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */ +#endif + + driver->verify = &longrun_verify_policy; + driver->setpolicy = &longrun_set_policy; + + longrun_driver = driver; + + result = cpufreq_register(driver); + if (result) { + longrun_driver = NULL; + kfree(driver); + } + + return result; +} + + +/** + * longrun_exit - unregisters LongRun support + */ +static void __exit longrun_exit(void) +{ + if (longrun_driver) { + cpufreq_unregister(); + kfree(longrun_driver); + } +} + + +MODULE_AUTHOR ("Dominik Brodowski "); +MODULE_DESCRIPTION ("LongRun driver for Transmeta Crusoe processors."); +MODULE_LICENSE ("GPL"); +module_init(longrun_init); +module_exit(longrun_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/Makefile linux.21pre4-ac6/arch/i386/kernel/Makefile --- linux.21pre4/arch/i386/kernel/Makefile 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/Makefile 2003-01-10 16:26:51.000000000 +0000 @@ -40,5 +40,14 @@ obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o acpitable.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o +obj-$(CONFIG_EDD) += edd.o +obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o +obj-$(CONFIG_X86_LONGHAUL) += longhaul.o +obj-$(CONFIG_X86_SPEEDSTEP) += speedstep.o +obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o +obj-$(CONFIG_X86_LONGRUN) += longrun.o +obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o +obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o + include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/microcode.c linux.21pre4-ac6/arch/i386/kernel/microcode.c --- linux.21pre4/arch/i386/kernel/microcode.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/microcode.c 2003-01-28 16:19:28.000000000 +0000 @@ -55,7 +55,7 @@ * Tigran Aivazian , * Serialize updates as required on HT processors due to speculative * nature of implementation. - * 1.11 22 Mar 2001 Tigran Aivazian + * 1.11 22 Mar 2002 Tigran Aivazian * Fix the panic when writing zero-length microcode chunk. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/mpparse.c linux.21pre4-ac6/arch/i386/kernel/mpparse.c --- linux.21pre4/arch/i386/kernel/mpparse.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/mpparse.c 2003-01-29 17:11:52.000000000 +0000 @@ -126,6 +126,8 @@ case 0x0F: if (model == 0x00) return("Pentium 4(tm)"); + if (model == 0x01) + return("Pentium 4(tm)"); if (model == 0x02) return("Pentium 4(tm) XEON(tm)"); if (model == 0x0F) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/mtrr.c linux.21pre4-ac6/arch/i386/kernel/mtrr.c --- linux.21pre4/arch/i386/kernel/mtrr.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/mtrr.c 2003-01-29 17:12:01.000000000 +0000 @@ -492,6 +492,14 @@ return 0; } } + /* Intel 450NX errata # 23. No ascending cachline evictions to + write combining memory may resulting in data corruption */ + dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, NULL); + if(dev) + { + printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n"); + return 0; + } switch ( mtrr_if ) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/p4-clockmod.c linux.21pre4-ac6/arch/i386/kernel/p4-clockmod.c --- linux.21pre4/arch/i386/kernel/p4-clockmod.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/p4-clockmod.c 2003-01-10 16:27:32.000000000 +0000 @@ -0,0 +1,287 @@ +/* + * Pentium 4/Xeon CPU on demand clock modulation/speed scaling + * (C) 2002 Zwane Mwaikambo + * (C) 2002 Arjan van de Ven + * (C) 2002 Tora T. Engstad + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * The author(s) of this software shall not be held liable for damages + * of any nature resulting due to the use of this software. This + * software is provided AS-IS with no warranties. + * + * Date Errata Description + * 20020525 N44, O17 12.5% or 25% DC causes lockup + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PFX "cpufreq: " + +/* + * Duty Cycle (3bits), note DC_DISABLE is not specified in + * intel docs i just use it to mean disable + */ +enum { + DC_RESV, DC_DFLT, DC_25PT, DC_38PT, DC_50PT, + DC_64PT, DC_75PT, DC_88PT, DC_DISABLE +}; + +#define DC_ENTRIES 8 + + +static int has_N44_O17_errata; +static int stock_freq; +MODULE_PARM(stock_freq, "i"); + +static struct cpufreq_driver *cpufreq_p4_driver; + + +static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) +{ + u32 l, h; + unsigned long cpus_allowed; + struct cpufreq_freqs freqs; + int hyperthreading = 0; + int affected_cpu_map = 0; + int sibling = 0; + + if (!cpu_online(cpu) || (newstate > DC_DISABLE) || + (newstate == DC_RESV)) + return -EINVAL; + + /* switch to physical CPU where state is to be changed*/ + cpus_allowed = current->cpus_allowed; + + /* only run on CPU to be set, or on its sibling */ + affected_cpu_map = 1 << cpu; +#ifdef CONFIG_X86_HT + hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2)); + if (hyperthreading) { + sibling = cpu_sibling_map[cpu]; + affected_cpu_map |= (1 << sibling); + } +#endif + set_cpus_allowed(current, affected_cpu_map); + BUG_ON(!(affected_cpu_map & (1 << smp_processor_id()))); + + /* get current state */ + rdmsr(MSR_IA32_THERM_CONTROL, l, h); + if (l & 0x10) { + l = l >> 1; + l &= 0x7; + } else + l = DC_DISABLE; + + if (l == newstate) { + set_cpus_allowed(current, cpus_allowed); + return 0; + } else if (l == DC_RESV) { + printk(KERN_ERR PFX "BIG FAT WARNING: currently in invalid setting\n"); + } + + /* notifiers */ + freqs.old = stock_freq * l / 8; + freqs.new = stock_freq * newstate / 8; + freqs.cpu = cpu; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + if (hyperthreading) { + freqs.cpu = sibling; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + } + + rdmsr(MSR_IA32_THERM_STATUS, l, h); + if (l & 0x01) + printk(KERN_DEBUG PFX "CPU#%d currently thermal throttled\n", cpu); + + if (has_N44_O17_errata && (newstate == DC_25PT || newstate == DC_DFLT)) + newstate = DC_38PT; + + rdmsr(MSR_IA32_THERM_CONTROL, l, h); + if (newstate == DC_DISABLE) { + printk(KERN_INFO PFX "CPU#%d disabling modulation\n", cpu); + wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); + } else { + printk(KERN_INFO PFX "CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); + /* bits 63 - 5 : reserved + * bit 4 : enable/disable + * bits 3-1 : duty cycle + * bit 0 : reserved + */ + l = (l & ~14); + l = l | (1<<4) | ((newstate & 0x7)<<1); + wrmsr(MSR_IA32_THERM_CONTROL, l, h); + } + + set_cpus_allowed(current, cpus_allowed); + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + if (hyperthreading) { + freqs.cpu = cpu; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + + return 0; +} + + +static struct cpufreq_frequency_table p4clockmod_table[] = { + {DC_RESV, CPUFREQ_ENTRY_INVALID}, + {DC_DFLT, 0}, + {DC_25PT, 0}, + {DC_38PT, 0}, + {DC_50PT, 0}, + {DC_64PT, 0}, + {DC_75PT, 0}, + {DC_88PT, 0}, + {DC_DISABLE, 0}, + {DC_RESV, CPUFREQ_TABLE_END}, +}; + + +static int cpufreq_p4_setpolicy(struct cpufreq_policy *policy) +{ + unsigned int newstate = DC_RESV; + + if (cpufreq_frequency_table_setpolicy(policy, &p4clockmod_table[0], &newstate)) + return -EINVAL; + + cpufreq_p4_setdc(policy->cpu, newstate); + + return 0; +} + + +static int cpufreq_p4_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]); +} + + +static int __init cpufreq_p4_init(void) +{ + struct cpuinfo_x86 *c = cpu_data; + int cpuid; + int ret; + struct cpufreq_driver *driver; + unsigned int i; + + /* + * THERM_CONTROL is architectural for IA32 now, so + * we can rely on the capability checks + */ + if (c->x86_vendor != X86_VENDOR_INTEL) + return -ENODEV; + + if (!test_bit(X86_FEATURE_ACPI, c->x86_capability) || + !test_bit(X86_FEATURE_ACC, c->x86_capability)) + return -ENODEV; + + /* Errata workarounds */ + cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask; + switch (cpuid) { + case 0x0f07: + case 0x0f0a: + case 0x0f11: + case 0x0f12: + has_N44_O17_errata = 1; + default: + break; + } + + printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n"); + + if (!stock_freq) { + if (cpu_khz) + stock_freq = cpu_khz; + else { + printk(KERN_INFO PFX "unknown core frequency - please use module parameter 'stock_freq'\n"); + return -EINVAL; + } + } + + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) + return -ENOMEM; + + driver->policy = (struct cpufreq_policy *) (driver + 1); + + /* table init */ + for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { + if ((i<2) && (has_N44_O17_errata)) + p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; + else + p4clockmod_table[i].frequency = (stock_freq * i)/8; + } + + +#ifdef CONFIG_CPU_FREQ_24_API + for (i=0;icpu_cur_freq[i] = stock_freq; + } +#endif + + driver->verify = &cpufreq_p4_verify; + driver->setpolicy = &cpufreq_p4_setpolicy; + + for (i=0;ipolicy[i].cpu = i; + ret = cpufreq_frequency_table_cpuinfo(&driver->policy[i], &p4clockmod_table[0]); + if (ret) { + kfree(driver); + return ret; + } + driver->policy[i].policy = CPUFREQ_POLICY_PERFORMANCE; + driver->policy[i].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + } + + cpufreq_p4_driver = driver; + + ret = cpufreq_register(driver); + if (ret) { + cpufreq_p4_driver = NULL; + kfree(driver); + } + + return ret; +} + + +static void __exit cpufreq_p4_exit(void) +{ + unsigned int i; + + if (cpufreq_p4_driver) { + for (i=0; i"); +MODULE_DESCRIPTION ("cpufreq driver for Pentium(TM) 4/Xeon(TM)"); +MODULE_LICENSE ("GPL"); + +module_init(cpufreq_p4_init); +module_exit(cpufreq_p4_exit); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/pci-dma.c linux.21pre4-ac6/arch/i386/kernel/pci-dma.c --- linux.21pre4/arch/i386/kernel/pci-dma.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/pci-dma.c 2003-01-06 16:22:34.000000000 +0000 @@ -19,7 +19,7 @@ void *ret; int gfp = GFP_ATOMIC; - if (hwdev == NULL || ((u32)hwdev->dma_mask < 0xffffffff)) + if (hwdev == NULL || hwdev->dma_mask < 0xffffffff) gfp |= GFP_DMA; ret = (void *)__get_free_pages(gfp, get_order(size)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/pci-irq.c linux.21pre4-ac6/arch/i386/kernel/pci-irq.c --- linux.21pre4/arch/i386/kernel/pci-irq.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/pci-irq.c 2003-01-31 11:18:37.000000000 +0000 @@ -779,9 +779,16 @@ void pcibios_enable_irq(struct pci_dev *dev) { u8 pin; + extern int interrupt_line_quirk; + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { char *msg; + + /* With IDE legacy devices the IRQ lookup failure is not a problem.. */ + if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5)) + return; + if (io_apic_assign_pci_irqs) msg = " Probably buggy MP table."; else if (pci_probe & PCI_BIOS_IRQ_SCAN) @@ -791,4 +798,9 @@ printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", 'A' + pin - 1, dev->slot_name, msg); } + /* VIA bridges use interrupt line for apic/pci steering across + the V-Link */ + else if (interrupt_line_quirk) + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/powernow-k6.c linux.21pre4-ac6/arch/i386/kernel/powernow-k6.c --- linux.21pre4/arch/i386/kernel/powernow-k6.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/powernow-k6.c 2003-01-10 16:27:32.000000000 +0000 @@ -0,0 +1,237 @@ +/* + * $Id: powernow-k6.c,v 1.42 2003/01/02 22:41:08 db Exp $ + * This file was part of Powertweak Linux (http://powertweak.sf.net) + * and is shared with the Linux Kernel module. + * + * (C) 2000-2002 Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski. + * + * Licensed under the terms of the GNU GPL License version 2. + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long + as it is unused */ + +static struct cpufreq_driver *powernow_driver; +static unsigned int busfreq; /* FSB, in 10 kHz */ +static unsigned int max_multiplier; + + +/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ +static struct cpufreq_frequency_table clock_ratio[] = { + {45, /* 000 -> 4.5x */ 0}, + {50, /* 001 -> 5.0x */ 0}, + {40, /* 010 -> 4.0x */ 0}, + {55, /* 011 -> 5.5x */ 0}, + {20, /* 100 -> 2.0x */ 0}, + {30, /* 101 -> 3.0x */ 0}, + {60, /* 110 -> 6.0x */ 0}, + {35, /* 111 -> 3.5x */ 0}, + {0, CPUFREQ_TABLE_END} +}; + + +/** + * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier + * + * Returns the current setting of the frequency multiplier. Core clock + * speed is frequency of the Front-Side Bus multiplied with this value. + */ +static int powernow_k6_get_cpu_multiplier(void) +{ + u64 invalue = 0; + u32 msrval; + + msrval = POWERNOW_IOPORT + 0x1; + wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ + invalue=inl(POWERNOW_IOPORT + 0x8); + msrval = POWERNOW_IOPORT + 0x0; + wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ + + return clock_ratio[(invalue >> 5)&7].index; +} + + +/** + * powernow_k6_set_state - set the PowerNow! multiplier + * @best_i: clock_ratio[best_i] is the target multiplier + * + * Tries to change the PowerNow! multiplier + */ +static void powernow_k6_set_state (unsigned int best_i) +{ + unsigned long outvalue=0, invalue=0; + unsigned long msrval; + struct cpufreq_freqs freqs; + + if (!powernow_driver) { + printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n"); + return; + } + + freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); + freqs.new = busfreq * clock_ratio[best_i].index; + freqs.cpu = 0; /* powernow-k6.c is UP only driver */ + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* we now need to transform best_i to the BVC format, see AMD#23446 */ + + outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5); + + msrval = POWERNOW_IOPORT + 0x1; + wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ + invalue=inl(POWERNOW_IOPORT + 0x8); + invalue = invalue & 0xf; + outvalue = outvalue | invalue; + outl(outvalue ,(POWERNOW_IOPORT + 0x8)); + msrval = POWERNOW_IOPORT + 0x0; + wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return; +} + + +/** + * powernow_k6_verify - verifies a new CPUfreq policy + * @policy: new policy + * + * Policy must be within lowest and highest possible CPU Frequency, + * and at least one possible state must be within min and max. + */ +static int powernow_k6_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &clock_ratio[0]); +} + + +/** + * powernow_k6_setpolicy - sets a new CPUFreq policy + * @policy - new policy + * + * sets a new CPUFreq policy + */ +static int powernow_k6_setpolicy (struct cpufreq_policy *policy) +{ + unsigned int newstate = 0; + + if (cpufreq_frequency_table_setpolicy(policy, &clock_ratio[0], &newstate)) + return -EINVAL; + + powernow_k6_set_state(newstate); + + return 0; +} + + +/** + * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver + * + * Initializes the K6 PowerNow! support. Returns -ENODEV on unsupported + * devices, -EINVAL or -ENOMEM on problems during initiatization, and zero + * on success. + */ +static int __init powernow_k6_init(void) +{ + struct cpuinfo_x86 *c = cpu_data; + struct cpufreq_driver *driver; + unsigned int result; + unsigned int i; + + if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || + ((c->x86_model != 12) && (c->x86_model != 13))) + return -ENODEV; + + max_multiplier = powernow_k6_get_cpu_multiplier(); + busfreq = cpu_khz / max_multiplier; + + if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { + printk("cpufreq: PowerNow IOPORT region already used.\n"); + return -EIO; + } + + /* initialization of main "cpufreq" code*/ + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) { + release_region (POWERNOW_IOPORT, 16); + return -ENOMEM; + } + driver->policy = (struct cpufreq_policy *) (driver + 1); + + /* table init */ + for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { + if (clock_ratio[i].index > max_multiplier) + clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; + else + clock_ratio[i].frequency = busfreq * clock_ratio[i].index; + } + + driver->verify = &powernow_k6_verify; + driver->setpolicy = &powernow_k6_setpolicy; + + /* cpuinfo and default policy values */ + driver->policy[0].cpu = 0; + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; +#ifdef CONFIG_CPU_FREQ_24_API + driver->cpu_cur_freq[0] = busfreq * max_multiplier; +#endif + result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &clock_ratio[0]); + if (result) { + kfree(driver); + return result; + } + + powernow_driver = driver; + + result = cpufreq_register(driver); + if (result) { + release_region (POWERNOW_IOPORT, 16); + powernow_driver = NULL; + kfree(driver); + } + + return result; +} + + +/** + * powernow_k6_exit - unregisters AMD K6-2+/3+ PowerNow! support + * + * Unregisters AMD K6-2+ / K6-3+ PowerNow! support. + */ +static void __exit powernow_k6_exit(void) +{ + unsigned int i; + + if (powernow_driver) { + for (i=0;i<8;i++) + if (clock_ratio[i].index == max_multiplier) + powernow_k6_set_state(i); + cpufreq_unregister(); + kfree(powernow_driver); + } +} + + +MODULE_AUTHOR ("Arjan van de Ven , Dave Jones , Dominik Brodowski "); +MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); +MODULE_LICENSE ("GPL"); +module_init(powernow_k6_init); +module_exit(powernow_k6_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/process.c linux.21pre4-ac6/arch/i386/kernel/process.c --- linux.21pre4/arch/i386/kernel/process.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/process.c 2003-01-06 19:12:06.000000000 +0000 @@ -124,15 +124,12 @@ void cpu_idle (void) { /* endless idle loop with no priority at all */ - init_idle(); - current->nice = 20; - current->counter = -100; while (1) { void (*idle)(void) = pm_idle; if (!idle) idle = default_idle; - while (!current->need_resched) + if (!current->need_resched) idle(); schedule(); check_pgt_cache(); @@ -187,7 +184,7 @@ } /* we will leave sorting out the final value when we are ready to reboot, since we might not - have set up boot_cpu_id or smp_num_cpu */ + have set up boot_cpu_physical_apicid or smp_num_cpu */ break; #endif } @@ -253,7 +250,7 @@ 0x66, 0x0f, 0x20, 0xc3, /* movl %cr0,%ebx */ 0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60, /* andl $0x60000000,%ebx */ 0x74, 0x02, /* jz f */ - 0x0f, 0x08, /* invd */ + 0x0f, 0x09, /* wbinvd */ 0x24, 0x10, /* f: andb $0x10,al */ 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ }; @@ -466,23 +463,6 @@ } /* - * No need to lock the MM as we are the last user - */ -void release_segments(struct mm_struct *mm) -{ - void * ldt = mm->context.segments; - - /* - * free the LDT - */ - if (ldt) { - mm->context.segments = NULL; - clear_LDT(); - vfree(ldt); - } -} - -/* * Create a kernel thread */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -534,45 +514,19 @@ void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { - void * ldt = dead_task->mm->context.segments; - // temporary debugging check - if (ldt) { - printk("WARNING: dead process %8s still has LDT? <%p>\n", - dead_task->comm, ldt); + if (dead_task->mm->context.size) { + printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", + dead_task->comm, + dead_task->mm->context.ldt, + dead_task->mm->context.size); BUG(); } } - release_x86_irqs(dead_task); } /* - * we do not have to muck with descriptors here, that is - * done in switch_mm() as needed. - */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) -{ - struct mm_struct * old_mm; - void *old_ldt, *ldt; - - ldt = NULL; - old_mm = current->mm; - if (old_mm && (old_ldt = old_mm->context.segments) != NULL) { - /* - * Completely new LDT, we initialize it from the parent: - */ - ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - if (!ldt) - printk(KERN_WARNING "ldt allocation failed\n"); - else - memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE); - } - new_mm->context.segments = ldt; - new_mm->context.cpuvalid = ~0UL; /* valid on all CPU's - they can't have stale data */ -} - -/* * Save a segment. */ #define savesegment(seg,value) \ @@ -697,15 +651,17 @@ asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs)); /* - * Restore %fs and %gs. + * Restore %fs and %gs if needed. */ - loadsegment(fs, next->fs); - loadsegment(gs, next->gs); + if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) { + loadsegment(fs, next->fs); + loadsegment(gs, next->gs); + } /* * Now maybe reload the debug registers */ - if (next->debugreg[7]){ + if (unlikely(next->debugreg[7])) { loaddebug(next, 0); loaddebug(next, 1); loaddebug(next, 2); @@ -715,7 +671,7 @@ loaddebug(next, 7); } - if (prev->ioperm || next->ioperm) { + if (unlikely(prev->ioperm || next->ioperm)) { if (next->ioperm) { /* * 4 cachelines copy ... not good, but not that diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/setup.c linux.21pre4-ac6/arch/i386/kernel/setup.c --- linux.21pre4/arch/i386/kernel/setup.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/setup.c 2003-02-21 17:48:58.000000000 +0000 @@ -118,6 +118,7 @@ #include #include #include +#include /* * Machine setup.. */ @@ -196,6 +197,8 @@ #define KERNEL_START (*(unsigned long *) (PARAM+0x214)) #define INITRD_START (*(unsigned long *) (PARAM+0x218)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) +#define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) +#define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE ((char *) (PARAM+2048)) #define COMMAND_LINE_SIZE 256 @@ -203,6 +206,7 @@ #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 + #ifdef CONFIG_VISWS char visws_board_type = -1; char visws_board_rev = -1; @@ -700,6 +704,23 @@ return 0; } +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +unsigned char eddnr; +struct edd_info edd[EDDMAXNR]; +/** + * copy_edd() - Copy the BIOS EDD information + * from empty_zero_page into a safe place. + * + */ +static inline void copy_edd(void) +{ + eddnr = EDD_NR; + memcpy(edd, EDD_BUF, sizeof(edd)); +} +#else +#define copy_edd() do {} while (0) +#endif + /* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines. @@ -1112,6 +1133,7 @@ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); #endif setup_memory_region(); + copy_edd(); if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; @@ -1419,7 +1441,7 @@ * If the BIOS didn't enable it already, enable it * here. */ - if (c->x86_model == 6 || c->x86_model == 7) { + if (c->x86_model >= 6 && c->x86_model <= 10) { if (!test_bit(X86_FEATURE_XMM, &c->x86_capability)) { printk(KERN_INFO @@ -2918,6 +2940,7 @@ * applications want to get the raw CPUID data, they should access * /dev/cpu//cpuid instead. */ + extern int phys_proc_id[NR_CPUS]; static char *x86_cap_flags[] = { /* Intel-defined */ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", @@ -2975,6 +2998,11 @@ /* Cache size */ if (c->x86_cache_size >= 0) seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); + +#ifdef CONFIG_SMP + seq_printf(m, "physical id\t: %d\n",phys_proc_id[n]); + seq_printf(m, "siblings\t: %d\n",smp_num_siblings); +#endif /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */ fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu); @@ -3077,11 +3105,12 @@ set_tss_desc(nr,t); gdt_table[__TSS(nr)].b &= 0xfffffdff; load_TR(nr); - load_LDT(&init_mm); + load_LDT(&init_mm.context); - /* - * Clear all 6 debug registers: - */ + /* Clear %fs and %gs. */ + asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); + + /* Clear all 6 debug registers: */ #define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/smpboot.c linux.21pre4-ac6/arch/i386/kernel/smpboot.c --- linux.21pre4/arch/i386/kernel/smpboot.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/smpboot.c 2003-01-06 19:12:31.000000000 +0000 @@ -58,7 +58,7 @@ /* Number of siblings per CPU package */ int smp_num_siblings = 1; -int __initdata phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ +int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ /* Bitmask of currently online CPUs */ unsigned long cpu_online_map; @@ -365,7 +365,7 @@ * (This works even if the APIC is not enabled.) */ phys_id = GET_APIC_ID(apic_read(APIC_ID)); - cpuid = current->processor; + cpuid = cpu(); if (test_and_set_bit(cpuid, &cpu_online_map)) { printk("huh, phys CPU#%d, CPU#%d already present??\n", phys_id, cpuid); @@ -435,6 +435,7 @@ */ smp_store_cpu_info(cpuid); + disable_APIC_timer(); /* * Allow the master to continue. */ @@ -443,7 +444,7 @@ /* * Synchronize the TSC with the BP */ - if (cpu_has_tsc) + if (cpu_has_tsc > 1) synchronize_tsc_ap(); } @@ -465,6 +466,7 @@ smp_callin(); while (!atomic_read(&smp_commenced)) rep_nop(); + enable_APIC_timer(); /* * low-memory mappings have been cleared, flush them from * the local TLBs too. @@ -803,16 +805,13 @@ if (!idle) panic("No idle process for CPU %d", cpu); - idle->processor = cpu; - idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */ + init_idle(idle, cpu); map_cpu_to_boot_apicid(cpu, apicid); idle->thread.eip = (unsigned long) start_secondary; - del_from_runqueue(idle); unhash_process(idle); - init_tasks[cpu] = idle; /* start_eip had better be page-aligned! */ start_eip = setup_trampoline(); @@ -925,6 +924,7 @@ } cycles_t cacheflush_time; +unsigned long cache_decay_ticks; static void smp_tune_scheduling (void) { @@ -958,9 +958,13 @@ cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth; } + cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000; + printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", (long)cacheflush_time/(cpu_khz/1000), ((long)cacheflush_time*100/(cpu_khz/1000)) % 100); + printk("task migration cache decay timeout: %ld msecs.\n", + (cache_decay_ticks + 1) * 1000 / HZ); } /* @@ -1026,8 +1030,7 @@ map_cpu_to_boot_apicid(0, boot_cpu_apicid); global_irq_holder = 0; - current->processor = 0; - init_idle(); + current->cpu = 0; smp_tune_scheduling(); /* @@ -1219,7 +1222,7 @@ /* * Synchronize the TSC with the AP */ - if (cpu_has_tsc && cpucount) + if (cpu_has_tsc > 1 && cpucount) synchronize_tsc_bp(); smp_done: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/smp.c linux.21pre4-ac6/arch/i386/kernel/smp.c --- linux.21pre4/arch/i386/kernel/smp.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/smp.c 2003-01-06 19:12:38.000000000 +0000 @@ -496,13 +496,23 @@ * it goes straight through and wastes no time serializing * anything. Worst case is that we lose a reschedule ... */ - void smp_send_reschedule(int cpu) { send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); } /* + * this function sends a reschedule IPI to all (other) CPUs. + * This should only be used if some 'global' task became runnable, + * such as a RT task, that must be handled now. The first CPU + * that manages to grab the task will run it. + */ +void smp_send_reschedule_all(void) +{ + send_IPI_allbutself(RESCHEDULE_VECTOR); +} + +/* * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/speedstep.c linux.21pre4-ac6/arch/i386/kernel/speedstep.c --- linux.21pre4/arch/i386/kernel/speedstep.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/i386/kernel/speedstep.c 2003-01-10 16:27:32.000000000 +0000 @@ -0,0 +1,731 @@ +/* + * $Id: speedstep.c,v 1.64 2003/01/02 22:16:26 db Exp $ + * + * (C) 2001 Dave Jones, Arjan van de ven. + * (C) 2002 Dominik Brodowski + * + * Licensed under the terms of the GNU GPL License version 2. + * Based upon reverse engineered information, and on Intel documentation + * for chipsets ICH2-M and ICH3-M. + * + * Many thanks to Ducrot Bruno for finding and fixing the last + * "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler + * for extensive testing. + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + */ + + +/********************************************************************* + * SPEEDSTEP - DEFINITIONS * + *********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include + + +static struct cpufreq_driver *speedstep_driver; + +/* speedstep_chipset: + * It is necessary to know which chipset is used. As accesses to + * this device occur at various places in this module, we need a + * static struct pci_dev * pointing to that device. + */ +static unsigned int speedstep_chipset; +static struct pci_dev *speedstep_chipset_dev; + +#define SPEEDSTEP_CHIPSET_ICH2M 0x00000002 +#define SPEEDSTEP_CHIPSET_ICH3M 0x00000003 + + +/* speedstep_processor + */ +static unsigned int speedstep_processor = 0; +static int speedstep_coppermine = 0; + +#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000001 /* Coppermine core */ +#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000002 /* Tualatin core */ +#define SPEEDSTEP_PROCESSOR_P4M 0x00000003 /* P4-M with 100 MHz FSB */ + + +/* speedstep_[low,high]_freq + * There are only two frequency states for each processor. Values + * are in kHz for the time being. + */ +#define SPEEDSTEP_HIGH 0x00000000 +#define SPEEDSTEP_LOW 0x00000001 + +static struct cpufreq_frequency_table speedstep_freqs[] = { + {SPEEDSTEP_HIGH, 0}, + {SPEEDSTEP_LOW, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +#define speedstep_low_freq speedstep_freqs[SPEEDSTEP_LOW].frequency +#define speedstep_high_freq speedstep_freqs[SPEEDSTEP_HIGH].frequency + + +/* DEBUG + * Define it if you want verbose debug output, e.g. for bug reporting + */ +//#define SPEEDSTEP_DEBUG + +#ifdef SPEEDSTEP_DEBUG +#define dprintk(msg...) printk(msg) +#else +#define dprintk(msg...) do { } while(0) +#endif + + + +/********************************************************************* + * LOW LEVEL CHIPSET INTERFACE * + *********************************************************************/ + +/** + * speedstep_get_state - read the current SpeedStep state + * @state: Speedstep state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) + * + * Tries to read the SpeedStep state. Returns -EIO when there has been + * trouble to read the status or write to the control register, -EINVAL + * on an unsupported chipset, and zero on success. + */ +static int speedstep_get_state (unsigned int *state) +{ + unsigned long flags; + u32 pmbase; + u8 value; + + if (!speedstep_chipset_dev || !state) + return -EINVAL; + + switch (speedstep_chipset) { + case SPEEDSTEP_CHIPSET_ICH2M: + case SPEEDSTEP_CHIPSET_ICH3M: + /* get PMBASE */ + pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); + if (!(pmbase & 0x01)) + return -EIO; + + pmbase &= 0xFFFFFFFE; + if (!pmbase) + return -EIO; + + /* read state */ + local_irq_save(flags); + value = inb(pmbase + 0x50); + local_irq_restore(flags); + + dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + + *state = value & 0x01; + return 0; + + } + + printk (KERN_ERR "cpufreq: setting CPU frequency on this chipset unsupported.\n"); + return -EINVAL; +} + + +/** + * speedstep_set_state - set the SpeedStep state + * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) + * + * Tries to change the SpeedStep state. + */ +static void speedstep_set_state (unsigned int state, int notify) +{ + u32 pmbase; + u8 pm2_blk; + u8 value; + unsigned long flags; + unsigned int oldstate; + struct cpufreq_freqs freqs; + + if (!speedstep_chipset_dev || (state > 0x1)) + return; + + if (speedstep_get_state(&oldstate)) + return; + + if (oldstate == state) + return; + + freqs.old = (oldstate == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; + freqs.new = (state == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; + freqs.cpu = 0; /* speedstep.c is UP only driver */ + + if (notify) + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + switch (speedstep_chipset) { + case SPEEDSTEP_CHIPSET_ICH2M: + case SPEEDSTEP_CHIPSET_ICH3M: + /* get PMBASE */ + pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); + if (!(pmbase & 0x01)) + { + printk(KERN_ERR "cpufreq: could not find speedstep register\n"); + return; + } + + pmbase &= 0xFFFFFFFE; + if (!pmbase) { + printk(KERN_ERR "cpufreq: could not find speedstep register\n"); + return; + } + + /* Disable IRQs */ + local_irq_save(flags); + + /* read state */ + value = inb(pmbase + 0x50); + + dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + + /* write new state */ + value &= 0xFE; + value |= state; + + dprintk(KERN_DEBUG "cpufreq: writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); + + /* Disable bus master arbitration */ + pm2_blk = inb(pmbase + 0x20); + pm2_blk |= 0x01; + outb(pm2_blk, (pmbase + 0x20)); + + /* Actual transition */ + outb(value, (pmbase + 0x50)); + + /* Restore bus master arbitration */ + pm2_blk &= 0xfe; + outb(pm2_blk, (pmbase + 0x20)); + + /* check if transition was sucessful */ + value = inb(pmbase + 0x50); + + /* Enable IRQs */ + local_irq_restore(flags); + + dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + + if (state == (value & 0x1)) { + dprintk (KERN_INFO "cpufreq: change to %u MHz succeded\n", (freqs.new / 1000)); + } else { + printk (KERN_ERR "cpufreq: change failed - I/O error\n"); + } + break; + default: + printk (KERN_ERR "cpufreq: setting CPU frequency on this chipset unsupported.\n"); + } + + if (notify) + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return; +} + + +/** + * speedstep_activate - activate SpeedStep control in the chipset + * + * Tries to activate the SpeedStep status and control registers. + * Returns -EINVAL on an unsupported chipset, and zero on success. + */ +static int speedstep_activate (void) +{ + if (!speedstep_chipset_dev) + return -EINVAL; + + switch (speedstep_chipset) { + case SPEEDSTEP_CHIPSET_ICH2M: + case SPEEDSTEP_CHIPSET_ICH3M: + { + u16 value = 0; + + pci_read_config_word(speedstep_chipset_dev, + 0x00A0, &value); + if (!(value & 0x08)) { + value |= 0x08; + dprintk(KERN_DEBUG "cpufreq: activating SpeedStep (TM) registers\n"); + pci_write_config_word(speedstep_chipset_dev, + 0x00A0, value); + } + + return 0; + } + } + + printk (KERN_ERR "cpufreq: SpeedStep (TM) on this chipset unsupported.\n"); + return -EINVAL; +} + + +/** + * speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic + * + * Detects PIIX4, ICH2-M and ICH3-M so far. The pci_dev points to + * the LPC bridge / PM module which contains all power-management + * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected + * chipset, or zero on failure. + */ +static unsigned int speedstep_detect_chipset (void) +{ + speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801CA_12, + PCI_ANY_ID, + PCI_ANY_ID, + NULL); + if (speedstep_chipset_dev) + return SPEEDSTEP_CHIPSET_ICH3M; + + + speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801BA_10, + PCI_ANY_ID, + PCI_ANY_ID, + NULL); + if (speedstep_chipset_dev) { + /* speedstep.c causes lockups on Dell Inspirons 8000 and + * 8100 which use a pretty old revision of the 82815 + * host brige. Abort on these systems. + */ + static struct pci_dev *hostbridge; + u8 rev = 0; + + hostbridge = pci_find_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82815_MC, + PCI_ANY_ID, + PCI_ANY_ID, + NULL); + + if (!hostbridge) + return SPEEDSTEP_CHIPSET_ICH2M; + + pci_read_config_byte(hostbridge, PCI_REVISION_ID, &rev); + if (rev < 5) { + dprintk(KERN_INFO "cpufreq: hostbrige does not support speedstep\n"); + speedstep_chipset_dev = NULL; + return 0; + } + + return SPEEDSTEP_CHIPSET_ICH2M; + } + + return 0; +} + + + +/********************************************************************* + * LOW LEVEL PROCESSOR INTERFACE * + *********************************************************************/ + + +/** + * pentium3_get_frequency - get the core frequencies for PIIIs + * + * Returns the core frequency of a Pentium III processor (in kHz) + */ +static unsigned int pentium3_get_frequency (void) +{ + /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ + struct { + unsigned int ratio; /* Frequency Multiplier (x10) */ + u8 bitmap; /* power on configuration bits + [27, 25:22] (in MSR 0x2a) */ + } msr_decode_mult [] = { + { 30, 0x01 }, + { 35, 0x05 }, + { 40, 0x02 }, + { 45, 0x06 }, + { 50, 0x00 }, + { 55, 0x04 }, + { 60, 0x0b }, + { 65, 0x0f }, + { 70, 0x09 }, + { 75, 0x0d }, + { 80, 0x0a }, + { 85, 0x26 }, + { 90, 0x20 }, + { 100, 0x2b }, + { 0, 0xff } /* error or unknown value */ + }; + /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ + struct { + unsigned int value; /* Front Side Bus speed in MHz */ + u8 bitmap; /* power on configuration bits [18: 19] + (in MSR 0x2a) */ + } msr_decode_fsb [] = { + { 66, 0x0 }, + { 100, 0x2 }, + { 133, 0x1 }, + { 0, 0xff} + }; + u32 msr_lo, msr_tmp; + int i = 0, j = 0; + struct cpuinfo_x86 *c = cpu_data; + + /* read MSR 0x2a - we only need the low 32 bits */ + rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); + dprintk(KERN_DEBUG "cpufreq: P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); + msr_tmp = msr_lo; + + /* decode the FSB */ + msr_tmp &= 0x00c0000; + msr_tmp >>= 18; + while (msr_tmp != msr_decode_fsb[i].bitmap) { + if (msr_decode_fsb[i].bitmap == 0xff) + return -EINVAL; + i++; + } + + /* decode the multiplier */ + if ((c->x86_model == 0x08) && (c->x86_mask == 0x01)) + /* different on early Coppermine PIII */ + msr_lo &= 0x03c00000; + else + msr_lo &= 0x0bc00000; + msr_lo >>= 22; + while (msr_lo != msr_decode_mult[j].bitmap) { + if (msr_decode_mult[j].bitmap == 0xff) + return -EINVAL; + j++; + } + + return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100); +} + + +/** + * pentium4_get_frequency - get the core frequency for P4-Ms + * + * Should return the core frequency (in kHz) for P4-Ms. + */ +static unsigned int pentium4_get_frequency(void) +{ + u32 msr_lo, msr_hi; + + rdmsr(0x2c, msr_lo, msr_hi); + + dprintk(KERN_DEBUG "cpufreq: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); + + /* First 12 bits seem to change a lot (0x511, 0x410 and 0x30f seen + * yet). Next 12 bits always seem to be 0x300. If this is not true + * on this CPU, complain. Last 8 bits are frequency (in 100MHz). + */ + if (msr_hi || ((msr_lo & 0x00FFF000) != 0x300000)) { + printk(KERN_DEBUG "cpufreq: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); + printk(KERN_INFO "cpufreq: problem in initialization. Please contact Dominik Brodowski\n"); + printk(KERN_INFO "cpufreq: and attach this dmesg. Thanks in advance\n"); + return 0; + } + + msr_lo >>= 24; + return (msr_lo * 100000); +} + + +/** + * speedstep_detect_processor - detect Intel SpeedStep-capable processors. + * + * Returns the SPEEDSTEP_PROCESSOR_-number for the detected processor, + * or zero on failure. + */ +static unsigned int speedstep_detect_processor (void) +{ + struct cpuinfo_x86 *c = cpu_data; + u32 ebx; + + if ((c->x86_vendor != X86_VENDOR_INTEL) || + ((c->x86 != 6) && (c->x86 != 0xF))) + return 0; + + if (c->x86 == 0xF) { + /* Intel Pentium 4 Mobile P4-M */ + if (c->x86_model != 2) + return 0; + + if ((c->x86_mask != 4) && (c->x86_mask != 7)) + return 0; + + ebx = cpuid_ebx(0x00000001); + ebx &= 0x000000FF; + if ((ebx != 0x0e) && (ebx != 0x0f)) + return 0; + + return SPEEDSTEP_PROCESSOR_P4M; + } + + switch (c->x86_model) { + case 0x0B: /* Intel PIII [Tualatin] */ + /* cpuid_ebx(1) is 0x04 for desktop PIII, + 0x06 for mobile PIII-M */ + ebx = cpuid_ebx(0x00000001); + + ebx &= 0x000000FF; + if (ebx != 0x06) + return 0; + + /* So far all PIII-M processors support SpeedStep. See + * Intel's 24540633.pdf of August 2002 + */ + + return SPEEDSTEP_PROCESSOR_PIII_T; + + case 0x08: /* Intel PIII [Coppermine] */ + { + u32 msr_lo, msr_hi; + + /* all mobile PIII Coppermines have FSB 100 MHz + * ==> sort out a few desktop PIIIs. */ + rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); + dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_EBL_Cr_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi); + msr_lo &= 0x00c0000; + if (msr_lo != 0x0080000) + return 0; + + if (speedstep_coppermine) + return SPEEDSTEP_PROCESSOR_PIII_C; + + printk(KERN_INFO "cpufreq: in case this is a SpeedStep-capable Intel Pentium III Coppermine\n"); + printk(KERN_INFO "cpufreq: processor, please pass the boot option or module parameter\n"); + printk(KERN_INFO "cpufreq: `speedstep_coppermine=1` to the kernel. Thanks!\n"); + return 0; + } + + default: + return 0; + } +} + + + +/********************************************************************* + * HIGH LEVEL FUNCTIONS * + *********************************************************************/ + +/** + * speedstep_detect_speeds - detects low and high CPU frequencies. + * + * Detects the low and high CPU frequencies in kHz. Returns 0 on + * success or -EINVAL / -EIO on problems. + */ +static int speedstep_detect_speeds (void) +{ + unsigned long flags; + unsigned int state; + int i, result; + + /* Disable irqs for entire detection process */ + local_irq_save(flags); + + for (i=0; i<2; i++) { + /* read the current state */ + result = speedstep_get_state(&state); + if (result) + return result; + + /* save the correct value, and switch to other */ + if (state == SPEEDSTEP_LOW) { + switch (speedstep_processor) { + case SPEEDSTEP_PROCESSOR_PIII_C: + case SPEEDSTEP_PROCESSOR_PIII_T: + speedstep_low_freq = pentium3_get_frequency(); + break; + case SPEEDSTEP_PROCESSOR_P4M: + speedstep_low_freq = pentium4_get_frequency(); + } + speedstep_set_state(SPEEDSTEP_HIGH, 0); + } else { + switch (speedstep_processor) { + case SPEEDSTEP_PROCESSOR_PIII_C: + case SPEEDSTEP_PROCESSOR_PIII_T: + speedstep_high_freq = pentium3_get_frequency(); + break; + case SPEEDSTEP_PROCESSOR_P4M: + speedstep_high_freq = pentium4_get_frequency(); + } + speedstep_set_state(SPEEDSTEP_LOW, 0); + } + } + + local_irq_restore(flags); + + if (!speedstep_low_freq || !speedstep_high_freq || + (speedstep_low_freq == speedstep_high_freq)) + return -EIO; + + return 0; +} + + +/** + * speedstep_setpolicy - set a new CPUFreq policy + * @policy: new policy + * + * Sets a new CPUFreq policy. + */ +static int speedstep_setpolicy (struct cpufreq_policy *policy) +{ + unsigned int newstate = 0; + + if (cpufreq_frequency_table_setpolicy(policy, &speedstep_freqs[0], &newstate)) + return -EINVAL; + + speedstep_set_state(newstate, 1); + + return 0; +} + + +/** + * speedstep_verify - verifies a new CPUFreq policy + * @freq: new policy + * + * Limit must be within speedstep_low_freq and speedstep_high_freq, with + * at least one border included. + */ +static int speedstep_verify (struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); +} + + +#ifndef MODULE +/** + * speedstep_setup speedstep command line parameter parsing + * + * speedstep command line parameter. Use: + * speedstep_coppermine=1 + * if the CPU in your notebook is a SpeedStep-capable Intel + * Pentium III Coppermine. These processors cannot be detected + * automatically, as Intel continues to consider the detection + * alogrithm as proprietary material. + */ +static int __init speedstep_setup(char *str) +{ + speedstep_coppermine = simple_strtoul(str, &str, 0); + return 1; +} +__setup("speedstep_coppermine=", speedstep_setup); +#endif + +/** + * speedstep_init - initializes the SpeedStep CPUFreq driver + * + * Initializes the SpeedStep support. Returns -ENODEV on unsupported + * devices, -EINVAL on problems during initiatization, and zero on + * success. + */ +static int __init speedstep_init(void) +{ + int result; + unsigned int speed; + struct cpufreq_driver *driver; + + + /* detect chipset */ + speedstep_chipset = speedstep_detect_chipset(); + + /* detect chipset */ + if (speedstep_chipset) + speedstep_processor = speedstep_detect_processor(); + + if ((!speedstep_chipset) || (!speedstep_processor)) { + printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset"); + return -ENODEV; + } + + dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.64 $\n"); + dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n", + speedstep_chipset, speedstep_processor); + + /* activate speedstep support */ + result = speedstep_activate(); + if (result) + return result; + + /* detect low and high frequency */ + result = speedstep_detect_speeds(); + if (result) + return result; + + /* get current speed setting */ + result = speedstep_get_state(&speed); + if (result) + return result; + + speed = (speed == SPEEDSTEP_LOW) ? speedstep_low_freq : speedstep_high_freq; + + dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", + (speed == speedstep_low_freq) ? "low" : "high", + (speed / 1000)); + + /* initialization of main "cpufreq" code*/ + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) + return -ENOMEM; + + driver->policy = (struct cpufreq_policy *) (driver + 1); + + driver->policy[0].cpu = 0; + result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &speedstep_freqs[0]); + if (result) { + kfree(driver); + return result; + } + +#ifdef CONFIG_CPU_FREQ_24_API + driver->cpu_cur_freq[0] = speed; +#endif + + driver->verify = &speedstep_verify; + driver->setpolicy = &speedstep_setpolicy; + + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + + driver->policy[0].policy = (speed == speedstep_low_freq) ? + CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE; + + speedstep_driver = driver; + + result = cpufreq_register(driver); + if (result) { + speedstep_driver = NULL; + kfree(driver); + } + + return result; +} + + +/** + * speedstep_exit - unregisters SpeedStep support + * + * Unregisters SpeedStep support. + */ +static void __exit speedstep_exit(void) +{ + if (speedstep_driver) { + cpufreq_unregister(); + kfree(speedstep_driver); + } +} + + +MODULE_AUTHOR ("Dave Jones , Dominik Brodowski "); +MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors."); +MODULE_LICENSE ("GPL"); +module_init(speedstep_init); +module_exit(speedstep_exit); + +MODULE_PARM (speedstep_coppermine, "i"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/time.c linux.21pre4-ac6/arch/i386/kernel/time.c --- linux.21pre4/arch/i386/kernel/time.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/time.c 2003-01-29 17:12:12.000000000 +0000 @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include @@ -833,6 +835,50 @@ return 0; } +#ifdef CONFIG_CPU_FREQ +static unsigned int ref_freq = 0; +static unsigned long loops_per_jiffy_ref = 0; + +#ifndef CONFIG_SMP +static unsigned long fast_gettimeoffset_ref = 0; +static unsigned long cpu_khz_ref = 0; +#endif + +static int +time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct cpufreq_freqs *freq = data; + + if (!ref_freq) { + ref_freq = freq->old; + loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; +#ifndef CONFIG_SMP + fast_gettimeoffset_ref = fast_gettimeoffset_quotient; + cpu_khz_ref = cpu_khz; +#endif + } + + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { + cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); +#ifndef CONFIG_SMP + if (use_tsc) { + fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq); + cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); + } +#endif + } + + return 0; +} + +static struct notifier_block time_cpufreq_notifier_block = { + .notifier_call = time_cpufreq_notifier +}; +#endif + + void __init time_init(void) { extern int x86_udelay_tsc; @@ -904,6 +950,9 @@ } } +#ifdef CONFIG_CPU_FREQ + cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); +#endif #ifdef CONFIG_VISWS printk("Starting Cobalt Timer system clock\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/kernel/traps.c linux.21pre4-ac6/arch/i386/kernel/traps.c --- linux.21pre4/arch/i386/kernel/traps.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/kernel/traps.c 2003-01-06 15:42:33.000000000 +0000 @@ -284,6 +284,20 @@ void die(const char * str, struct pt_regs * regs, long err) { +#ifdef CONFIG_PNPBIOS + if (regs->xcs == 0x60 || regs->xcs == 0x68) + { + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; + extern u32 pnp_bios_is_utter_crap; + pnp_bios_is_utter_crap = 1; + printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n"); + __asm__ volatile( + "movl %0, %%esp\n\t" + "jmp %1\n\t" + : "=a" (pnp_bios_fault_esp), "=b" (pnp_bios_fault_eip)); + panic("do_trap: can't hit this"); + } +#endif console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/lib/delay.c linux.21pre4-ac6/arch/i386/lib/delay.c --- linux.21pre4/arch/i386/lib/delay.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/lib/delay.c 2003-02-05 18:09:34.000000000 +0000 @@ -56,7 +56,7 @@ :"=&a" (d0) :"0" (loops)); } -extern __cyclone_delay(unsigned long loops); +extern void __cyclone_delay(unsigned long loops); extern int use_cyclone; void __delay(unsigned long loops) { @@ -81,3 +81,8 @@ { __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/Makefile linux.21pre4-ac6/arch/i386/Makefile --- linux.21pre4/arch/i386/Makefile 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/Makefile 2003-02-24 00:00:07.000000000 +0000 @@ -23,8 +23,10 @@ CFLAGS += -pipe +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + # prevent gcc from keeping the stack 16 byte aligned -CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi) +CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,) ifdef CONFIG_M386 CFLAGS += -march=i386 @@ -59,15 +61,16 @@ endif ifdef CONFIG_MK6 -CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; else echo "-march=i586"; fi) +CFLAGS += $(call check_gcc,-march=k6,-march=i586) endif ifdef CONFIG_MK7 -CFLAGS += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else echo "-march=i686 -malign-functions=4"; fi) +CFLAGS += $(call check_gcc,-march=athlon,-march=i686 -malign-functions=4) endif ifdef CONFIG_MCRUSOE -CFLAGS += -march=i686 -malign-functions=0 -malign-jumps=0 -malign-loops=0 +CFLAGS += -march=i686 +CFLAGS += $(call check_gcc,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0) endif ifdef CONFIG_MWINCHIPC6 @@ -83,7 +86,8 @@ endif ifdef CONFIG_MCYRIXIII -CFLAGS += -march=i486 -malign-functions=0 -malign-jumps=0 -malign-loops=0 +CFLAGS += $(call check_gcc,-march=c3,-march=i486) +CFLAGS += $(call check_gcc,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0) endif HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/math-emu/fpu_system.h linux.21pre4-ac6/arch/i386/math-emu/fpu_system.h --- linux.21pre4/arch/i386/math-emu/fpu_system.h 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/math-emu/fpu_system.h 2003-01-06 19:12:50.000000000 +0000 @@ -20,7 +20,7 @@ of the stack frame of math_emulate() */ #define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg -#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.segments)[(s) >> 3]) +#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) #define SEG_D_SIZE(x) ((x).b & (3 << 21)) #define SEG_G_BIT(x) ((x).b & (1 << 23)) #define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/mm/fault.c linux.21pre4-ac6/arch/i386/mm/fault.c --- linux.21pre4/arch/i386/mm/fault.c 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/mm/fault.c 2003-01-06 19:10:27.000000000 +0000 @@ -76,9 +76,7 @@ return 1; check_stack: - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - if (expand_stack(vma, start) == 0) + if (!expand_stack(vma, start)) goto good_area; bad_area: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/i386/mm/init.c linux.21pre4-ac6/arch/i386/mm/init.c --- linux.21pre4/arch/i386/mm/init.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/i386/mm/init.c 2003-01-08 15:27:29.000000000 +0000 @@ -510,7 +510,15 @@ if (!mem_map) BUG(); - +#ifdef CONFIG_HIGHMEM + /* check that fixmap and pkmap do not overlap */ + if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) { + printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n"); + printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n", + PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START); + BUG(); + } +#endif set_max_mapnr_init(); high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ia64/ia32/sys_ia32.c linux.21pre4-ac6/arch/ia64/ia32/sys_ia32.c --- linux.21pre4/arch/ia64/ia32/sys_ia32.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/ia64/ia32/sys_ia32.c 2003-01-06 23:19:29.000000000 +0000 @@ -3782,7 +3782,11 @@ return result; } -struct dqblk32 { +extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr); + +#ifdef CONFIG_QIFACE_COMPAT +#ifdef CONFIG_QIFACE_V1 +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -3792,49 +3796,82 @@ __kernel_time_t32 dqb_btime; __kernel_time_t32 dqb_itime; }; +typedef struct v1c_mem_dqblk comp_dqblk_t; -asmlinkage long -sys32_quotactl (int cmd, unsigned int special, int id, struct dqblk32 *addr) +#define Q_COMP_GETQUOTA Q_V1_GETQUOTA +#define Q_COMP_SETQUOTA Q_V1_SETQUOTA +#define Q_COMP_SETQLIM Q_V1_SETQLIM +#define Q_COMP_SETUSE Q_V1_SETUSE +#else +struct user_dqblk32 { + __u32 dqb_ihardlimit; + __u32 dqb_isoftlimit; + __u32 dqb_curinodes; + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u64 dqb_curspace; + __kernel_time_t32 dqb_btime; + __kernel_time_t32 dqb_itime; +}; +typedef struct v2c_mem_dqblk comp_dqblk_t; + +#define Q_COMP_GETQUOTA Q_V2_GETQUOTA +#define Q_COMP_SETQUOTA Q_V2_SETQUOTA +#define Q_COMP_SETQLIM Q_V2_SETQLIM +#define Q_COMP_SETUSE Q_V2_SETUSE +#endif + +asmlinkage long sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) { - extern asmlinkage long sys_quotactl (int, const char *, int, caddr_t); int cmds = cmd >> SUBCMDSHIFT; + long err; + comp_dqblk_t d; mm_segment_t old_fs; - struct dqblk d; char *spec; - long err; - + switch (cmds) { - case Q_GETQUOTA: - break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, addr, sizeof(struct dqblk32))) - return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; - break; - default: - return sys_quotactl(cmd, (void *) A(special), id, (caddr_t) addr); + case Q_COMP_GETQUOTA: + break; + case Q_COMP_SETQUOTA: + case Q_COMP_SETUSE: + case Q_COMP_SETQLIM: + if (copy_from_user(&d, (struct user_dqblk32 *)addr, + sizeof (struct user_dqblk32))) + return -EFAULT; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; + break; + default: + return sys_quotactl(cmd, special, id, (__kernel_caddr_t)addr); } - spec = getname32((void *) A(special)); + spec = getname (special); err = PTR_ERR(spec); - if (IS_ERR(spec)) + if (IS_ERR(spec)) return err; + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d); + set_fs (old_fs); + putname (spec); + if (err) return err; - old_fs = get_fs (); - set_fs(KERNEL_DS); - err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); - set_fs(old_fs); - putname(spec); - if (cmds == Q_GETQUOTA) { + if (cmds == Q_COMP_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct dqblk32 *)&d)->dqb_itime = i; - ((struct dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user(addr, &d, sizeof(struct dqblk32))) + ((struct user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user ((struct user_dqblk32 *)addr, &d, + sizeof (struct user_dqblk32))) return -EFAULT; } - return err; + return 0; +} + +#else +/* No conversion needed for new interface */ +asmlinkage long sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) +{ + return sys_quotactl(cmd, special, id, addr); } +#endif asmlinkage long sys32_sched_rr_get_interval (pid_t pid, struct timespec32 *interval) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ia64/mm/fault.c linux.21pre4-ac6/arch/ia64/mm/fault.c --- linux.21pre4/arch/ia64/mm/fault.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/ia64/mm/fault.c 2003-01-06 19:13:14.000000000 +0000 @@ -127,8 +127,6 @@ check_expansion: if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) { - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (rgn_index(address) != rgn_index(vma->vm_start) || rgn_offset(address) >= RGN_MAP_LIMIT) goto bad_area; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/m68k/config.in linux.21pre4-ac6/arch/m68k/config.in --- linux.21pre4/arch/m68k/config.in 2003-01-29 16:27:11.000000000 +0000 +++ linux.21pre4-ac6/arch/m68k/config.in 2003-01-28 16:35:25.000000000 +0000 @@ -517,9 +517,12 @@ if [ "$CONFIG_SUN3" = "y" ]; then define_bool CONFIG_GEN_RTC y else - bool 'Generic /dev/rtc emulation' CONFIG_GEN_RTC + tristate 'Generic /dev/rtc emulation' CONFIG_GEN_RTC fi fi +if [ "$CONFIG_GEN_RTC" != "n" ]; then + bool ' Extended RTC operation' CONFIG_GEN_RTC_X +fi bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then int ' Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/m68k/kernel/m68k_ksyms.c linux.21pre4-ac6/arch/m68k/kernel/m68k_ksyms.c --- linux.21pre4/arch/m68k/kernel/m68k_ksyms.c 2003-01-29 16:27:11.000000000 +0000 +++ linux.21pre4-ac6/arch/m68k/kernel/m68k_ksyms.c 2003-01-28 16:35:25.000000000 +0000 @@ -18,6 +18,7 @@ #include #include #include +#include asmlinkage long long __ashldi3 (long long, int); asmlinkage long long __ashrdi3 (long long, int); @@ -49,6 +50,10 @@ EXPORT_SYMBOL(kernel_set_cachemode); #endif /* !CONFIG_SUN3 */ EXPORT_SYMBOL(m68k_debug_device); +EXPORT_SYMBOL(mach_hwclk); +EXPORT_SYMBOL(mach_get_ss); +EXPORT_SYMBOL(mach_get_rtc_pll); +EXPORT_SYMBOL(mach_set_rtc_pll); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(strnlen); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/m68k/kernel/setup.c linux.21pre4-ac6/arch/m68k/kernel/setup.c --- linux.21pre4/arch/m68k/kernel/setup.c 2003-01-29 16:27:11.000000000 +0000 +++ linux.21pre4-ac6/arch/m68k/kernel/setup.c 2003-01-28 16:35:25.000000000 +0000 @@ -90,6 +90,9 @@ void (*mach_gettod) (int*, int*, int*, int*, int*, int*); int (*mach_hwclk) (int, struct rtc_time*) = NULL; int (*mach_set_clock_mmss) (unsigned long) = NULL; +unsigned int (*mach_get_ss)(void) = NULL; +int (*mach_get_rtc_pll)(struct rtc_pll_info *) = NULL; +int (*mach_set_rtc_pll)(struct rtc_pll_info *) = NULL; void (*mach_reset)( void ); void (*mach_halt)( void ) = NULL; void (*mach_power_off)( void ) = NULL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/m68k/q40/config.c linux.21pre4-ac6/arch/m68k/q40/config.c --- linux.21pre4/arch/m68k/q40/config.c 2003-01-29 16:27:14.000000000 +0000 +++ linux.21pre4-ac6/arch/m68k/q40/config.c 2003-01-28 16:35:25.000000000 +0000 @@ -58,7 +58,10 @@ extern void q40_gettod (int *year, int *mon, int *day, int *hour, int *min, int *sec); extern int q40_hwclk (int, struct rtc_time *); +extern unsigned int q40_get_ss (void); extern int q40_set_clock_mmss (unsigned long); +static int q40_get_rtc_pll(struct rtc_pll_info *pll); +static int q40_set_rtc_pll(struct rtc_pll_info *pll); extern void q40_reset (void); void q40_halt(void); extern void q40_waitbut(void); @@ -196,6 +199,9 @@ mach_gettimeoffset = q40_gettimeoffset; mach_gettod = q40_gettod; mach_hwclk = q40_hwclk; + mach_get_ss = q40_get_ss; + mach_get_rtc_pll = q40_get_rtc_pll; + mach_set_rtc_pll = q40_set_rtc_pll; mach_set_clock_mmss = q40_set_clock_mmss; mach_reset = q40_reset; @@ -331,6 +337,11 @@ return 0; } +unsigned int q40_get_ss() +{ + return bcd2bin(Q40_RTC_SECS); +} + /* * Set the minutes and seconds from seconds value 'nowtime'. Fail if * clock is out by > 30 minutes. Logic lifted from atari code. @@ -362,3 +373,33 @@ return retval; } + +/* get and set PLL calibration of RTC clock */ +#define Q40_RTC_PLL_MASK ((1<<5)-1) +#define Q40_RTC_PLL_SIGN (1<<5) + +static int q40_get_rtc_pll(struct rtc_pll_info *pll) +{ + int tmp=Q40_RTC_CTRL; + pll->pll_value = tmp & Q40_RTC_PLL_MASK; + if (tmp & Q40_RTC_PLL_SIGN) + pll->pll_value = -pll->pll_value; + pll->pll_max=31; + pll->pll_min=-31; + pll->pll_posmult=512; + pll->pll_negmult=256; + pll->pll_clock=125829120; + return 0; + } + +static int q40_set_rtc_pll(struct rtc_pll_info *pll) +{ + if (!pll->pll_ctrl){ + /* the docs are a bit unclear so I am doublesetting RTC_WRITE here ... */ + int tmp=(pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) | Q40_RTC_WRITE; + Q40_RTC_CTRL |= Q40_RTC_WRITE; + Q40_RTC_CTRL = tmp; + Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); + return 0; + } else return -EINVAL; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/mips/mm/fault.c linux.21pre4-ac6/arch/mips/mm/fault.c --- linux.21pre4/arch/mips/mm/fault.c 2003-01-29 16:27:06.000000000 +0000 +++ linux.21pre4-ac6/arch/mips/mm/fault.c 2003-01-06 19:13:14.000000000 +0000 @@ -111,8 +111,6 @@ goto bad_area; if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (expand_stack(vma, address)) goto bad_area; /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/mips64/mm/fault.c linux.21pre4-ac6/arch/mips64/mm/fault.c --- linux.21pre4/arch/mips64/mm/fault.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/mips64/mm/fault.c 2003-01-06 19:13:14.000000000 +0000 @@ -135,8 +135,6 @@ goto bad_area; if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (expand_stack(vma, address)) goto bad_area; /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/config.in linux.21pre4-ac6/arch/parisc/config.in --- linux.21pre4/arch/parisc/config.in 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/config.in 2003-01-06 15:38:40.000000000 +0000 @@ -47,9 +47,6 @@ bool 'Symmetric multi-processing support' CONFIG_SMP bool 'Chassis LCD and LED support' CONFIG_CHASSIS_LCD_LED -bool 'Kernel Debugger support' CONFIG_KWDB -# define_bool CONFIG_KWDB n - bool 'U2/Uturn I/O MMU' CONFIG_IOMMU_CCIO bool 'VSC/GSC/HSC bus support' CONFIG_GSC dep_bool ' Lasi I/O support' CONFIG_GSC_LASI $CONFIG_GSC @@ -194,6 +191,7 @@ #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ +bool 'Debug spinlocks' CONFIG_DEBUG_SPINLOCK endmenu source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/defconfig linux.21pre4-ac6/arch/parisc/defconfig --- linux.21pre4/arch/parisc/defconfig 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/defconfig 2003-01-06 15:38:40.000000000 +0000 @@ -32,7 +32,6 @@ # # CONFIG_SMP is not set CONFIG_CHASSIS_LCD_LED=y -# CONFIG_KWDB is not set CONFIG_IOMMU_CCIO=y CONFIG_GSC=y CONFIG_GSC_LASI=y @@ -87,7 +86,9 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -138,6 +139,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -155,6 +161,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # ATA/IDE/MFM/RLL support # CONFIG_IDE=y @@ -171,6 +182,7 @@ # CONFIG_BLK_DEV_HD is not set # CONFIG_BLK_DEV_IDEDISK is not set # CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set # CONFIG_BLK_DEV_IDEDISK_IBM is not set @@ -185,6 +197,7 @@ # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set # # IDE chipset support/bugfixes @@ -196,12 +209,15 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y -CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set # CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -209,6 +225,7 @@ # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CMD680 is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set @@ -296,9 +313,13 @@ CONFIG_53C700_USE_CONSISTENT=y # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -CONFIG_SCSI_SYM53C8XX=y +# CONFIG_ASK_ZALON is not set +# CONFIG_ASK_NCR53C8XX is not set +# CONFIG_ASK_SYM53C8XX is not set CONFIG_SCSI_ZALON=y +CONFIG_ASK_ZALON=y +CONFIG_SCSI_SYM53C8XX=y +CONFIG_ASK_SYM53C8XX=y CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 CONFIG_SCSI_NCR53C8XX_SYNC=20 @@ -366,6 +387,7 @@ # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y +# CONFIG_TC35815 is not set # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set @@ -403,6 +425,7 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -473,6 +496,7 @@ CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set # # Joysticks @@ -515,7 +539,6 @@ # # CONFIG_WATCHDOG is not set CONFIG_GENRTC=y -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -585,7 +608,7 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y # CONFIG_ZISOFS is not set @@ -697,6 +720,7 @@ # CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set # CONFIG_FB_CYBER2000 is not set CONFIG_FB_STI=y # CONFIG_FB_MATROX is not set @@ -704,6 +728,7 @@ # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set @@ -759,106 +784,6 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# -# CONFIG_USB_HID is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_WACOM is not set - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_RIO500 is not set - -# # Kernel hacking # CONFIG_MAGIC_SYSRQ=y diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/ccio-dma.c linux.21pre4-ac6/arch/parisc/kernel/ccio-dma.c --- linux.21pre4/arch/parisc/kernel/ccio-dma.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/ccio-dma.c 2003-01-06 15:38:40.000000000 +0000 @@ -609,8 +609,6 @@ return 0; } - dev->dma_mask = mask; /* save it */ - /* only support 32-bit devices (ie PCI/GSC) */ return (int)(mask == 0xffffffffUL); } @@ -1441,7 +1439,7 @@ result = request_resource(&iomem_resource, res); if (result < 0) { printk(KERN_ERR - "%s: failed to claim CCIO bus address space (%p,%p)\n", + "%s: failed to claim CCIO bus address space (%lx,%lx)\n", __FILE__, res->start, res->end); } } @@ -1486,7 +1484,7 @@ int ccio_allocate_resource(const struct parisc_device *dev, struct resource *res, unsigned long size, unsigned long min, unsigned long max, unsigned long align, - void (*alignf)(void *, struct resource *, unsigned long), + void (*alignf)(void *, struct resource *, unsigned long, unsigned long), void *alignf_data) { struct ioc *ioc = ccio_get_iommu(dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/ccio-rm-dma.c linux.21pre4-ac6/arch/parisc/kernel/ccio-rm-dma.c --- linux.21pre4/arch/parisc/kernel/ccio-rm-dma.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/ccio-rm-dma.c 2003-01-06 15:38:40.000000000 +0000 @@ -74,8 +74,6 @@ return(0); } - dev->dma_mask = mask; /* save it */ - /* only support 32-bit devices (ie PCI/GSC) */ return((int) (mask >= 0xffffffffUL)); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/drivers.c linux.21pre4-ac6/arch/parisc/kernel/drivers.c --- linux.21pre4/arch/parisc/kernel/drivers.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/drivers.c 2003-01-06 15:38:40.000000000 +0000 @@ -461,6 +461,7 @@ #define BC_PORT_MASK 0x8 #define BC_LOWER_PORT 0x8 + #define BUS_CONVERTER(dev) \ ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT)) @@ -473,14 +474,29 @@ __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low) << 16 : \ __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low)) -static void walk_native_bus(unsigned long addr, struct parisc_device *parent); +#define READ_IO_IO_HIGH(dev) \ + (dev->id.hw_type == HPHW_IOA ? \ + __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_high) << 16 : \ + __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_high)) + + +static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, + struct parisc_device *parent); + +#define FLEX_MASK (unsigned long)0xfffffffffffc0000 + + void walk_lower_bus(struct parisc_device *dev) { + unsigned long io_io_low, io_io_high; if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev)) return; - walk_native_bus((unsigned long)(signed int)READ_IO_IO_LOW(dev), dev); + io_io_low = ((unsigned long)(signed int)READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK; + io_io_high = ((unsigned long)(signed int)READ_IO_IO_HIGH(dev) + ~FLEX_MASK) & FLEX_MASK; + + walk_native_bus(io_io_low, io_io_high, dev); } #define MAX_NATIVE_DEVICES 64 @@ -488,7 +504,9 @@ /** * walk_native_bus -- Probe a bus for devices - * @addr: Base address of this bus. + * @io_io_low: Base address of this bus. + * @io_io_high: Last address of this bus. + * @parent: The parent bus device. * * A native bus (eg Runway or GSC) may have up to 64 devices on it, * spaced at intervals of 0x1000 bytes. PDC may not inform us of these @@ -496,28 +514,32 @@ * devices which are not physically connected (such as extra serial & * keyboard ports). This problem is not yet solved. */ -static void walk_native_bus(unsigned long addr, struct parisc_device *parent) +static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, + struct parisc_device *parent) { - int i; + int i, devices_found = 0; + unsigned long hpa = io_io_low; struct hardware_path path; get_node_path(parent, &path); - for (i = 0; i < MAX_NATIVE_DEVICES; i++) { - unsigned long hpa = (addr + i * NATIVE_DEVICE_OFFSET); - struct parisc_device *dev; - - /* Was the device already added by Firmware? */ - dev = find_device_by_addr(hpa); - if (!dev) { - path.mod = i; - dev = alloc_pa_dev(hpa, &path); - if (!dev) - continue; - - register_parisc_device(dev); + do { + for (i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) { + struct parisc_device *dev; + + /* Was the device already added by Firmware? */ + dev = find_device_by_addr(hpa); + if (!dev) { + path.mod = i; + dev = alloc_pa_dev(hpa, &path); + if (!dev) + continue; + + register_parisc_device(dev); + devices_found++; + } + walk_lower_bus(dev); } - walk_lower_bus(dev); - } + } while (!devices_found && hpa < io_io_high); } #define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000 @@ -530,7 +552,9 @@ */ void walk_central_bus(void) { - walk_native_bus(CENTRAL_BUS_ADDR, &root); + walk_native_bus(CENTRAL_BUS_ADDR, + CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET), + &root); } void fixup_child_irqs(struct parisc_device *parent, int base, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/entry.S linux.21pre4-ac6/arch/parisc/kernel/entry.S --- linux.21pre4/arch/parisc/kernel/entry.S 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/entry.S 2003-01-06 15:38:40.000000000 +0000 @@ -759,32 +759,30 @@ .import do_softirq,code intr_do_softirq: - bl do_softirq,%r2 #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ -#else - nop #endif - b intr_check_resched - nop + ldil L%intr_check_resched, %r2 + b do_softirq + ldo R%intr_check_resched(%r2), %r2 .import schedule,code intr_do_resched: /* Only do reschedule if we are returning to user space */ LDREG PT_IASQ0(%r16), %r20 - CMPIB= 0,%r20,intr_restore /* backward */ + CMPIB= 0,%r20,intr_check_sig /* backward */ nop LDREG PT_IASQ1(%r16), %r20 - CMPIB= 0,%r20,intr_restore /* backward */ + CMPIB= 0,%r20,intr_check_sig /* backward */ nop #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ #endif - ldil L%intr_return, %r2 + ldil L%intr_check_sig, %r2 b schedule - ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */ + ldo R%intr_check_sig(%r2), %r2 .import do_signal,code @@ -799,15 +797,14 @@ copy %r0, %r24 /* unsigned long in_syscall */ copy %r16, %r25 /* struct pt_regs *regs */ - ssm PSW_SM_I, %r0 + copy %r0, %r26 /* sigset_t *oldset = NULL */ #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ #endif - bl do_signal,%r2 - copy %r0, %r26 /* sigset_t *oldset = NULL */ + ldil L%intr_restore, %r2 + b do_signal + ldo R%intr_restore(%r2), %r2 - b intr_restore - nop /* * External interrupts. @@ -852,7 +849,7 @@ ldo -16(%r30),%r29 /* Reference param save area */ #endif b do_cpu_irq_mask - ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */ + ldo R%intr_return(%r2), %r2 @@ -925,19 +922,16 @@ loadgp copy %r29, %r25 /* arg1 is pt_regs */ -#ifdef CONFIG_KWDB - copy %r29, %r3 /* KWDB - update frame pointer (gr3) */ -#endif #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ #endif - ldil L%intr_return, %r2 + ldil L%intr_restore, %r2 copy %r25, %r16 /* save pt_regs */ b handle_interruption - ldo R%intr_return(%r2), %r2 /* return to intr_return */ + ldo R%intr_restore(%r2), %r2 /* @@ -1319,9 +1313,9 @@ /* Get rid of prot bits and convert to page addr for idtlbt */ - extrd,s pte,35,4,t0 + extrd,s pte,35,4,t1 depdi 0,63,12,pte /* clear lower 12 bits */ - addi,= 1,t0,0 + addi,= 1,t1,0 extrd,u,*tr pte,56,25,pte extrd,s pte,56,25,pte /* bit 31:8 >> 8 */ idtlbt pte,prot @@ -1389,9 +1383,9 @@ /* Get rid of prot bits and convert to page addr for idtlbt */ - extrd,s pte,35,4,t0 + extrd,s pte,35,4,t1 depdi 0,63,12,pte /* clear lower 12 bits */ - addi,= 1,t0,0 + addi,= 1,t1,0 extrd,u,*tr pte,56,25,pte extrd,s pte,56,25,pte /* bit 31:8 >> 8 */ idtlbt pte,prot @@ -1642,9 +1636,9 @@ /* Get rid of prot bits and convert to page addr for iitlbt */ - extrd,s pte,35,4,t0 + extrd,s pte,35,4,t1 depdi 0,63,12,pte /* clear lower 12 bits */ - addi,= 1,t0,0 + addi,= 1,t1,0 extrd,u,*tr pte,56,25,pte extrd,s pte,56,25,pte /* bit 31:8 >> 8 */ iitlbt pte,prot @@ -1860,9 +1854,9 @@ extrd,u,*= pte,_PAGE_GATEWAY_BIT+32,1,r0 depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */ - extrd,s pte,35,4,t0 + extrd,s pte,35,4,t1 depdi 0,63,12,pte /* clear lower 12 bits */ - addi,= 1,t0,0 + addi,= 1,t1,0 extrd,u,*tr pte,56,25,pte extrd,s pte,56,25,pte /* bit 31:8 >> 8 */ idtlbt pte,prot @@ -2358,9 +2352,9 @@ STREG %r2,TASK_PT_IAOQ0(%r1) ldo 4(%r2),%r2 STREG %r2,TASK_PT_IAOQ1(%r1) - copy %r25,%r16 + b intr_restore - nop + copy %r25,%r16 .import do_softirq,code syscall_do_softirq: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/firmware.c linux.21pre4-ac6/arch/parisc/kernel/firmware.c --- linux.21pre4/arch/parisc/kernel/firmware.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/firmware.c 2003-01-06 15:38:40.000000000 +0000 @@ -1,4 +1,4 @@ -/* arch/parisc/kernel/pdc.c - safe pdc access routines +/* arch/parisc/kernel/firmware.c - safe pdc access routines * * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org) * portions Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) @@ -177,6 +177,45 @@ } /** + * pdc_pat_chassis_send_log - Sends a PDC PAT CHASSIS log message. + * @retval: -1 on error, 0 on success. Other value are PDC errors + * + * Must be correctly formatted or expect system crash + */ +#ifdef __LP64__ +int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) +{ + if (!is_pdc_pat()) + return -1; + + int retval = 0; + + spin_lock_irq(&pdc_lock); + retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data)); + spin_unlock_irq(&pdc_lock); + + return retval; +} +#endif + +/** + * pdc_chassis_disp - Updates display + * @retval: -1 on error, 0 on success + * + * Works on old PDC only (E class, others?) + */ +int pdc_chassis_disp(unsigned long disp) +{ + int retval = 0; + + spin_lock_irq(&pdc_lock); + retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp); + spin_unlock_irq(&pdc_lock); + + return retval; +} + +/** * pdc_coproc_cfg - To identify coprocessors attached to the processor. * @pdc_coproc_info: Return buffer address. * @@ -507,12 +546,11 @@ /* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */ #define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \ - strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 9) == 0) + strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0) retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, __pa(pdc_result), __pa(hwpath)); - if (retval >= PDC_OK) { *scsi_id = (unsigned char) pdc_result[0]; @@ -534,10 +572,12 @@ ** pdc_result[3] PDC suggested SCSI rate */ + /* + ** XXX REVISIT: Doesn't look like PAT PDC does the same. + ** Problem is A500 also exports 50-pin SE SCSI port. + */ if (IS_SPROCKETS()) { /* - ** Revisit: PAT PDC do the same thing? - ** A500 also exports 50-pin SE SCSI. ** 0 == 8-bit ** 1 == 16-bit */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/head64.S linux.21pre4-ac6/arch/parisc/kernel/head64.S --- linux.21pre4/arch/parisc/kernel/head64.S 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/head64.S 2003-01-06 15:38:40.000000000 +0000 @@ -24,7 +24,7 @@ #include /* for PDC_PSW defines */ - .level 2.0 + .level 2.0w .section .initcall.init .align 4 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/ioctl32.c linux.21pre4-ac6/arch/parisc/kernel/ioctl32.c --- linux.21pre4/arch/parisc/kernel/ioctl32.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/ioctl32.c 2003-01-06 15:38:40.000000000 +0000 @@ -2986,6 +2986,9 @@ COMPATIBLE_IOCTL(BLKFRASET) COMPATIBLE_IOCTL(BLKSECTSET) COMPATIBLE_IOCTL(BLKSSZGET) +COMPATIBLE_IOCTL(BLKBSZGET) +COMPATIBLE_IOCTL(BLKBSZSET) +COMPATIBLE_IOCTL(BLKGETSIZE64) /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/irq.c linux.21pre4-ac6/arch/parisc/kernel/irq.c --- linux.21pre4/arch/parisc/kernel/irq.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/irq.c 2003-01-06 15:38:40.000000000 +0000 @@ -201,7 +201,7 @@ { #ifdef CONFIG_PROC_FS char *p = buf; - unsigned int regnr; + unsigned int regnr = 0; p += sprintf(p, " "); #ifdef CONFIG_SMP diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/lasimap.map linux.21pre4-ac6/arch/parisc/kernel/lasimap.map --- linux.21pre4/arch/parisc/kernel/lasimap.map 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/lasimap.map 1970-01-01 01:00:00.000000000 +0100 @@ -1,322 +0,0 @@ -# HP 712 kernel keymap. This uses 7 modifier combinations. - -keymaps 0-2,4-5,8,12 -# ie, plain, Shift, AltGr, Control, Control+Shift, Alt and Control+Alt - - -# Change the above line into -# keymaps 0-2,4-6,8,12 -# in case you want the entries -# altgr control keycode 83 = Boot -# altgr control keycode 111 = Boot -# below. -# -# In fact AltGr is used very little, and one more keymap can -# be saved by mapping AltGr to Alt (and adapting a few entries): -# keycode 100 = Alt -# -keycode 1 = F9 F19 Console_21 - control keycode 1 = F9 - alt keycode 1 = Console_9 - control alt keycode 1 = Console_9 -keycode 2 = -keycode 3 = F5 F15 Console_17 - control keycode 3 = F5 - alt keycode 3 = Console_5 - control alt keycode 3 = Console_5 -keycode 4 = F3 F13 Console_15 - control keycode 4 = F3 - alt keycode 4 = Console_3 - control alt keycode 4 = Console_3 -keycode 5 = F1 F11 Console_13 - control keycode 5 = F1 - alt keycode 5 = Console_1 - control alt keycode 5 = Console_1 -keycode 6 = F2 F12 Console_14 - control keycode 6 = F2 - alt keycode 6 = Console_2 - control alt keycode 6 = Console_2 -keycode 7 = F12 F12 Console_24 - control keycode 7 = F12 - alt keycode 7 = Console_12 - control alt keycode 7 = Console_12 -keycode 8 = -keycode 9 = F10 F20 Console_22 - control keycode 9 = F10 - alt keycode 9 = Console_10 - control alt keycode 9 = Console_10 -keycode 10 = F8 F18 Console_20 - control keycode 10 = F8 - alt keycode 10 = Console_8 - control alt keycode 10 = Console_8 -keycode 11 = F6 F16 Console_18 - control keycode 11 = F6 - alt keycode 11 = Console_6 - control alt keycode 11 = Console_6 -keycode 12 = F4 F14 Console_16 - control keycode 12 = F4 - alt keycode 12 = Console_4 - control alt keycode 12 = Console_4 -keycode 13 = Tab Tab - alt keycode 13 = Meta_Tab -keycode 14 = grave asciitilde - control keycode 14 = nul - alt keycode 14 = Meta_grave -keycode 15 = -keycode 16 = -keycode 17 = Alt -keycode 18 = Shift -keycode 19 = -keycode 20 = Control -keycode 21 = q -keycode 22 = one exclam exclam -keycode 23 = -keycode 24 = -keycode 25 = -keycode 26 = z -keycode 27 = s -keycode 28 = a - altgr keycode 28 = Hex_A -keycode 29 = w -keycode 30 = two at at -keycode 31 = -keycode 32 = -keycode 33 = c - altgr keycode 46 = Hex_C -keycode 34 = x -keycode 35 = d - altgr keycode 35 = Hex_D -keycode 36 = e - altgr keycode 36 = Hex_E -keycode 37 = four dollar -keycode 38 = three numbersign -keycode 39 = -keycode 40 = -keycode 41 = -keycode 42 = v -keycode 43 = f - altgr keycode 43 = Hex_F -keycode 44 = t -keycode 45 = r -keycode 46 = five percent -keycode 47 = -keycode 48 = -keycode 49 = n -keycode 50 = b - altgr keycode 50 = Hex_B -keycode 51 = h -keycode 52 = g -keycode 53 = y -keycode 54 = six asciicircum -keycode 55 = -keycode 56 = -keycode 57 = -keycode 58 = m -keycode 59 = j -keycode 60 = u -keycode 61 = seven ampersand -keycode 62 = eight asterisk asterisk -keycode 63 = -keycode 64 = -keycode 65 = comma less - alt keycode 65 = Meta_comma -keycode 66 = k -keycode 67 = i -keycode 68 = o -keycode 69 = zero parenright bracketright -keycode 70 = nine parenleft bracketleft -keycode 71 = -keycode 72 = -keycode 73 = period greater - control keycode 73 = Compose - alt keycode 73 = Meta_period -keycode 74 = slash question - control keycode 74 = Delete - alt keycode 53 = Meta_slash -keycode 75 = l -keycode 76 = semicolon colon - alt keycode 39 = Meta_semicolon -keycode 77 = p -keycode 78 = minus underscore -keycode 79 = -keycode 80 = -keycode 81 = -keycode 82 = apostrophe quotedbl - control keycode 82 = Control_g - alt keycode 40 = Meta_apostrophe -keycode 83 = -keycode 84 = bracketleft braceleft - control keycode 84 = Escape - alt keycode 26 = Meta_bracketleft -keycode 85 = equal plus -keycode 86 = -keycode 87 = -keycode 88 = Caps_Lock -keycode 88 = -keycode 89 = -keycode 89 = -keycode 89 = -keycode 90 = Return - alt keycode 90 = Meta_Control_m -keycode 91 = bracketright braceright asciitilde - control keycode 91 = Control_bracketright - alt keycode 91 = Meta_bracketright -keycode 92 = -keycode 93 = backslash bar - control keycode 43 = Control_backslash - alt keycode 43 = Meta_backslash -keycode 94 = -keycode 95 = -keycode 96 = -keycode 97 = -keycode 98 = -keycode 99 = -keycode 100 = -keycode 101 = -keycode 102 = BackSpace -keycode 103 = -keycode 104 = -keycode 105 = KP_1 - alt keycode 105 = Ascii_1 - altgr keycode 105 = Hex_1 -keycode 106 = -keycode 107 = KP_4 - alt keycode 107 = Ascii_4 - altgr keycode 107 = Hex_4 -keycode 108 = KP_7 - alt keycode 108 = Ascii_7 - altgr keycode 108 = Hex_7 -keycode 109 = -keycode 110 = -keycode 111 = -keycode 112 = KP_0 - alt keycode 82 = Ascii_0 - altgr keycode 82 = Hex_0 -keycode 113 = KP_Period -keycode 114 = KP_2 - alt keycode 114 = Ascii_2 - altgr keycode 114 = Hex_2 -keycode 115 = KP_5 - alt keycode 115 = Ascii_5 - altgr keycode 115 = Hex_5 -keycode 116 = KP_6 - alt keycode 116 = Ascii_6 - altgr keycode 116 = Hex_6 -keycode 117 = KP_8 - alt keycode 117 = Ascii_8 - altgr keycode 117 = Hex_8 -keycode 118 = Escape -keycode 119 = -keycode 120 = F11 -keycode 121 = KP_Add -keycode 122 = KP_3 - alt keycode 122 = Ascii_3 - altgr keycode 122 = Hex_3 -keycode 123 = KP_Subtract -keycode 124 = KP_Multiply -keycode 125 = KP_9 - alt keycode 125 = Ascii_9 - altgr keycode 125 = Hex_9 -keycode 126 = -# 131!! -keycode 127 = F7 F17 Console_19 - control keycode 127 = F7 - alt keycode 127 = Console_7 - control alt keycode 127 = Console_7 - -string F1 = "\033[[A" -string F2 = "\033[[B" -string F3 = "\033[[C" -string F4 = "\033[[D" -string F5 = "\033[[E" -string F6 = "\033[17~" -string F7 = "\033[18~" -string F8 = "\033[19~" -string F9 = "\033[20~" -string F10 = "\033[21~" -string F11 = "\033[23~" -string F12 = "\033[24~" -string F13 = "\033[25~" -string F14 = "\033[26~" -string F15 = "\033[28~" -string F16 = "\033[29~" -string F17 = "\033[31~" -string F18 = "\033[32~" -string F19 = "\033[33~" -string F20 = "\033[34~" -string Find = "\033[1~" -string Insert = "\033[2~" -string Remove = "\033[3~" -string Select = "\033[4~" -string Prior = "\033[5~" -string Next = "\033[6~" -string Macro = "\033[M" -string Pause = "\033[P" -compose '`' 'A' to 'À' -compose '`' 'a' to 'à' -compose '\'' 'A' to 'Á' -compose '\'' 'a' to 'á' -compose '^' 'A' to 'Â' -compose '^' 'a' to 'â' -compose '~' 'A' to 'Ã' -compose '~' 'a' to 'ã' -compose '"' 'A' to 'Ä' -compose '"' 'a' to 'ä' -compose 'O' 'A' to 'Å' -compose 'o' 'a' to 'å' -compose '0' 'A' to 'Å' -compose '0' 'a' to 'å' -compose 'A' 'A' to 'Å' -compose 'a' 'a' to 'å' -compose 'A' 'E' to 'Æ' -compose 'a' 'e' to 'æ' -compose ',' 'C' to 'Ç' -compose ',' 'c' to 'ç' -compose '`' 'E' to 'È' -compose '`' 'e' to 'è' -compose '\'' 'E' to 'É' -compose '\'' 'e' to 'é' -compose '^' 'E' to 'Ê' -compose '^' 'e' to 'ê' -compose '"' 'E' to 'Ë' -compose '"' 'e' to 'ë' -compose '`' 'I' to 'Ì' -compose '`' 'i' to 'ì' -compose '\'' 'I' to 'Í' -compose '\'' 'i' to 'í' -compose '^' 'I' to 'Î' -compose '^' 'i' to 'î' -compose '"' 'I' to 'Ï' -compose '"' 'i' to 'ï' -compose '-' 'D' to 'Ð' -compose '-' 'd' to 'ð' -compose '~' 'N' to 'Ñ' -compose '~' 'n' to 'ñ' -compose '`' 'O' to 'Ò' -compose '`' 'o' to 'ò' -compose '\'' 'O' to 'Ó' -compose '\'' 'o' to 'ó' -compose '^' 'O' to 'Ô' -compose '^' 'o' to 'ô' -compose '~' 'O' to 'Õ' -compose '~' 'o' to 'õ' -compose '"' 'O' to 'Ö' -compose '"' 'o' to 'ö' -compose '/' 'O' to 'Ø' -compose '/' 'o' to 'ø' -compose '`' 'U' to 'Ù' -compose '`' 'u' to 'ù' -compose '\'' 'U' to 'Ú' -compose '\'' 'u' to 'ú' -compose '^' 'U' to 'Û' -compose '^' 'u' to 'û' -compose '"' 'U' to 'Ü' -compose '"' 'u' to 'ü' -compose '\'' 'Y' to 'Ý' -compose '\'' 'y' to 'ý' -compose 'T' 'H' to 'Þ' -compose 't' 'h' to 'þ' -compose 's' 's' to 'ß' -compose '"' 'y' to 'ÿ' -compose 's' 'z' to 'ß' -compose 'i' 'j' to 'ÿ' diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/lba_pci.c linux.21pre4-ac6/arch/parisc/kernel/lba_pci.c --- linux.21pre4/arch/parisc/kernel/lba_pci.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/lba_pci.c 2003-01-06 15:38:40.000000000 +0000 @@ -735,47 +735,11 @@ bus->resource[0] = &(ldev->hba.io_space); bus->resource[1] = &(ldev->hba.lmmio_space); } else { - /* KLUGE ALERT! - ** PCI-PCI Bridge resource munging. - ** This hack should go away in the near future. - ** It's based on the Alpha port. - */ - int i; - u16 cmd; - - for (i = 0; i < 4; i++) { - bus->resource[i] = - &bus->self->resource[PCI_BRIDGE_RESOURCES+i]; - bus->resource[i]->name = bus->name; - } -#if 0 - bus->resource[0]->flags |= pci_bridge_check_io(bus->self); -#else - bus->resource[0]->flags |= IORESOURCE_IO; -#endif - bus->resource[1]->flags |= IORESOURCE_MEM; - bus->resource[2]->flags = 0; /* Don't support prefetchable */ - bus->resource[3]->flags = 0; /* not used */ - - /* - ** If the PPB is enabled (ie already configured) then - ** just read those values. - */ - (void) lba_cfg_read16(bus->self, PCI_COMMAND, &cmd); - if (cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) { - pci_read_bridge_bases(bus); - } else { - /* Not configured. - ** For now, propogate HBA limits to the bus; - ** PCI will adjust them later. - */ - bus->resource[0]->end = ldev->hba.io_space.end; - bus->resource[1]->end = ldev->hba.lmmio_space.end; - } + pci_read_bridge_bases(bus); - /* Turn off downstream PF memory address range by default */ - bus->resource[2]->start = 1024*1024; - bus->resource[2]->end = bus->resource[2]->start - 1; + /* Turn off downstream PreFetchable Memory range by default */ + bus->resource[2]->start = 0; + bus->resource[2]->end = 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/led.c linux.21pre4-ac6/arch/parisc/kernel/led.c --- linux.21pre4/arch/parisc/kernel/led.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/led.c 2003-01-06 15:38:40.000000000 +0000 @@ -352,7 +352,8 @@ static unsigned long led_net_rx_counter, led_net_tx_counter; static void led_get_net_stats(int addvalue) -{ +{ +#ifdef CONFIG_NET static unsigned long rx_total_last, tx_total_last; unsigned long rx_total, tx_total; struct net_device *dev; @@ -383,6 +384,7 @@ rx_total_last += rx_total; tx_total_last += tx_total; +#endif } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/Makefile linux.21pre4-ac6/arch/parisc/kernel/Makefile --- linux.21pre4/arch/parisc/kernel/Makefile 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/Makefile 2003-01-06 15:38:40.000000000 +0000 @@ -24,7 +24,7 @@ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o semaphore.o \ signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ - processor.o power.o + processor.o power.o pdc_chassis.o export-objs := parisc_ksyms.o superio.o keyboard.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/parisc_ksyms.c linux.21pre4-ac6/arch/parisc/kernel/parisc_ksyms.c --- linux.21pre4/arch/parisc/kernel/parisc_ksyms.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/parisc_ksyms.c 2003-01-06 15:38:40.000000000 +0000 @@ -232,3 +232,11 @@ EXPORT_SYMBOL_NOVERS($$dyncall); #endif +#ifdef CONFIG_SMP +#ifdef CONFIG_DEBUG_SPINLOCK +#include +EXPORT_SYMBOL(spin_lock); +EXPORT_SYMBOL(spin_unlock); +EXPORT_SYMBOL(spin_trylock); +#endif +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/pci.c linux.21pre4-ac6/arch/parisc/kernel/pci.c --- linux.21pre4/arch/parisc/kernel/pci.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/pci.c 2003-01-06 15:38:40.000000000 +0000 @@ -306,13 +306,13 @@ (32) for primary and secondary buses. */ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32); - /* Read bridge control */ + /* Read bridge control - force SERR/PERR on */ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bus->bridge_ctl); + bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bus->bridge_ctl); } - /* Set FBB bit for now. Disable ISA IO forwarding. Enable PERR/SERR */ - bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK | - PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; + bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; } @@ -390,7 +390,7 @@ */ void __devinit pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long alignment) + unsigned long size, unsigned long alignment) { unsigned long mask, align; @@ -407,7 +407,7 @@ align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; /* Align to largest of MIN or input size */ - mask = MAX(size, align) - 1; + mask = MAX(alignment, align) - 1; res->start += mask; res->start &= ~mask; @@ -420,7 +420,7 @@ int __devinit -pcibios_enable_device(struct pci_dev *dev) +pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd; int idx; @@ -438,6 +438,11 @@ */ for (idx=0; idxresource[idx]; + + /* only setup requested resources */ + if (!(mask & (1<flags & IORESOURCE_IO) cmd |= PCI_COMMAND_IO; if (r->flags & IORESOURCE_MEM) @@ -454,9 +459,11 @@ */ cmd |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY); +#if 0 /* If bridge/bus controller has FBB enabled, child must too. */ if (dev->bus->bridge_ctl & PCI_BRIDGE_CTL_FAST_BACK) cmd |= PCI_COMMAND_FAST_BACK; +#endif DBGC("PCIBIOS: Enabling device %s cmd 0x%04x\n", dev->slot_name, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); @@ -478,6 +485,19 @@ #endif } +static void __devinit +pcibios_enable_ppb(struct pci_bus *bus) +{ + struct list_head *list; + + /* find a leaf of the PCI bus tree. */ + list_for_each(list, &bus->children) + pcibios_enable_ppb(pci_bus_b(list)); + + if (bus->self && (bus->self->class >> 8) == PCI_CLASS_BRIDGE_PCI) + pdev_enable_device(bus->self); +} + /* ** Mostly copied from drivers/pci/setup-bus.c:pci_assign_unassigned_resources() @@ -486,16 +506,13 @@ pcibios_assign_unassigned_resources(struct pci_bus *bus) { /* from drivers/pci/setup-bus.c */ - extern void pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges); + extern void pbus_size_bridges(struct pci_bus *bus); + extern void pbus_assign_resources(struct pci_bus *bus); - struct pbus_set_ranges_data ranges; + pbus_size_bridges(bus); + pbus_assign_resources(bus); - ranges.io_end = ranges.io_start - = bus->resource[0]->start + PCIBIOS_MIN_IO; - ranges.mem_end = ranges.mem_start - = bus->resource[1]->start + PCIBIOS_MIN_MEM; - ranges.found_vga = 0; - pbus_assign_resources(bus, &ranges); + pcibios_enable_ppb(bus); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/pdc_chassis.c linux.21pre4-ac6/arch/parisc/kernel/pdc_chassis.c --- linux.21pre4/arch/parisc/kernel/pdc_chassis.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/parisc/kernel/pdc_chassis.c 2003-01-06 15:38:40.000000000 +0000 @@ -0,0 +1,205 @@ +/* + * arch/parisc/kernel/pdc_chassis.c + * + * Copyright (C) 2002 Laurent Canet + * Copyright (C) 2002 Thibaut Varene + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#undef PDC_CHASSIS_DEBUG +#ifdef PDC_CHASSIS_DEBUG +#define DPRINTK(fmt, args...) printk(fmt, ## args) +#else +#define DPRINTK(fmt, args...) +#endif + +#include +#include +#include +#include + +#include +#include + +static int pdc_chassis_old = 0; + + +/** + * pdc_chassis_checkold() - Checks for old PDC_CHASSIS compatibility + * @pdc_chassis_old: 1 if old pdc chassis style + * + * Currently, only E class and A180 are known to work with this. + * Inspired by Christoph Plattner + */ + +static void __init pdc_chassis_checkold(void) +{ + switch(CPU_HVERSION) { + case 0x480: /* E25 */ + case 0x481: /* E35 */ + case 0x482: /* E45 */ + case 0x483: /* E55 */ + case 0x516: /* A180 */ + pdc_chassis_old = 1; + break; + + default: + break; + } + DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); +} + + +/** + * pdc_chassis_panic_event() - Called by the panic handler. + * + * As soon as a panic occurs, we should inform the PDC. + */ + +static int pdc_chassis_panic_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); + return NOTIFY_DONE; +} + + +static struct notifier_block pdc_chassis_panic_block = { + notifier_call: pdc_chassis_panic_event, + priority: INT_MAX, +}; + + +/** + * parisc_reboot_event() - Called by the reboot handler. + * + * As soon as a reboot occurs, we should inform the PDC. + */ + +static int pdc_chassis_reboot_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN); + return NOTIFY_DONE; +} + + +static struct notifier_block pdc_chassis_reboot_block = { + notifier_call: pdc_chassis_reboot_event, + priority: INT_MAX, +}; + + +/** + * parisc_pdc_chassis_init() - Called at boot time. + */ + +void __init parisc_pdc_chassis_init(void) +{ + DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); + + /* initialize panic notifier chain */ + notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block); + + /* initialize reboot notifier chain */ + register_reboot_notifier(&pdc_chassis_reboot_block); + + /* Check for old LED Panel */ + pdc_chassis_checkold(); +} + + +/** + * pdc_chassis_send_status() - Sends a predefined message to the chassis, + * and changes the front panel LEDs according to the new system state + * @retval: PDC call return value. + * + * Only machines with 64 bits PDC PAT and E-class are supported atm. + * + * returns 0 if no error, -1 if no supported PDC is present or invalid message, + * else returns the appropriate PDC error code. + * + * For a list of predefined messages, see asm-parisc/pdc_chassis.h + */ + +int pdc_chassis_send_status(int message) +{ + /* Maybe we should do that in an other way ? */ + int retval = 0; + + DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message); + +#ifdef __LP64__ /* pdc_pat_chassis_send_log is defined only when #ifdef __LP64__ */ + if (is_pdc_pat()) { + switch(message) { + case PDC_CHASSIS_DIRECT_BSTART: + retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BSTART, PDC_CHASSIS_LSTATE_RUN_NORMAL); + break; + + case PDC_CHASSIS_DIRECT_BCOMPLETE: + retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BCOMPLETE, PDC_CHASSIS_LSTATE_RUN_NORMAL); + break; + + case PDC_CHASSIS_DIRECT_SHUTDOWN: + retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_SHUTDOWN, PDC_CHASSIS_LSTATE_NONOS); + break; + + case PDC_CHASSIS_DIRECT_PANIC: + retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_PANIC, PDC_CHASSIS_LSTATE_RUN_CRASHREC); + break; + + case PDC_CHASSIS_DIRECT_LPMC: + retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_LPMC, PDC_CHASSIS_LSTATE_RUN_SYSINT); + break; + + case PDC_CHASSIS_DIRECT_HPMC: + retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_HPMC, PDC_CHASSIS_LSTATE_RUN_NCRIT); + break; + + default: + retval = -1; + } + } else retval = -1; +#else + if (pdc_chassis_old) { + switch (message) { + case PDC_CHASSIS_DIRECT_BSTART: + case PDC_CHASSIS_DIRECT_BCOMPLETE: + retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); + break; + + case PDC_CHASSIS_DIRECT_SHUTDOWN: + retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_SHUT)); + break; + + case PDC_CHASSIS_DIRECT_HPMC: + case PDC_CHASSIS_DIRECT_PANIC: + retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_FLT)); + break; + + case PDC_CHASSIS_DIRECT_LPMC: + retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_WARN)); + break; + + default: + retval = -1; + } + } else retval = -1; +#endif + + return retval; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/pdc_cons.c linux.21pre4-ac6/arch/parisc/kernel/pdc_cons.c --- linux.21pre4/arch/parisc/kernel/pdc_cons.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/pdc_cons.c 2003-01-06 15:38:40.000000000 +0000 @@ -51,33 +51,33 @@ return 0; } -#ifdef CONFIG_PDC_CONSOLE +#if defined(CONFIG_PDC_CONSOLE) || defined(CONFIG_SERIAL_MUX) +#define PDC_CONSOLE_DEVICE pdc_console_device static kdev_t pdc_console_device (struct console *c) { - return MKDEV(PDCCONS_MAJOR, 0); + return MKDEV(MUX_MAJOR, 0); } -#endif - -#ifdef CONFIG_PDC_CONSOLE -#define PDC_CONSOLE_DEVICE pdc_console_device -#else +#else #define PDC_CONSOLE_DEVICE NULL #endif static struct console pdc_cons = { name: "ttyB", write: pdc_console_write, - device: PDC_CONSOLE_DEVICE, +#warning UPSTREAM 2.4.19 removed the next 4 lines but we did not + read: NULL, + device: PDC_CONSOLE_DEVICE, + unblank: NULL, setup: pdc_console_setup, flags: CON_BOOT|CON_PRINTBUFFER|CON_ENABLED, index: -1, }; static int pdc_console_initialized; - extern unsigned long con_start; /* kernel/printk.c */ extern unsigned long log_end; /* kernel/printk.c */ - + + static void pdc_console_init_force(void) { if (pdc_console_initialized) @@ -94,7 +94,7 @@ void pdc_console_init(void) { -#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE) +#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE) || defined(CONFIG_SERIAL_MUX) pdc_console_init_force(); #endif #ifdef EARLY_BOOTUP_DEBUG diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/power.c linux.21pre4-ac6/arch/parisc/kernel/power.c --- linux.21pre4/arch/parisc/kernel/power.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/power.c 2003-01-06 15:38:40.000000000 +0000 @@ -44,15 +44,12 @@ #include #include #include -#include -#include #include #include #include #include #include -#include #include @@ -144,11 +141,7 @@ DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0); /* soft power switch enabled/disabled */ -#ifdef CONFIG_PROC_FS -static int pwrsw_enabled = 1; -#else -#define pwrsw_enabled (1) -#endif +int pwrsw_enabled = 1; /* * On gecko style machines (e.g. 712/xx and 715/xx) @@ -209,90 +202,6 @@ -/* - * /proc filesystem support - */ - -#ifdef CONFIG_SYSCTL -static int power_proc_read(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - char *out = page; - int len; - - out += sprintf(out, "Software power switch support: "); - out += sprintf(out, pwrsw_enabled ? "enabled (1)" : "disabled (0)" ); - out += sprintf(out, "\n"); - - len = out - page - off; - if (len < count) { - *eof = 1; - if (len <= 0) return 0; - } else { - len = count; - } - *start = page + off; - return len; -} - -static int power_proc_write(struct file *file, const char *buf, - unsigned long count, void *data) -{ - char *cur, lbuf[count]; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - memset(lbuf, 0, count); - - copy_from_user(lbuf, buf, count); - cur = lbuf; - - /* skip initial spaces */ - while (*cur && isspace(*cur)) - cur++; - - switch (*cur) { - case '0': pwrsw_enabled = 0; - break; - case '1': pwrsw_enabled = 1; - break; - default: printk(KERN_CRIT "/proc/" SYSCTL_FILENAME - ": Parse error: only '0' or '1' allowed!\n"); - return -EINVAL; - } /* switch() */ - - return count; -} - -static struct proc_dir_entry *ent; - -static void __init power_create_procfs(void) -{ - if (!power_tasklet.func) - return; - - ent = create_proc_entry(SYSCTL_FILENAME, S_IFREG|S_IRUGO|S_IWUSR, 0); - if (!ent) return; - - ent->nlink = 1; - ent->read_proc = power_proc_read; - ent->write_proc = power_proc_write; - ent->owner = THIS_MODULE; -} - -static void __exit power_remove_procfs(void) -{ - remove_proc_entry(SYSCTL_FILENAME, NULL); -} - -#else -#define power_create_procfs() do { } while (0) -#define power_remove_procfs() do { } while (0) -#endif /* CONFIG_SYSCTL */ - - - /* parisc_panic_event() is called by the panic handler. * As soon as a panic occurs, our tasklets above will not be * executed any longer. This function then re-enables the @@ -346,7 +255,6 @@ /* Register a call for panic conditions. */ notifier_chain_register(&panic_notifier_list, &parisc_panic_block); - power_create_procfs(); tasklet_enable(&power_tasklet); return 0; @@ -359,7 +267,6 @@ tasklet_disable(&power_tasklet); notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block); - power_remove_procfs(); power_tasklet.func = NULL; pdc_soft_power_button(0); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/process.c linux.21pre4-ac6/arch/parisc/kernel/process.c --- linux.21pre4/arch/parisc/kernel/process.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/process.c 2003-01-06 15:38:40.000000000 +0000 @@ -36,6 +36,7 @@ #include #include #include +#include int hlt_counter; @@ -118,6 +119,9 @@ /* "Normal" system reset */ pdc_do_reset(); + /* set up a new led state on systems shipped with a LED State panel */ + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN); + /* Nope...box should reset with just CMD_RESET now */ gsc_writel(CMD_RESET, COMMAND_GLOBAL); @@ -150,6 +154,8 @@ * following call will immediately power off. */ pdc_soft_power_button(0); + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN); + /* It seems we have no way to power the system off via * software. The user has to press the button himself. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/processor.c linux.21pre4-ac6/arch/parisc/kernel/processor.c --- linux.21pre4/arch/parisc/kernel/processor.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/processor.c 2003-01-06 15:38:40.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: processor.c,v 1.13 2002/07/04 19:33:01 grundler Exp $ +/* $Id: processor.c,v 1.14 2002/09/13 06:46:28 grundler Exp $ * * Initial setup-routines for HP 9000 based hardware. * @@ -77,6 +77,8 @@ unsigned long txn_addr; unsigned long cpuid; struct cpuinfo_parisc *p; + extern struct irq_region_ops cpu_irq_ops; /* arch/parisc...irq.c */ + extern struct irqaction cpu_irq_actions[]; /* arch/parisc...irq.c */ #ifndef CONFIG_SMP if (boot_cpu_data.cpu_count > 0) { @@ -167,12 +169,24 @@ ** p->state = STATE_RENDEZVOUS; */ - /* - ** itimer and ipi IRQ handlers are statically initialized in - ** arch/parisc/kernel/irq.c. ie Don't need to register them. - */ - p->region = irq_region[IRQ_FROM_REGION(CPU_IRQ_REGION)]; +#if 0 + /* CPU 0 IRQ table is statically allocated/initialized */ + if (cpuid) { + struct irqaction actions[]; + + /* + ** itimer and ipi IRQ handlers are statically initialized in + ** arch/parisc/kernel/irq.c. ie Don't need to register them. + */ + actions = kmalloc(sizeof(struct irqaction)*MAX_CPU_IRQ, GFP_ATOMIC); + if (!actions) { + /* not getting it's own table, share with monarch */ + actions = cpu_irq_actions[0]; + } + cpu_irq_actions[cpuid] = actions; + } +#endif return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/sba_iommu.c linux.21pre4-ac6/arch/parisc/kernel/sba_iommu.c --- linux.21pre4/arch/parisc/kernel/sba_iommu.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/sba_iommu.c 2003-01-06 15:38:40.000000000 +0000 @@ -812,10 +812,8 @@ return(0); } - dev->dma_mask = mask; /* save it */ - /* only support 32-bit PCI devices - no DAC support (yet) */ - return((int) (mask == 0xffffffff)); + return((int) (mask == 0xffffffffUL)); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/setup.c linux.21pre4-ac6/arch/parisc/kernel/setup.c --- linux.21pre4/arch/parisc/kernel/setup.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/setup.c 2003-01-06 15:38:40.000000000 +0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include /* for pa7300lc_init() proto */ #define COMMAND_LINE_SIZE 1024 @@ -283,6 +284,11 @@ parisc_init_resources(); do_device_inventory(); /* probe for hardware */ + parisc_pdc_chassis_init(); + + /* set up a new led state on systems shipped LED State panel */ + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); + processor_init(); printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", boot_cpu_data.cpu_count, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/syscall.S linux.21pre4-ac6/arch/parisc/kernel/syscall.S --- linux.21pre4/arch/parisc/kernel/syscall.S 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/syscall.S 2003-01-06 15:38:40.000000000 +0000 @@ -593,11 +593,18 @@ ENTRY_DIFF(ftruncate64) /* 200 */ ENTRY_SAME(getdents64) ENTRY_DIFF(fcntl64) - ENTRY_SAME(ni_syscall) /* attrctl */ - ENTRY_SAME(ni_syscall) /* acl_get */ - ENTRY_SAME(ni_syscall) /* acl_set */ - ENTRY_SAME(gettid) +#ifdef CONFIG_XFS_FS + ENTRY_SAME(attrctl) + ENTRY_SAME(acl_get) + ENTRY_SAME(acl_set) /* 205 */ +#else + ENTRY_SAME(ni_syscall) + ENTRY_SAME(ni_syscall) + ENTRY_SAME(ni_syscall) /* 205 */ +#endif + ENTRY_SAME(gettid) ENTRY_SAME(readahead) + ENTRY_SAME(tkill) .end diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/sys_parisc32.c linux.21pre4-ac6/arch/parisc/kernel/sys_parisc32.c --- linux.21pre4/arch/parisc/kernel/sys_parisc32.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/sys_parisc32.c 2003-01-06 15:38:40.000000000 +0000 @@ -2759,20 +2759,9 @@ asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) { - switch (cmd) { - case F_GETLK64: - cmd = F_GETLK; - break; - case F_SETLK64: - cmd = F_SETLK; - break; - case F_SETLKW64: - cmd = F_SETLKW; - break; - default: - break; - } - return sys_fcntl(fd, cmd, arg); + if (cmd >= F_GETLK64 && cmd <= F_SETLKW64) + return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg); + return sys32_fcntl(fd, cmd, arg); } asmlinkage int sys32_pread(int fd, void *buf, size_t count, unsigned int high, unsigned int low) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/traps.c linux.21pre4-ac6/arch/parisc/kernel/traps.c --- linux.21pre4/arch/parisc/kernel/traps.c 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/traps.c 2003-01-06 15:38:40.000000000 +0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -34,17 +35,10 @@ #include #include #include +#include #include "../math-emu/math-emu.h" /* for handle_fpe() */ -#ifdef CONFIG_KWDB -#include /* for BI2_KGDB_GDB */ -#include /* for __() */ -#include /* for struct save_state */ -#include /* for pt_regs_to_ssp and ssp_to_pt_regs */ -#include /* for I_BRK_INST */ -#endif /* CONFIG_KWDB */ - #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */ /* dumped to the console via printk) */ @@ -66,6 +60,99 @@ #define RFMT "%08lx" #endif +static int kstack_depth_to_print = 24; +extern struct module *module_list; +extern struct module kernel_module; + +static inline int kernel_text_address(unsigned long addr) +{ +#ifdef CONFIG_MODULES + int retval = 0; + struct module *mod; +#endif + extern char _stext, _etext; + + if (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext) + return 1; + +#ifdef CONFIG_MODULES + for (mod = module_list; mod != &kernel_module; mod = mod->next) { + /* mod_bound tests for addr being inside the vmalloc'ed + * module area. Of course it'd be better to test only + * for the .text subset... */ + if (mod_bound(addr, 0, mod)) { + retval = 1; + break; + } + } + return retval; +#endif +} + + +void show_trace(unsigned long * stack) +{ + unsigned long *startstack; + unsigned long addr; + int i; + + startstack = (unsigned long *)((unsigned long)stack & ~(THREAD_SIZE - 1)); + i = 1; + printk("Kernel addresses on the stack:\n"); + while (stack >= startstack) { + addr = *stack--; + if (kernel_text_address(addr)) { + printk(" [<" RFMT ">] ", addr); + if ((i & 0x03) == 0) + printk("\n"); + i++; + } + } + printk("\n"); +} + +void show_trace_task(struct task_struct *tsk) +{ + show_trace((unsigned long *)tsk->thread.regs.ksp); +} + +void show_stack(unsigned long * sp) +{ + unsigned long *stack; + int i; + + /* + * debugging aid: "show_stack(NULL);" prints the + * back trace for this cpu. + */ + if (sp==NULL) + sp = (unsigned long*)&sp; + + stack = sp; + printk("\n" KERN_CRIT "Stack Dump:\n"); + printk(KERN_CRIT " " RFMT ": ", (unsigned long) stack); + for (i=0; i < kstack_depth_to_print; i++) { + if (((long) stack & (THREAD_SIZE-1)) == 0) + break; + if (i && ((i & 0x03) == 0)) + printk("\n" KERN_CRIT " " RFMT ": ", + (unsigned long) stack); + printk(RFMT " ", *stack--); + } + printk("\n" KERN_CRIT "\n"); + show_trace(sp); +} + +/* + * The architecture-independent backtrace generator + */ +void dump_stack(void) +{ + show_stack(0); +} + + void show_regs(struct pt_regs *regs) { int i; @@ -121,84 +208,6 @@ } -static void dump_stack(unsigned long from, unsigned long to, int istackflag) -{ - unsigned int *fromptr; - unsigned int *toptr; - - fromptr = (unsigned int *)from; - toptr = (unsigned int *)to; - - printk("\n"); - printk(KERN_CRIT "Dumping %sStack from 0x%p to 0x%p:\n", - istackflag ? "Interrupt " : "", - fromptr, toptr); - - while (fromptr < toptr) { - printk(KERN_CRIT "%04lx %08x %08x %08x %08x %08x %08x %08x %08x\n", - ((unsigned long)fromptr) & 0xffff, - fromptr[0], fromptr[1], fromptr[2], fromptr[3], - fromptr[4], fromptr[5], fromptr[6], fromptr[7]); - fromptr += 8; - } -} - - -void show_stack(struct pt_regs *regs) -{ -#if 1 - /* If regs->sr[7] == 0, we are on a kernel stack */ - if (regs->sr[7] == 0) { - - unsigned long sp = regs->gr[30]; - unsigned long cr30; - unsigned long cr31; - unsigned long stack_start; - struct pt_regs *int_regs; - - cr30 = mfctl(30); - cr31 = mfctl(31); - stack_start = sp & ~(ISTACK_SIZE - 1); - if (stack_start == cr31) { - /* - * We are on the interrupt stack, get the stack - * pointer from the first pt_regs structure on - * the interrupt stack, so we can dump the task - * stack first. - */ - - int_regs = (struct pt_regs *)cr31; - sp = int_regs->gr[30]; - stack_start = sp & ~(INIT_TASK_SIZE - 1); - if (stack_start != cr30) { - printk(KERN_CRIT "WARNING! Interrupt-Stack pointer and cr30 do not correspond!\n"); - printk(KERN_CRIT "Dumping virtual address stack instead\n"); - dump_stack((unsigned long)__va(stack_start), (unsigned long)__va(sp), 0); - } else { - dump_stack(stack_start, sp, 0); - }; - - printk("\n\n" KERN_DEBUG "Registers at Interrupt:\n"); - show_regs(int_regs); - - /* Now dump the interrupt stack */ - - sp = regs->gr[30]; - stack_start = sp & ~(ISTACK_SIZE - 1); - dump_stack(stack_start,sp,1); - } - else - { - /* Stack Dump! */ - printk(KERN_CRIT "WARNING! Stack pointer and cr30 do not correspond!\n"); - printk(KERN_CRIT "Dumping virtual address stack instead\n"); - dump_stack((unsigned long)__va(stack_start), (unsigned long)__va(sp), 0); - } - } -#endif -} - - void die_if_kernel(char *str, struct pt_regs *regs, long err) { if (user_mode(regs)) { @@ -260,9 +269,6 @@ void handle_break(unsigned iir, struct pt_regs *regs) { struct siginfo si; -#ifdef CONFIG_KWDB - struct save_state ssp; -#endif /* CONFIG_KWDB */ switch(iir) { case 0x00: @@ -285,26 +291,6 @@ handle_gdb_break(regs, TRAP_BRKPT); break; -#ifdef CONFIG_KWDB - case KGDB_BREAK_INSN: - mtctl(0, 15); - pt_regs_to_ssp(regs, &ssp); - kgdb_trap(I_BRK_INST, &ssp, 1); - ssp_to_pt_regs(&ssp, regs); - break; - - case KGDB_INIT_BREAK_INSN: - mtctl(0, 15); - pt_regs_to_ssp(regs, &ssp); - kgdb_trap(I_BRK_INST, &ssp, 1); - ssp_to_pt_regs(&ssp, regs); - - /* Advance pcoq to skip break */ - regs->iaoq[0] = regs->iaoq[1]; - regs->iaoq[1] += 4; - break; -#endif /* CONFIG_KWDB */ - default: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n", @@ -335,20 +321,6 @@ void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap; -#ifdef CONFIG_KWDB -int debug_call (void) -{ - printk (KERN_DEBUG "Debug call.\n"); - return 0; -} - -int debug_call_leaf (void) -{ - return 0; -} -#endif /* CONFIG_KWDB */ - - void transfer_pim_to_trap_frame(struct pt_regs *regs) { register int i; @@ -425,7 +397,7 @@ /* - * This routine handles page faults. It determines the address, + * This routine handles various exception codes. It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. */ @@ -444,10 +416,20 @@ if (!console_drivers) pdc_console_restart(); - if (code == 1) - transfer_pim_to_trap_frame(regs); - show_stack(regs); + /* Not all switch paths will gutter the processor... */ + switch(code){ + + case 1: + transfer_pim_to_trap_frame(regs); + break; + + default: + /* Fall through */ + break; + } + + show_stack((unsigned long *)regs->gr[30]); printk("\n"); printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n", @@ -461,32 +443,34 @@ * system will shut down immediately right here. */ pdc_soft_power_button(0); + /* Gutter the processor... */ for(;;) ; } + void handle_interruption(int code, struct pt_regs *regs) { unsigned long fault_address = 0; unsigned long fault_space = 0; struct siginfo si; -#ifdef CONFIG_KWDB - struct save_state ssp; -#endif /* CONFIG_KWDB */ - - if (code == 1) - pdc_console_restart(); /* switch back to pdc if HPMC */ - else - sti(); -#if 0 - printk(KERN_CRIT "Interruption # %d\n", code); -#endif + /* HACK! jsm is going to fix this. + * entry.S will manage I-bit - only enable I-bit if it was + * enabled before we took the "trap". + */ + if (code != 1) + local_irq_enable(); switch(code) { case 1: /* High-priority machine check (HPMC) */ + pdc_console_restart(); /* switch back to pdc if HPMC */ + + /* set up a new led state on systems shipped with a LED State panel */ + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC); + parisc_terminate("High Priority Machine Check (HPMC)", regs, code, 0); /* NOT REACHED */ @@ -506,6 +490,9 @@ case 5: /* Low-priority machine check */ + + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC); + flush_all_caches(); cpu_lpmc(5, regs); return; @@ -554,6 +541,7 @@ die_if_kernel("Privileged register usage", regs, code); si.si_code = ILL_PRVREG; + /* Fall thru */ give_sigill: si.si_signo = SIGILL; si.si_errno = 0; @@ -561,17 +549,47 @@ force_sig_info(SIGILL, &si, current); return; + case 12: + /* Overflow Trap, let the userland signal handler do the cleanup */ + si.si_signo = SIGFPE; + si.si_code = FPE_INTOVF; + si.si_addr = (void *) regs->iaoq[0]; + force_sig_info(SIGFPE, &si, current); + return; + + case 13: + /* Conditional Trap + The condition succees in an instruction which traps on condition */ + si.si_signo = SIGFPE; + /* Set to zero, and let the userspace app figure it out from + the insn pointed to by si_addr */ + si.si_code = 0; + si.si_addr = (void *) regs->iaoq[0]; + force_sig_info(SIGFPE, &si, current); + return; + case 14: /* Assist Exception Trap, i.e. floating point exception. */ die_if_kernel("Floating point exception", regs, 0); /* quiet */ handle_fpe(regs); return; + case 15: + /* Data TLB miss fault/Data page fault */ + /* Fall thru */ + case 16: + /* Non-access instruction TLB miss fault */ + /* The instruction TLB entry needed for the target address of the FIC + is absent, and hardware can't find it, so we get to cleanup */ + /* Fall thru */ case 17: /* Non-access data TLB miss fault/Non-access data page fault */ /* TODO: Still need to add slow path emulation code here */ + /* TODO: Understand what is meant by the TODO listed + above this one. (Carlos) */ fault_address = regs->ior; - parisc_terminate("Non access data tlb fault!",regs,code,fault_address); + fault_space = regs->isr; + break; case 18: /* PCXS only -- later cpu's split this into types 26,27 & 28 */ @@ -581,9 +599,8 @@ return; } /* Fall Through */ - - case 15: /* Data TLB miss fault/Data page fault */ - case 26: /* PCXL: Data memory access rights trap */ + case 26: + /* PCXL: Data memory access rights trap */ fault_address = regs->ior; fault_space = regs->isr; break; @@ -599,7 +616,6 @@ case 25: /* Taken branch trap */ -#ifndef CONFIG_KWDB regs->gr[0] &= ~PSW_T; if (regs->iasq[0]) handle_gdb_break(regs, TRAP_BRANCH); @@ -607,14 +623,6 @@ * run. */ return; -#else - /* Kernel debugger: */ - mtctl(0, 15); - pt_regs_to_ssp(regs, &ssp); - kgdb_trap(I_TAKEN_BR, &ssp, 1); - ssp_to_pt_regs(&ssp, regs); - break; -#endif /* CONFIG_KWDB */ case 7: /* Instruction access rights */ @@ -648,7 +656,6 @@ up_read(¤t->mm->mmap_sem); } /* Fall Through */ - case 27: /* Data memory protection ID trap */ die_if_kernel("Protection id trap", regs, code); @@ -682,6 +689,9 @@ force_sig_info(SIGBUS, &si, current); return; } + + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); + parisc_terminate("Unexpected interruption", regs, code, 0); /* NOT REACHED */ } @@ -710,24 +720,17 @@ * The kernel should never fault on its own address space. */ - if (fault_space == 0) - parisc_terminate("Kernel Fault", regs, code, fault_address); + if (fault_space == 0) { + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); + parisc_terminate("Kernel Fault", regs, code, fault_address); + /** NOT REACHED **/ + } } -#ifdef CONFIG_KWDB - debug_call_leaf (); -#endif /* CONFIG_KWDB */ - do_page_fault(regs, code, fault_address); } -void show_trace_task(struct task_struct *tsk) -{ - BUG(); -} - - int __init check_ivt(void *iva) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/kernel/unaligned.c linux.21pre4-ac6/arch/parisc/kernel/unaligned.c --- linux.21pre4/arch/parisc/kernel/unaligned.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/kernel/unaligned.c 2003-01-06 15:38:40.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.9 2001/10/04 03:31:08 tausq Exp $ +/* $Id: unaligned.c,v 1.10 2002/09/22 02:21:05 tausq Exp $ * * Unaligned memory access handler * @@ -108,7 +108,7 @@ #define OPCODE_STW_L OPCODE4(0x1A) #define OPCODE_STW_L2 OPCODE4(0x1B) - +int unaligned_enabled = 1; void die_if_kernel (char *str, struct pt_regs *regs, long err); @@ -281,6 +281,9 @@ } } + if (!unaligned_enabled) + goto force_sigbus; + /* TODO: make this cleaner... */ switch (regs->iir & OPCODE1_MASK) { @@ -368,7 +371,7 @@ { printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret); die_if_kernel("Unaligned data reference", regs, 28); - +force_sigbus: /* couldn't handle it ... */ si.si_signo = SIGBUS; si.si_errno = 0; @@ -432,3 +435,4 @@ return (int)(regs->ior & align_mask); } + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/lib/locks.c linux.21pre4-ac6/arch/parisc/lib/locks.c --- linux.21pre4/arch/parisc/lib/locks.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/parisc/lib/locks.c 2003-01-06 15:38:40.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * debugging spinlocks for parisc + * + * Adapted from the ppc version + */ + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_DEBUG_SPINLOCK + +#undef INIT_STUCK +#define INIT_STUCK 200000000 /*0xffffffff*/ + +#define __spin_trylock(x) (__ldcw(&(x)->lock) != 0) + +void spin_lock(spinlock_t *lock) +{ + int cpu = smp_processor_id(); + unsigned int stuck = INIT_STUCK; + while (!__spin_trylock(lock)) { + while ((unsigned volatile long)lock->lock == 0) { + if (!--stuck) { + printk("spin_lock(%p) CPU#%d NIP %p" + " holder: cpu %ld pc %08lX\n", + lock, cpu, __builtin_return_address(0), + lock->owner_cpu,lock->owner_pc); + stuck = INIT_STUCK; + /* steal the lock */ + /*xchg_u32((void *)&lock->lock,0);*/ + } + } + } + lock->owner_pc = (unsigned long)__builtin_return_address(0); + lock->owner_cpu = cpu; +} + +int spin_trylock(spinlock_t *lock) +{ + if (!__spin_trylock(lock)) + return 0; + lock->owner_cpu = smp_processor_id(); + lock->owner_pc = (unsigned long)__builtin_return_address(0); + return 1; +} + +void spin_unlock(spinlock_t *lp) +{ + if ( lp->lock ) + printk("spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n", + lp, smp_processor_id(), __builtin_return_address(0), + current->comm, current->pid); + if ( lp->owner_cpu != smp_processor_id() ) + printk("spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %x\n", + lp, smp_processor_id(), (int)lp->owner_cpu, + lp->owner_pc,lp->lock); + lp->owner_pc = lp->owner_cpu = 0; + wmb(); + lp->lock = 1; +} + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/lib/Makefile linux.21pre4-ac6/arch/parisc/lib/Makefile --- linux.21pre4/arch/parisc/lib/Makefile 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/lib/Makefile 2003-01-06 15:38:40.000000000 +0000 @@ -6,4 +6,6 @@ L_TARGET = lib.a obj-y := lusercopy.o bitops.o checksum.o io.o memset.o +obj-$(CONFIG_SMP) += locks.o + include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/Makefile linux.21pre4-ac6/arch/parisc/Makefile --- linux.21pre4/arch/parisc/Makefile 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/Makefile 2003-01-06 15:38:40.000000000 +0000 @@ -91,14 +91,6 @@ SUBDIRS := $(SUBDIRS) arch/parisc/math-emu DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.o -ifdef CONFIG_KWDB -SUBDIRS := $(SUBDIRS) arch/parisc/kdb -DRIVERS := $(DRIVERS) arch/parisc/kdb/kdb.o - -arch/parisc/kdb: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/parisc/kdb -endif - arch/parisc/kernel: dummy $(MAKE) linuxsubdirs SUBDIRS=arch/parisc/kernel @@ -106,6 +98,21 @@ $(MAKE) linuxsubdirs SUBDIRS=arch/parisc/mm palo: vmlinux + @if [ $$(palo -f /dev/null >/dev/null 2>&1 ; echo $$?) != 2 ]; then \ + echo 'ERROR: Please install palo first (apt-get install palo)';\ + echo 'or build it from source and install it somewhere in your $$PATH';\ + false; \ + fi + @if [ ! -f ./palo.conf ]; then \ + cp arch/parisc/defpalo.conf palo.conf; \ + echo 'A generic palo config file (./palo.conf) has been created for you.'; \ + echo 'You should check it and re-run "make palo".'; \ + echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \ + false; \ + fi + palo -f ./palo.conf + +oldpalo: vmlinux export TOPDIR=`pwd`; \ unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/mm/fault.c linux.21pre4-ac6/arch/parisc/mm/fault.c --- linux.21pre4/arch/parisc/mm/fault.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/mm/fault.c 2003-01-06 15:38:40.000000000 +0000 @@ -257,7 +257,8 @@ } parisc_terminate("Bad Address (null pointer deref?)", regs, code, address); - + /* NOT REACHED! */ + out_of_memory: up_read(&mm->mmap_sem); printk(KERN_CRIT "VM: killing process %s\n", current->comm); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/mm/init.c linux.21pre4-ac6/arch/parisc/mm/init.c --- linux.21pre4/arch/parisc/mm/init.c 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/mm/init.c 2003-01-06 15:38:40.000000000 +0000 @@ -21,6 +21,7 @@ #include #include +#include mmu_gather_t mmu_gathers[NR_CPUS]; @@ -409,6 +410,9 @@ } printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10); + + /* set up a new led state on systems shipped LED State panel */ + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); } /* @@ -574,13 +578,8 @@ for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++,pg_table++) { pte_t pte; -#if !defined(CONFIG_KWDB) && !defined(CONFIG_STI_CONSOLE) +#if !defined(CONFIG_STI_CONSOLE) #warning STI console should explicitly allocate executable pages but does not -/* KWDB needs to write kernel text when setting break points. -** -** The right thing to do seems like KWDB modify only the pte which -** has a break point on it...otherwise we might mask worse bugs. -*/ /* * Map the fault vector writable so we can * write the HPMC checksum. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/vmlinux64.lds linux.21pre4-ac6/arch/parisc/vmlinux64.lds --- linux.21pre4/arch/parisc/vmlinux64.lds 2003-01-29 16:27:20.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/vmlinux64.lds 2003-01-06 15:38:40.000000000 +0000 @@ -15,12 +15,12 @@ *(.gnu.warning) } = 0 + _etext = .; /* End of text section */ + . = ALIGN(16); .rodata : { *(.rodata) } .kstrtab : { *(.kstrtab) } - _etext = .; /* End of text section */ - .data BLOCK(8192) : { /* Data without special */ data_start = .; *(.data) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/parisc/vmlinux.lds linux.21pre4-ac6/arch/parisc/vmlinux.lds --- linux.21pre4/arch/parisc/vmlinux.lds 2003-01-29 16:27:19.000000000 +0000 +++ linux.21pre4-ac6/arch/parisc/vmlinux.lds 2003-01-06 15:38:40.000000000 +0000 @@ -14,12 +14,12 @@ *(.gnu.warning) } = 0 + _etext = .; /* End of text section */ + . = ALIGN(16); .rodata : { *(.rodata) *(.rodata.*) } .kstrtab : { *(.kstrtab) } - _etext = .; /* End of text section */ - .data BLOCK(8192) : { /* Data without special */ data_start = .; *(.data) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/config.in linux.21pre4-ac6/arch/ppc/config.in --- linux.21pre4/arch/ppc/config.in 2003-01-29 16:27:11.000000000 +0000 +++ linux.21pre4-ac6/arch/ppc/config.in 2003-02-04 14:58:59.000000000 +0000 @@ -184,12 +184,9 @@ source drivers/parport/Config.in -if [ "$CONFIG_4xx" != "y" ]; then - if [ "$CONFIG_APUS" != "y" ]; then - tristate 'Support for /dev/rtc' CONFIG_PPC_RTC - else - bool 'Generic /dev/rtc emulation' CONFIG_GEN_RTC - fi +tristate 'Generic /dev/rtc emulation' CONFIG_GEN_RTC +if [ "$CONFIG_GEN_RTC" = "n" -a "$CONFIG_APUS" != "y" ]; then + tristate 'Support for /dev/rtc' CONFIG_PPC_RTC fi if [ "$CONFIG_ALL_PPC" = "y" -a "$CONFIG_POWER3" = "n" ] ; then diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/kernel/entry.S linux.21pre4-ac6/arch/ppc/kernel/entry.S --- linux.21pre4/arch/ppc/kernel/entry.S 2003-01-29 16:27:10.000000000 +0000 +++ linux.21pre4-ac6/arch/ppc/kernel/entry.S 2003-01-06 19:13:14.000000000 +0000 @@ -264,7 +264,9 @@ .globl ret_from_fork ret_from_fork: +#ifdef CONFIG_SMP bl schedule_tail +#endif lwz r0,TASK_PTRACE(r2) andi. r0,r0,PT_TRACESYS bnel- syscall_trace diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/kernel/idle.c linux.21pre4-ac6/arch/ppc/kernel/idle.c --- linux.21pre4/arch/ppc/kernel/idle.c 2003-01-29 16:27:10.000000000 +0000 +++ linux.21pre4-ac6/arch/ppc/kernel/idle.c 2003-01-06 19:13:14.000000000 +0000 @@ -51,9 +51,6 @@ do_power_save = 1; /* endless loop with no priority at all */ - current->nice = 20; - current->counter = -100; - init_idle(); for (;;) { #ifdef CONFIG_SMP if (!do_power_save) { @@ -73,11 +70,8 @@ if (do_power_save && !current->need_resched) power_save_6xx(); #endif /* CONFIG_6xx */ - - if (current->need_resched) { - schedule(); - check_pgt_cache(); - } + schedule(); + check_pgt_cache(); } return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/kernel/mk_defs.c linux.21pre4-ac6/arch/ppc/kernel/mk_defs.c --- linux.21pre4/arch/ppc/kernel/mk_defs.c 2003-01-29 16:27:10.000000000 +0000 +++ linux.21pre4-ac6/arch/ppc/kernel/mk_defs.c 2003-01-06 19:13:14.000000000 +0000 @@ -37,8 +37,7 @@ /*DEFINE(KERNELBASE, KERNELBASE);*/ DEFINE(STATE, offsetof(struct task_struct, state)); DEFINE(NEXT_TASK, offsetof(struct task_struct, next_task)); - DEFINE(COUNTER, offsetof(struct task_struct, counter)); - DEFINE(PROCESSOR, offsetof(struct task_struct, processor)); + DEFINE(PROCESSOR, offsetof(struct task_struct, cpu)); DEFINE(SIGPENDING, offsetof(struct task_struct, sigpending)); DEFINE(THREAD, offsetof(struct task_struct, thread)); DEFINE(MM, offsetof(struct task_struct, mm)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/kernel/ppc_defs.h linux.21pre4-ac6/arch/ppc/kernel/ppc_defs.h --- linux.21pre4/arch/ppc/kernel/ppc_defs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/arch/ppc/kernel/ppc_defs.h 2003-01-06 19:13:14.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * WARNING! This file is automatically generated - DO NOT EDIT! + */ +#define STATE 0 +#define NEXT_TASK 76 +#define PROCESSOR 32 +#define SIGPENDING 8 +#define THREAD 608 +#define MM 84 +#define ACTIVE_MM 88 +#define TASK_STRUCT_SIZE 1520 +#define KSP 0 +#define PGDIR 16 +#define LAST_SYSCALL 20 +#define PT_REGS 8 +#define PT_TRACESYS 2 +#define TASK_FLAGS 4 +#define TASK_PTRACE 24 +#define NEED_RESCHED 20 +#define THREAD_FPR0 24 +#define THREAD_FPSCR 284 +#define THREAD_VR0 288 +#define THREAD_VRSAVE 816 +#define THREAD_VSCR 800 +#define TASK_UNION_SIZE 8192 +#define STACK_FRAME_OVERHEAD 16 +#define INT_FRAME_SIZE 192 +#define GPR0 16 +#define GPR1 20 +#define GPR2 24 +#define GPR3 28 +#define GPR4 32 +#define GPR5 36 +#define GPR6 40 +#define GPR7 44 +#define GPR8 48 +#define GPR9 52 +#define GPR10 56 +#define GPR11 60 +#define GPR12 64 +#define GPR13 68 +#define GPR14 72 +#define GPR15 76 +#define GPR16 80 +#define GPR17 84 +#define GPR18 88 +#define GPR19 92 +#define GPR20 96 +#define GPR21 100 +#define GPR22 104 +#define GPR23 108 +#define GPR24 112 +#define GPR25 116 +#define GPR26 120 +#define GPR27 124 +#define GPR28 128 +#define GPR29 132 +#define GPR30 136 +#define GPR31 140 +#define _NIP 144 +#define _MSR 148 +#define _CTR 156 +#define _LINK 160 +#define _CCR 168 +#define _MQ 172 +#define _XER 164 +#define _DAR 180 +#define _DSISR 184 +#define _DEAR 180 +#define _ESR 184 +#define ORIG_GPR3 152 +#define RESULT 188 +#define TRAP 176 +#define CLONE_VM 256 +#define MM_PGD 12 +#define CPU_SPEC_ENTRY_SIZE 32 +#define CPU_SPEC_PVR_MASK 0 +#define CPU_SPEC_PVR_VALUE 4 +#define CPU_SPEC_FEATURES 12 +#define CPU_SPEC_SETUP 28 +#define NUM_USER_SEGMENTS 8 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/kernel/smp.c linux.21pre4-ac6/arch/ppc/kernel/smp.c --- linux.21pre4/arch/ppc/kernel/smp.c 2003-01-29 16:27:10.000000000 +0000 +++ linux.21pre4-ac6/arch/ppc/kernel/smp.c 2003-01-06 19:13:14.000000000 +0000 @@ -294,8 +294,6 @@ cpu_callin_map[0] = 1; current->processor = 0; - init_idle(); - for (i = 0; i < NR_CPUS; i++) { prof_counter[i] = 1; prof_multiplier[i] = 1; @@ -348,7 +346,8 @@ p = init_task.prev_task; if (!p) panic("No idle task for CPU %d", i); - del_from_runqueue(p); + init_idle(p, i); + unhash_process(p); init_tasks[i] = p; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/ppc/mm/fault.c linux.21pre4-ac6/arch/ppc/mm/fault.c --- linux.21pre4/arch/ppc/mm/fault.c 2003-01-29 16:27:10.000000000 +0000 +++ linux.21pre4-ac6/arch/ppc/mm/fault.c 2003-01-06 19:13:14.000000000 +0000 @@ -109,8 +109,6 @@ goto bad_area; if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (expand_stack(vma, address)) goto bad_area; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/s390/kernel/entry.S linux.21pre4-ac6/arch/s390/kernel/entry.S --- linux.21pre4/arch/s390/kernel/entry.S 2003-01-29 16:27:16.000000000 +0000 +++ linux.21pre4-ac6/arch/s390/kernel/entry.S 2003-01-06 19:13:14.000000000 +0000 @@ -254,13 +254,14 @@ ret_from_fork: basr %r13,0 l %r13,.Lentry_base-.(%r13) # setup base pointer to &entry_base + # not saving R14 here because we go to sysc_return ultimately + l %r1,BASED(.Lschedtail) + basr %r14,%r1 # call schedule_tail (unlock stuff) GET_CURRENT # load pointer to task_struct to R9 stosm 24(%r15),0x03 # reenable interrupts sr %r0,%r0 # child returns 0 st %r0,SP_R2(%r15) # store return value (change R2 on stack) - l %r1,BASED(.Lschedtail) - la %r14,BASED(sysc_return) - br %r1 # call schedule_tail, return to sysc_return + b BASED(sysc_return) # # clone, fork, vfork, exec and sigreturn need glue, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/s390x/kernel/entry.S linux.21pre4-ac6/arch/s390x/kernel/entry.S --- linux.21pre4/arch/s390x/kernel/entry.S 2003-01-29 16:27:20.000000000 +0000 +++ linux.21pre4-ac6/arch/s390x/kernel/entry.S 2003-01-06 19:13:14.000000000 +0000 @@ -240,11 +240,11 @@ # .globl ret_from_fork ret_from_fork: + brasl %r14,schedule_tail GET_CURRENT # load pointer to task_struct to R9 stosm 48(%r15),0x03 # reenable interrupts xc SP_R2(8,%r15),SP_R2(%r15) # child returns 0 - larl %r14,sysc_return - jg schedule_tail # return to sysc_return + j sysc_return # # clone, fork, vfork, exec and sigreturn need glue, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/s390x/kernel/linux32.c linux.21pre4-ac6/arch/s390x/kernel/linux32.c --- linux.21pre4/arch/s390x/kernel/linux32.c 2003-01-29 16:27:20.000000000 +0000 +++ linux.21pre4-ac6/arch/s390x/kernel/linux32.c 2003-01-06 23:19:40.000000000 +0000 @@ -912,64 +912,97 @@ return sys32_fcntl(fd, cmd, arg); } -struct dqblk32 { - __u32 dqb_bhardlimit; - __u32 dqb_bsoftlimit; - __u32 dqb_curblocks; - __u32 dqb_ihardlimit; - __u32 dqb_isoftlimit; - __u32 dqb_curinodes; - __kernel_time_t32 dqb_btime; - __kernel_time_t32 dqb_itime; -}; - extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); -asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) +#ifdef CONFIG_QIFACE_COMPAT +#ifdef CONFIG_QIFACE_V1 +struct user_dqblk32 { + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u32 dqb_curblocks; + __u32 dqb_ihardlimit; + __u32 dqb_isoftlimit; + __u32 dqb_curinodes; + __kernel_time_t32 dqb_btime; + __kernel_time_t32 dqb_itime; +}; +typedef struct v1c_mem_dqblk comp_dqblk_t; + +#define Q_COMP_GETQUOTA Q_V1_GETQUOTA +#define Q_COMP_SETQUOTA Q_V1_SETQUOTA +#define Q_COMP_SETQLIM Q_V1_SETQLIM +#define Q_COMP_SETUSE Q_V1_SETUSE +#else +struct user_dqblk32 { + __u32 dqb_ihardlimit; + __u32 dqb_isoftlimit; + __u32 dqb_curinodes; + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u64 dqb_curspace; + __kernel_time_t32 dqb_btime; + __kernel_time_t32 dqb_itime; +}; +typedef struct v2c_mem_dqblk comp_dqblk_t; + +#define Q_COMP_GETQUOTA Q_V2_GETQUOTA +#define Q_COMP_SETQUOTA Q_V2_SETQUOTA +#define Q_COMP_SETQLIM Q_V2_SETQLIM +#define Q_COMP_SETUSE Q_V2_SETUSE +#endif + +asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) { int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + comp_dqblk_t d; mm_segment_t old_fs; char *spec; switch (cmds) { - case Q_GETQUOTA: - break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) - return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; - break; + case Q_COMP_GETQUOTA: + break; + case Q_COMP_SETQUOTA: + case Q_COMP_SETUSE: + case Q_COMP_SETQLIM: + if (copy_from_user(&d, (struct user_dqblk32 *)addr, + sizeof (struct user_dqblk32))) + return -EFAULT; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; + break; default: - return sys_quotactl(cmd, special, - id, (caddr_t)addr); + return sys_quotactl(cmd, special, id, (__kernel_caddr_t)addr); } spec = getname (special); err = PTR_ERR(spec); if (IS_ERR(spec)) return err; - old_fs = get_fs (); + old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); + err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d); set_fs (old_fs); putname (spec); if (err) return err; - if (cmds == Q_GETQUOTA) { + if (cmds == Q_COMP_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct dqblk32 *)&d)->dqb_itime = i; - ((struct dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user ((struct dqblk32 *)addr, &d, - sizeof (struct dqblk32))) + ((struct user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user ((struct user_dqblk32 *)addr, &d, + sizeof (struct user_dqblk32))) return -EFAULT; } return 0; } +#else +/* No conversion needed for new interface */ +asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) +{ + return sys_quotactl(cmd, special, id, addr); +} +#endif + static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) { int err; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sh/mm/fault.c linux.21pre4-ac6/arch/sh/mm/fault.c --- linux.21pre4/arch/sh/mm/fault.c 2003-01-29 16:27:15.000000000 +0000 +++ linux.21pre4-ac6/arch/sh/mm/fault.c 2003-01-06 19:13:27.000000000 +0000 @@ -72,8 +72,6 @@ return 1; check_stack: - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (expand_stack(vma, start) == 0) goto good_area; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sparc/kernel/sunos_ioctl.c linux.21pre4-ac6/arch/sparc/kernel/sunos_ioctl.c --- linux.21pre4/arch/sparc/kernel/sunos_ioctl.c 2003-01-29 16:27:06.000000000 +0000 +++ linux.21pre4-ac6/arch/sparc/kernel/sunos_ioctl.c 2003-01-06 18:20:22.000000000 +0000 @@ -39,8 +39,12 @@ { int ret = -EBADF; - if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) + read_lock(¤t->files->file_lock); + if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) { + read_unlock(¤t->files->file_lock); goto out; + } + read_unlock(¤t->files->file_lock); /* First handle an easy compat. case for tty ldisc. */ if(cmd == TIOCSETD) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sparc/mm/fault.c linux.21pre4-ac6/arch/sparc/mm/fault.c --- linux.21pre4/arch/sparc/mm/fault.c 2003-01-29 16:27:06.000000000 +0000 +++ linux.21pre4-ac6/arch/sparc/mm/fault.c 2003-01-06 19:13:27.000000000 +0000 @@ -249,8 +249,6 @@ goto bad_area; if(vma->vm_start <= address) goto good_area; - if(!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if(expand_stack(vma, address)) goto bad_area; /* @@ -496,8 +494,6 @@ goto bad_area; if(vma->vm_start <= address) goto good_area; - if(!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if(expand_stack(vma, address)) goto bad_area; good_area: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sparc64/kernel/sunos_ioctl32.c linux.21pre4-ac6/arch/sparc64/kernel/sunos_ioctl32.c --- linux.21pre4/arch/sparc64/kernel/sunos_ioctl32.c 2003-01-29 16:27:14.000000000 +0000 +++ linux.21pre4-ac6/arch/sparc64/kernel/sunos_ioctl32.c 2003-01-06 18:20:34.000000000 +0000 @@ -100,8 +100,12 @@ if(fd >= SUNOS_NR_OPEN) goto out; - if(!fcheck(fd)) + read_lock(¤t->files->file_lock); + if(!fcheck(fd)) { + read_unlock(¤t->files->file_lock); goto out; + } + read_unlock(¤t->files->file_lock); if(cmd == TIOCSETD) { mm_segment_t old_fs = get_fs(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sparc64/kernel/sys_sparc32.c linux.21pre4-ac6/arch/sparc64/kernel/sys_sparc32.c --- linux.21pre4/arch/sparc64/kernel/sys_sparc32.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/arch/sparc64/kernel/sys_sparc32.c 2003-01-29 17:13:26.000000000 +0000 @@ -889,62 +889,97 @@ return sys32_fcntl(fd, cmd, arg); } -struct dqblk32 { - __u32 dqb_bhardlimit; - __u32 dqb_bsoftlimit; - __u32 dqb_curblocks; - __u32 dqb_ihardlimit; - __u32 dqb_isoftlimit; - __u32 dqb_curinodes; - __kernel_time_t32 dqb_btime; - __kernel_time_t32 dqb_itime; -}; - extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); -asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) +#ifdef CONFIG_QIFACE_COMPAT +#ifdef CONFIG_QIFACE_V1 +struct user_dqblk32 { + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u32 dqb_curblocks; + __u32 dqb_ihardlimit; + __u32 dqb_isoftlimit; + __u32 dqb_curinodes; + __kernel_time_t32 dqb_btime; + __kernel_time_t32 dqb_itime; +}; +typedef struct v1c_mem_dqblk comp_dqblk_t; + +#define Q_COMP_GETQUOTA Q_V1_GETQUOTA +#define Q_COMP_SETQUOTA Q_V1_SETQUOTA +#define Q_COMP_SETQLIM Q_V1_SETQLIM +#define Q_COMP_SETUSE Q_V1_SETUSE +#else +struct user_dqblk32 { + __u32 dqb_ihardlimit; + __u32 dqb_isoftlimit; + __u32 dqb_curinodes; + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u64 dqb_curspace; + __kernel_time_t32 dqb_btime; + __kernel_time_t32 dqb_itime; +}; +typedef struct v2c_mem_dqblk comp_dqblk_t; + +#define Q_COMP_GETQUOTA Q_V2_GETQUOTA +#define Q_COMP_SETQUOTA Q_V2_SETQUOTA +#define Q_COMP_SETQLIM Q_V2_SETQLIM +#define Q_COMP_SETUSE Q_V2_SETUSE +#endif + +asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) { int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + comp_dqblk_t d; mm_segment_t old_fs; char *spec; switch (cmds) { - case Q_GETQUOTA: - break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) - return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; - break; + case Q_COMP_GETQUOTA: + break; + case Q_COMP_SETQUOTA: + case Q_COMP_SETUSE: + case Q_COMP_SETQLIM: + if (copy_from_user(&d, (struct user_dqblk32 *)addr, + sizeof (struct user_dqblk32))) + return -EFAULT; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; + break; default: - return sys_quotactl(cmd, special, - id, (caddr_t)addr); + return sys_quotactl(cmd, special, id, (__kernel_caddr_t)addr); } spec = getname (special); err = PTR_ERR(spec); if (IS_ERR(spec)) return err; - old_fs = get_fs (); + old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); + err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d); set_fs (old_fs); putname (spec); - if (cmds == Q_GETQUOTA) { + if (err) + return err; + if (cmds == Q_COMP_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct dqblk32 *)&d)->dqb_itime = i; - ((struct dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user ((struct dqblk32 *)addr, &d, - sizeof (struct dqblk32))) + ((struct user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user ((struct user_dqblk32 *)addr, &d, + sizeof (struct user_dqblk32))) return -EFAULT; } - return err; + return 0; } +#else +/* No conversion needed for new interface */ +asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) +{ + return sys_quotactl(cmd, special, id, addr); +} +#endif + static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) { int err; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sparc64/mm/fault.c linux.21pre4-ac6/arch/sparc64/mm/fault.c --- linux.21pre4/arch/sparc64/mm/fault.c 2003-01-29 16:27:14.000000000 +0000 +++ linux.21pre4-ac6/arch/sparc64/mm/fault.c 2003-01-06 19:13:39.000000000 +0000 @@ -373,8 +373,6 @@ if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; if (!(fault_code & FAULT_CODE_WRITE)) { /* Non-faulting loads shouldn't expand stack. */ insn = get_fault_insn(regs, insn); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/sparc64/solaris/timod.c linux.21pre4-ac6/arch/sparc64/solaris/timod.c --- linux.21pre4/arch/sparc64/solaris/timod.c 2003-01-29 16:27:14.000000000 +0000 +++ linux.21pre4-ac6/arch/sparc64/solaris/timod.c 2003-01-06 18:20:56.000000000 +0000 @@ -149,7 +149,9 @@ struct socket *sock; SOLD("wakeing socket"); + read_lock(¤t->files->file_lock); sock = ¤t->files->fd[fd]->f_dentry->d_inode->u.socket_i; + read_unlock(¤t->files->file_lock); wake_up_interruptible(&sock->wait); read_lock(&sock->sk->callback_lock); if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) @@ -163,7 +165,9 @@ struct sol_socket_struct *sock; SOLD("queuing primsg"); + read_lock(¤t->files->file_lock); sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data; + read_unlock(¤t->files->file_lock); it->next = sock->pfirst; sock->pfirst = it; if (!sock->plast) @@ -177,7 +181,9 @@ struct sol_socket_struct *sock; SOLD("queuing primsg at end"); + read_lock(¤t->files->file_lock); sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data; + read_unlock(¤t->files->file_lock); it->next = NULL; if (sock->plast) sock->plast->next = it; @@ -355,7 +361,11 @@ (int (*)(int, unsigned long *))SYS(socketcall); int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int) = (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int))SYS(sendto); - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); + if (!filp) + return -EBADF; ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLD("entry"); @@ -636,7 +646,11 @@ SOLD("entry"); SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p)); - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); + if (!filp) + return -EBADF; ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); @@ -847,7 +861,9 @@ lock_kernel(); if(fd >= NR_OPEN) goto out; - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); if(!filp) goto out; ino = filp->f_dentry->d_inode; @@ -914,7 +930,9 @@ lock_kernel(); if(fd >= NR_OPEN) goto out; - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); if(!filp) goto out; ino = filp->f_dentry->d_inode; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/arch/x86_64/boot/bootsect.S linux.21pre4-ac6/arch/x86_64/boot/bootsect.S --- linux.21pre4/arch/x86_64/boot/bootsect.S 2003-01-29 16:27:20.000000000 +0000 +++ linux.21pre4-ac6/arch/x86_64/boot/bootsect.S 2003-01-30 16:50:05.000000000 +0000 @@ -395,9 +395,15 @@ # NOTE: Doesn't save %ax or %dx; do it yourself if you need to. kill_motor: +#if 1 + xorw %ax, %ax # reset FDC + xorb %dl, %dl + int $0x13 +#else movw $0x3f2, %dx xorb %al, %al outb %al, %dx +#endif ret sectors: .word 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/CREDITS linux.21pre4-ac6/CREDITS --- linux.21pre4/CREDITS 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/CREDITS 2003-01-30 16:55:15.000000000 +0000 @@ -2218,11 +2218,12 @@ S: United Kingdom N: Ian S. Nelson -E: ian.nelson@echostar.com +E: nelsonis@earthlink.net D: Minor mmap and ide hacks S: 1370 Atlantis Ave. S: Lafayette CO, 80026 S: USA +P: 1024D/DD478240 4073 9AF8 027F 278D CBBB DA3C 9905 0415 DD47 8240 N: Russell Nelson E: nelson@crynwr.com @@ -2405,13 +2406,10 @@ D: CDROM driver "sonycd535" (Sony CDU-535/531) N: Stelian Pop -E: stelian.pop@fr.alcove.com +E: stelian@popies.net P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 D: sonypi, meye drivers, mct_u232 usb serial hacks -S: Alcôve -S: 153, bd. Anatole France -S: 93200 Saint Denis -S: France +S: Paris, France N: Frederic Potter E: fpotter@cirpack.com @@ -2549,6 +2547,12 @@ S: 7000 Stuttgart 50 S: Germany +N: Andrew Rodland +E: arodland@linuxguru.net +D: That crazy morse code thing. +P: D2B1 5215 B1B9 18E0 B6AD 6ADD 4373 165F 1770 BD5C +S: Pennsylvania, USA + N: Christoph Rohland E: hans-christoph.rohland@sap.com E: ch.rohland@gmx.net diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/00-INDEX linux.21pre4-ac6/Documentation/00-INDEX --- linux.21pre4/Documentation/00-INDEX 2003-01-29 16:27:24.000000000 +0000 +++ linux.21pre4-ac6/Documentation/00-INDEX 2003-01-06 16:20:24.000000000 +0000 @@ -52,6 +52,8 @@ - directory with information on the CD-ROM drivers that Linux has. computone.txt - info on Computone Intelliport II/Plus Multiport Serial Driver +cpufreq + - describes the CPU frequency and voltage scaling support cpqarray.txt - info on using Compaq's SMART2 Intelligent Disk Array Controllers. devices.txt diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/Configure.help linux.21pre4-ac6/Documentation/Configure.help --- linux.21pre4/Documentation/Configure.help 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/Documentation/Configure.help 2003-02-21 15:46:06.000000000 +0000 @@ -464,8 +464,14 @@ The initial RAM disk is a RAM disk that is loaded by the boot loader (loadlin or lilo) and that is mounted as root before the normal boot procedure. It is typically used to load modules needed to mount the - "real" root file system, etc. See - for details. + "real" root file system, etc. + + Due to a problem elsewhere in the kernel, initial RAM disks _must_ + have the file system on them created with a 1024 byte block size. + If any other value is used, the kernel will be unable to mount the + RAM disk at boot time, causing a kernel panic. + + See for details. Loopback device support CONFIG_BLK_DEV_LOOP @@ -1041,7 +1047,7 @@ Pacific Digital A-DMA support (EXPERIMENTAL) CONFIG_BLK_DEV_PDC_ADMA - Please read the comments at the top of . + Please read the comments at the top of . 3ware Hardware ATA-RAID support CONFIG_BLK_DEV_3W_XXXX_RAID @@ -1071,13 +1077,13 @@ The ATP860 is an UltraDMA 66 chipset base. The ATP860M(acintosh) version is an UltraDMA 66 chipset base. - Please read the comments at the top of . + Please read the comments at the top of . If you say Y here, then say Y to "Use DMA by default when available" as well. AEC62XX Tuning support CONFIG_AEC62XX_TUNING - Please read the comments at the top of . + Please read the comments at the top of . If unsure, say N. ALI M15x3 chipset support @@ -1088,7 +1094,7 @@ If you say Y here, you also need to say Y to "Use DMA by default when available", above. Please read the comments at the top of - . + . If unsure, say N. @@ -1112,7 +1118,7 @@ If you say Y here, you also need to say Y to "Use DMA by default when available", above. - Please read the comments at the top of . + Please read the comments at the top of . If unsure, say N. @@ -1156,16 +1162,18 @@ HPT34X AUTODMA support (WIP) CONFIG_HPT34X_AUTODMA This is a dangerous thing to attempt currently! Please read the - comments at the top of . If you say Y + comments at the top of . If you say Y here, then say Y to "Use DMA by default when available" as well. If unsure, say N. -HPT366/368/370 chipset support +HPT36X/37X chipset support CONFIG_BLK_DEV_HPT366 HPT366 is an Ultra DMA chipset for ATA-66. HPT368 is an Ultra DMA chipset for ATA-66 RAID Based. HPT370 is an Ultra DMA chipset for ATA-100. + HPT372 is an Ultra DMA chipset for ATA-133. + HPT374 is an Ultra DMA chipset for ATA-133. This driver adds up to 4 more EIDE devices sharing a single interrupt. @@ -1187,12 +1195,12 @@ This driver adds detection and support for the NS87415 chip (used in SPARC64, among others). - Please read the comments at the top of . + Please read the comments at the top of . OPTi 82C621 chipset enhanced support (EXPERIMENTAL) CONFIG_BLK_DEV_OPTI621 This is a driver for the OPTi 82C621 EIDE controller. - Please read the comments at the top of . + Please read the comments at the top of . ServerWorks OSB4/CSB5 chipset support CONFIG_BLK_DEV_SVWKS @@ -1206,7 +1214,7 @@ PIO 0-4 mode settings, this allows dynamic tuning of the chipset via the standard end-user tool 'hdparm'. - Please read the comments at the top of . + Please read the comments at the top of . If you say Y here, you should also say Y to "PIIXn Tuning support", below. @@ -1226,7 +1234,7 @@ If unsure, say N. PROMISE PDC20246/PDC20262/PDC20265/PDC20267/PDC20268 support -CONFIG_BLK_DEV_PDC202XX +CONFIG_BLK_DEV_PDC202XX_OLD Promise Ultra33 or PDC20246 Promise Ultra66 or PDC20262 Promise Ultra100 or PDC20265/PDC20267/PDC20268 @@ -1244,7 +1252,7 @@ available" as well. Please read the comments at the top of - . + . If unsure, say N. @@ -1259,7 +1267,7 @@ when the PDC20265 BIOS has been disabled (for faster boot up). Please read the comments at the top of - . + . If unsure, say N. @@ -1282,7 +1290,7 @@ If you say Y here, you need to say Y to "Use DMA by default when available" as well. - Please read the comments at the top of . + Please read the comments at the top of . Silicon Image chipset support CONFIG_BLK_DEV_SIIMAGE @@ -1301,7 +1309,7 @@ available" as well. Please read the comments at the top of - . + . Winbond SL82c105 support CONFIG_BLK_DEV_SL82C105 @@ -1314,7 +1322,7 @@ This driver adds support for bus master DMA transfers using the Tekram TRM290 PCI IDE chip. Volunteers are needed for further tweaking and development. - Please read the comments at the top of . + Please read the comments at the top of . VIA82CXXX chipset support CONFIG_BLK_DEV_VIA82CXXX @@ -1326,7 +1334,7 @@ system" support. Please read the comments at the top of - . + . If you say Y here, then say Y to "Use DMA by default when available" as well. @@ -1366,7 +1374,7 @@ boot parameter. It enables support for the secondary IDE interface of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster I/O speeds to be set as well. See the files - and for + and for more info. DTC-2278 support @@ -1375,7 +1383,7 @@ boot parameter. It enables support for the secondary IDE interface of the DTC-2278 card, and permits faster I/O speeds to be set as well. See the and - files for more info. + files for more info. Holtek HT6560B support CONFIG_BLK_DEV_HT6560B @@ -1383,7 +1391,7 @@ boot parameter. It enables support for the secondary IDE interface of the Holtek card, and permits faster I/O speeds to be set as well. See the and - files for more info. + files for more info. PROMISE DC4030 support (EXPERIMENTAL) CONFIG_BLK_DEV_PDC4030 @@ -1393,14 +1401,14 @@ attached to the secondary interface. CD-ROM and TAPE devices are not supported yet. This driver is enabled at runtime using the "ide0=dc4030" kernel boot parameter. See the - and files + and files for more info. QDI QD65XX support CONFIG_BLK_DEV_QD65XX This driver is enabled at runtime using the "ide0=qd65xx" kernel boot parameter. It permits faster I/O speeds to be set. See the - and for + and for more info. UMC 8672 support @@ -1409,7 +1417,7 @@ boot parameter. It enables support for the secondary IDE interface of the UMC-8672, and permits faster I/O speeds to be set as well. See the files and - for more info. + for more info. Amiga Gayle IDE interface support CONFIG_BLK_DEV_GAYLE @@ -1835,6 +1843,20 @@ want), say M here and read . The module will be called lvm-mod.o. +Device-mapper support +CONFIG_BLK_DEV_DM + Device-mapper is a low level volume manager. It works by allowing + people to specify mappings for ranges of logical sectors. Various + mapping types are available, in addition people may write their own + modules containing custom mappings if they wish. + + Higher level volume managers such as LVM2 use this driver. + + If you want to compile this as a module, say M here and read + . The module will be called dm-mod.o. + + If unsure, say N. + Multiple devices driver support (RAID and LVM) CONFIG_MD Support multiple physical spindles through a single logical device. @@ -4583,14 +4605,11 @@ BIOS routines contained in a ROM chip in HP PA-RISC based machines. Enabling this option will implement the linux framebuffer device and an fbcon color text console using calls to the STI BIOS routines. - The HP framebuffer device is usually planar, uses a strange memory + The HP framebuffer device is sometimes planar, using a strange memory layout, and changing the plane mask to create colored pixels - requires a call to the STI routines, so do not expect /dev/fb to - actually be useful. However, it is the best we have as far as - graphics on the HP chipsets due to lack of hardware level - documentation for the various on-board HP chipsets used in these - systems. It is sufficient for basic text console functions, - including fonts. + can require a call to the STI routines, so /dev/fb may not actually + be useful. However, on some systems packed pixel formats are supported. + It is sufficient for basic text console functions, including fonts. You should probably enable this option, unless you are having trouble getting video when booting the kernel (make sure it isn't @@ -4728,12 +4747,11 @@ messages. Most people will want to say N here. If unsure, you will also want to say N. -Matrox unified accelerated driver CONFIG_FB_MATROX - Say Y here if you have a Matrox Millennium, Millennium II, Mystique, - Mystique 220, Productiva G100, Mystique G200, Millennium G200, - Matrox G400, G450 or G550 card in your box. At this time, support for - the G-series digital output is almost non-existant. + Say Y here if you have a Matrox Millennium, Matrox Millennium II, + Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox + Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video, + Matrox G400, G450 or G550 card in your box. This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). @@ -4744,7 +4762,6 @@ module load time. The parameters look like "video=matrox:XXX", and are described in . -Matrox Millennium I/II support CONFIG_FB_MATROX_MILLENIUM Say Y here if you have a Matrox Millennium or Matrox Millennium II video card. If you select "Advanced lowlevel driver options" below, @@ -4752,7 +4769,6 @@ packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can also use font widths different from 8. -Matrox Mystique support CONFIG_FB_MATROX_MYSTIQUE Say Y here if you have a Matrox Mystique or Matrox Mystique 220 video card. If you select "Advanced lowlevel driver options" below, @@ -4760,27 +4776,46 @@ packed pixel and 32 bpp packed pixel. You can also use font widths different from 8. -Matrox G100/G200/G400/G450/G550 support -CONFIG_FB_MATROX_G100 - Say Y here if you have a Matrox G100, G200, G400, G450, or G550 - based video card. If you select "Advanced lowlevel driver options", - you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp - packed pixel and 32 bpp packed pixel. You can also use font widths +CONFIG_FB_MATROX_G450 + Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based + video card. If you select "Advanced lowlevel driver options", you + should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed + pixel and 32 bpp packed pixel. You can also use font widths different from 8. If you need support for G400 secondary head, you must first say Y to "I2C support" and "I2C bit-banging support" in the character devices section, and then to "Matrox I2C support" and "G400 second head - support" here in the framebuffer section. + support" here in the framebuffer section. G450/G550 secondary head + and digital output are supported without additional modules. + + The driver starts in monitor mode. You must use the matroxset tool + (available at ) to + swap primary and secondary head outputs, or to change output mode. + Secondary head driver always start in 640x480 resolution and you + must use fbset to change it. + + Do not forget that second head supports only 16 and 32 bpp + packed pixels, so it is a good idea to compile them into the kernel + too. You can use only some font widths, as the driver uses generic + painting procedures (the secondary head does not use acceleration + engine). - If you have G550, you must also compile support for G450/G550 secondary - head into kernel, otherwise picture will be shown only on the output you - are probably not using... + G450/G550 hardware can display TV picture only from secondary CRTC, + and it performs no scaling, so picture must have 525 or 625 lines. - If you need support for G450 or G550 secondary head, say Y to - "Matrox G450/G550 second head support" below. +CONFIG_FB_MATROX_G100A + Say Y here if you have a Matrox G100, G200 or G400 based + video card. If you select "Advanced lowlevel driver options", you + should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed + pixel and 32 bpp packed pixel. You can also use font widths + different from 8. + + If you need support for G400 secondary head, you must first say Y to + "I2C support" and "I2C bit-banging support" in the character devices + section, and then to "Matrox I2C support" and "G400 second head + support" here in the framebuffer section. -Matrox I2C support CONFIG_FB_MATROX_I2C This drivers creates I2C buses which are needed for accessing the DDC (I2C) bus present on all Matroxes, an I2C bus which @@ -4794,7 +4829,6 @@ If you compile it as module, it will create a module named i2c-matroxfb.o. -Matrox G400 second head support CONFIG_FB_MATROX_MAVEN WARNING !!! This support does not work with G450 !!! @@ -4823,32 +4857,14 @@ painting procedures (the secondary head does not use acceleration engine). -Matrox G450 second head support -CONFIG_FB_MATROX_G450 - Say Y or M here if you want to use a secondary head (meaning two - monitors in parallel) on G450, or if you are using analog output - of G550. - - If you compile it as module, two modules are created, - matroxfb_crtc2.o and matroxfb_g450.o. Both modules are needed if you - want two independent display devices. - - The driver starts in monitor mode and currently does not support - output in TV modes. You must use the matroxset tool (available - at ) to swap - primary and secondary head outputs. Secondary head driver always - start in 640x480 resolution and you must use fbset to change it. - - Note on most G550 cards the analog output is the secondary head, - so you will need to say Y here to use it. - - Also do not forget that second head supports only 16 and 32 bpp - packed pixels, so it is a good idea to compile them into the kernel - too. You can use only some font widths, as the driver uses generic - painting procedures (the secondary head does not use acceleration - engine). - -Matrox unified driver multihead support +CONFIG_FB_MATROX_PROC + Say Y or M here if you want to access some informations about driver + state through /proc interface. + + You should download matrox_pins tool (available at + ) to get human + readable output. + CONFIG_FB_MATROX_MULTIHEAD Say Y here if you have more than one (supported) Matrox device in your computer and you want to use all of them for different monitors @@ -5294,6 +5310,19 @@ replacement for kerneld.) Say Y here and read about configuring it in . +Kernel .config file saved in kernel image +CONFIG_IKCONFIG + This option enables the complete Linux kernel ".config" file contents + to be saved in the kernel (zipped) image file. It provides + documentation of which kernel options are used in a running kernel or + in an on-disk kernel. It can be extracted from the kernel image file + with a script and used as input to rebuild the current kernel or to + build another kernel. Since the kernel image is zipped, using this + option adds approximately 8 KB to a kernel image file. + This option is not available as a module. If you want a separate + file to save the kernel's .config contents, use 'installkernel' or 'cp' + or a similar tool, or just save it in '/lib/modules/'. + ARP daemon support CONFIG_ARPD Normally, the kernel maintains an internal cache which maps IP @@ -9117,7 +9146,7 @@ Aironet 4500/4800 I365 broken support CONFIG_AIRONET4500_I365 If you have a PCMCIA Aironet 4500/4800 card which you want to use - without the standard PCMCIA cardservices provided by the pcmcia-cs + without the standard PCMCIA card services provided by the pcmcia-cs package, say Y here. This is not recommended, so say N. Aironet 4500/4800 PCMCIA support @@ -10524,6 +10553,15 @@ If unsure, say N here. +Raw HDLC Ethernet device support +CONFIG_HDLC_RAW_ETH + Say Y to this option if you want generic HDLC driver to support + raw HDLC Ethernet device emulation over WAN (Wide Area Network) + connections. + You will need it for Ethernet over HDLC bridges. + + If unsure, say N here. + Cisco HDLC support CONFIG_HDLC_CISCO Say Y to this option if you want generic HDLC driver to support @@ -10538,13 +10576,6 @@ If unsure, say N here. -Frame-Relay bridging support -CONFIG_HDLC_FR_BRIDGE - Say Y to this option if you want generic HDLC driver to support - bridging LAN frames over Frame-Relay links. - - If unsure, say N here. - Synchronous Point-to-Point Protocol (PPP) support CONFIG_HDLC_PPP Say Y to this option if you want generic HDLC driver to support @@ -10915,31 +10946,41 @@ The safe and default value for this is N. -SysKonnect SK-98xx support +SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support CONFIG_SK98LIN - Say Y here if you have a SysKonnect SK-98xx Gigabit Ethernet Server - Adapter. The following adapters are supported by this driver: - - SK-9841 (single link 1000Base-LX) - - SK-9842 (dual link 1000Base-LX) - - SK-9843 (single link 1000Base-SX) - - SK-9844 (dual link 1000Base-SX) - - SK-9821 (single link 1000Base-T) - - SK-9822 (dual link 1000Base-T) - - SK-9861 (single link Volition connector) - - SK-9862 (dual link Volition connector) - The driver also supports the following adapters from Allied Telesyn: - - AT2970... - - The dual link adapters support a link-failover feature. Read - for information about + Say Y here if you have a SysKonnect SK-98xx or SK-95xx Gigabit + Ethernet Server Adapter. The following adapters are supported by + this driver: + - SK-9521 10/100/1000Base-T Adapter + - SK-9821 Gigabit Ethernet 1000Base-T Server Adapter + - SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter + - SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter + - SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter + - SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter + - SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter + - SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter + - SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter + - SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter + - SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter + - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter + - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter + - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter + - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter + - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter + - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter + + The adapters support Jumbo Frames. + The dual link adapters support link-failover and dual port features. + The V2.0 adapters support the scatter-gather functionality with + sendfile(). Read Documentation/networking/sk98lin.txt for information about optional driver parameters. Questions concerning this driver may be addressed to: linux@syskonnect.de If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), - say M here and read . This is - recommended. The module will be called sk98lin.o. + say M here and read Documentation/modules.txt. This is recommended. + The module will be called sk98lin.o. Sun GEM support CONFIG_SUNGEM @@ -11267,6 +11308,24 @@ say M here and read . The module will be called 3c59x.o. +3cr990 series "Typhoon" support +CONFIG_TYPHOON + This option enables driver support for the 3cr990 series of cards: + + 3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97, + 3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server, + 3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR + + If you have a network (Ethernet) card of this type, say Y and read + the Ethernet-HOWTO, available from + . + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called typhoon.o. If you want to compile it as a + module, say M here and read as well + as . + Other ISA cards CONFIG_NET_ISA If your network (Ethernet) card hasn't been mentioned yet and its @@ -12699,12 +12758,44 @@ Quota support CONFIG_QUOTA If you say Y here, you will be able to set per user limits for disk - usage (also called disk quotas). Currently, it works only for the - ext2 file system. You need additional software in order to use quota - support; for details, read the Quota mini-HOWTO, available from + usage (also called disk quotas). Currently, it works for the + ext2, ext3, and reiserfs file system. You need additional software + in order to use quota support (you can download sources from + ). For further details, read + the Quota mini-HOWTO, available from . Probably the quota support is only useful for multi user systems. If unsure, say N. +Old quota format support +CONFIG_QFMT_V1 + This quota format was (is) used by kernels earlier than 2.4.??. If + you have quota working and you don't want to convert to new quota + format say Y here. + +VFS v0 quota format support +CONFIG_QFMT_V2 + This quota format allows using quotas with 32-bit UIDs/GIDs. If you + need this functionality say Y here. Note that you will need latest + quota utilities for new quota format with this kernel. + +Compatible quota interfaces +CONFIG_QIFACE_COMPAT + This option will enable old quota interface in kernel. + If you have old quota tools (version <= 3.04) and you don't want to + upgrade them say Y here. + +Original quota interface +CONFIG_QIFACE_V1 + This is the oldest quota interface. It was used for old quota format. + If you have old quota tools and you use old quota format choose this + interface (if unsure, this interface is the best one to choose). + +VFS v0 quota interface +CONFIG_QIFACE_V2 + This quota interface was used by VFS v0 quota format. If you need + support for VFS v0 quota format (eg. you're using quota on ReiserFS) + and you don't want to upgrade quota tools, choose this interface. + Memory Technology Device (MTD) support CONFIG_MTD Memory Technology Devices are flash, RAM and similar chips, often @@ -14713,7 +14804,7 @@ The module will be called rio500.o. If you want to compile it as a module, say M here and read . -USB Auerswald ISDN device support +Auerswald device support CONFIG_USB_AUERSWALD Say Y here if you want to connect an Auerswald USB ISDN Device to your computer's USB port. @@ -15312,7 +15403,7 @@ debugging output from the driver. This is unlike previous versions of the driver, where enabling this option would turn on debugging output automatically. - + Example: mount -t befs /dev/hda2 /mnt -o debug @@ -15715,6 +15806,30 @@ If unsure, say N. +Allow direct I/O on files in NFS +CONFIG_NFS_DIRECTIO + There are important applications whose performance or correctness + depends on uncached access to file data. Database clusters (multiple + copies of the same instance running on separate hosts) implement their + own cache coherency protocol that subsumes the NFS cache protocols. + Applications that process datasets considerably larger than the client's + memory do not always benefit from a local cache. A streaming video + server, for instance, has no need to cache the contents of a file. + + This option enables applications to perform direct I/O on files in NFS + file systems using the O_DIRECT open() flag. When O_DIRECT is set for + files, their data is not cached in the system's page cache. Direct + read and write operations are aligned to block boundaries. Data is + moved to and from user-level application buffers directly. + + Unless your program is designed to use O_DIRECT properly, you are much + better off allowing the NFS client to manage caching for you. Misusing + O_DIRECT can cause poor server performance or network storms. This + kernel build option defaults OFF to avoid exposing system administrators + unwittingly to a potentially hazardous feature. + + If unsure, say N. + Root file system on NFS CONFIG_ROOT_NFS If you want your Linux box to mount its whole root file system (the @@ -16111,7 +16226,7 @@ Say Y here if you would like to use hard disks under Linux which were partitioned on a Macintosh. -Windows Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL) +Windows Logical Disk Manager (Dynamic Disk) support CONFIG_LDM_PARTITION Say Y here if you would like to use hard disks under Linux which were partitioned using Windows 2000's or XP's Logical Disk Manager. @@ -16126,8 +16241,7 @@ Normal partitions are now called Basic Disks under Windows 2000 and XP. - Technical documentation to accompany this driver is available from: - . + For a fuller description read . If unsure, say N. @@ -16200,8 +16314,9 @@ Intel EFI GUID partition support CONFIG_EFI_PARTITION Say Y here if you would like to use hard disks under Linux which - were partitioned using EFI GPT. Presently only useful on the - IA-64 platform. + were partitioned using EFI GPT. This is the default partition + scheme on IA64, and can be used on other platforms when + large block device (64-bit block address) support is desired. Ultrix partition table support CONFIG_ULTRIX_PARTITION @@ -17043,17 +17158,36 @@ HIL keyboard support CONFIG_HIL The "Human Interface Loop" is a older, 8-channel USB-like controller - used in Hewlett Packard PA-RISC based machines. There are a few - cases where it is seen on PC/MAC architectures as well, usually also - manufactured by HP. This driver is based off MACH and BSD drivers, - and implements support for a keyboard attached to the HIL port. + used in several Hewlett Packard models. This driver is based off + MACH and BSD drivers, and implements support for a keyboard attached + to the HIL port, but not for any other types of HIL input devices + like mice or tablets. However, it has been thoroughly tested and is + stable. + Full support for the USB-like functions and non-keyboard channels of - the HIL is not provided for in this driver. There are vestiges of - mouse support in the driver, but it is probably not working. The - necessary hardware documentation to fully support the HIL controller - and interface it to the linux-input API is lacking. + the HIL is currently being added to the PA-RISC port and will + be backported to work on the m68k port as well. + + Enable this option if you intend to use a HIL keyboard as your + primary keyboard and/or do not wish to test the new HIL driver. - Enable this option if you intend to use a HIL keyboard. +HP System Device Controller support +CONFIG_HP_SDC + This option enables supports for the the "System Device Controller", + an i8042 carrying microcode to manage a few miscellanous devices + on some Hewlett Packard systems. The SDC itself contains a 10ms + resolution timer/clock capable of delivering interrupts on periodic + and one-shot basis. The SDC may also be connected to a battery-backed + real-time clock, a basic audio waveform generator, and an HP-HIL + Master Link Controller serving up to seven input devices. + + By itself this option is rather useless, but enabling it will + enable selection of drivers for the abovementioned devices. + It is, however, incompatible with the old, reliable HIL keyboard + driver, and the new HIL driver is experimental, so if you plan to + use a HIL keyboard as your primary keyboard, you may wish to + keep using that driver until the new HIL drivers have had more + testing. Include IOP (IIfx/Quadra 9x0) ADB driver CONFIG_ADB_IOP @@ -17363,6 +17497,19 @@ read . The module will be called istallion.o. +PDC software console support +CONFIG_PDC_CONSOLE + Saying Y here will enable the software based PDC console to be + used as the system console. This is useful for machines in + which the hardware based console has not been written yet. The + following steps must be competed to use the PDC console: + + 1. create the device entry (mknod /dev/ttyB0 c 60 0) + 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0 + 3. Add device ttyB0 to /etc/securetty (if you want to log on as + root on this console.) + 4. Change the kernel command console parameter to: console=ttyB0 + Microgate SyncLink adapter support CONFIG_SYNCLINK Provides support for the SyncLink ISA and PCI multiprotocol serial @@ -17512,6 +17659,10 @@ doing that; to actually get it to happen you need to pass the option "console=lp0" to the kernel at boot time. + Note that kernel messages can get lost if the printer is out of + paper (or off, or unplugged, or too busy..), but this behaviour + can be changed. See drivers/char/lp.c (do this at your own risk). + If the printer is out of paper (or off, or unplugged, or too busy..) the kernel will stall until the printer is ready again. By defining CONSOLE_LP_STRICT to 0 (at your own risk) you @@ -19017,6 +19168,15 @@ . The module will be called cpuid.o +x86 BIOS Enhanced Disk Drive support +CONFIG_EDD + Say Y or M here if you want to enable BIOS Enhanced Disk Drive + Services real mode BIOS calls to determine which disk + BIOS tries boot from. This information is then exported via /proc. + + This option is experimental, but believed to be safe, + and most disk controller BIOS vendors do not yet implement this feature. + SBC-60XX Watchdog Timer CONFIG_60XX_WDT This driver can be used with the watchdog timer found on some @@ -19083,6 +19243,34 @@ The module is called rtc.o. If you want to compile it as a module, say M here and read . +Generic Real Time Clock Support +CONFIG_GEN_RTC + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock (or hardware clock) built + into your computer. + + In 2.4 and later kernels this is the only way to set and get rtc + time on m68k systems so it is highly recommended. + + It reports status information via the file /proc/driver/rtc and its + behaviour is set by various ioctls on /dev/rtc. If you enable the + "extended RTC operation" below it will also provide an emulation + for RTC_UIE which is required by some programs and may improve + precision in some cases. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called genrtc.o. If you want to compile it as a module, + say M here and read . To load the + module automatically add 'alias char-major-10-135 genrtc' to your + /etc/modules.conf + +Extended RTC operation +CONFIG_GEN_RTC_X + Provides an emulation for RTC_UIE which is required by some programs + and may improve precision of the generic RTC support in some cases. + Tadpole ANA H8 Support CONFIG_H8 The Hitachi H8/337 is a microcontroller used to deal with the power @@ -23065,6 +23253,23 @@ say M here and read . The module will be called radio-sf16fmi.o. +SF16FMR2 Radio +CONFIG_RADIO_SF16FMR2 + Choose Y here if you have one of these FM radio cards. If you + compile the driver into the kernel and your card is not PnP one, you + have to add "sf16fmr2=" to the kernel command line (I/O address is + 0x284 or 0x384, default 0x384). + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux API. Information on + this API and pointers to "v4l" programs may be found on the WWW at + . + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called radio-sf16fmr2.o. + Typhoon Radio (a.k.a. EcoRadio) CONFIG_RADIO_TYPHOON Choose Y here if you have one of these FM radio cards, and then fill @@ -25817,6 +26022,14 @@ of the BUG call as well as the EIP and oops trace. This aids debugging but costs about 70-100K of memory. +Morse code panics +CONFIG_PANIC_MORSE + Say Y here to receive panic messages in morse code on your keyboard LEDs, and + optionally the PC speaker, if available. + The kernel param "panicblink" controls this feature, set it to 0 to disable, + 1 for LEDs only, 2 for pc speaker, or 3 for both. If you disable this option, + then you will receive a steady blink on the LEDs instead. + Include kgdb kernel debugger CONFIG_KGDB Include in-kernel hooks for kgdb, the Linux kernel source level @@ -25862,9 +26075,11 @@ U2/Uturn I/O MMU CONFIG_IOMMU_CCIO - Say Y here to enable DMA management routines for the first - generation of PA-RISC cache-coherent machines. Programs the - U2/Uturn chip in "Virtual Mode" and use the I/O MMU. + The U2/UTurn is a bus converter with io mmu present in the Cxxx, D, + J, K, and R class machines. Compiling this driver into the kernel will + not hurt anything, removing it will reduce your kernel by about 14k. + + If unsure, say Y. LBA/Elroy PCI support CONFIG_PCI_LBA @@ -26237,6 +26452,96 @@ written) to implement the policy. If you don't understand what this is all about, it's safe to say 'N'. + For more information, take a look at linux/Documentation/cpufreq or + at + + If in doubt, say N. + +CONFIG_CPU_FREQ_24_API + This enables the /proc/sys/cpu/ sysctl interface for controlling + CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5 + uses /proc/cpufreq instead. Please note that some drivers do not + work with the 2.4. /proc/sys/cpu sysctl interface, so if in doubt, + say N here. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_X86_POWERNOW_K6 + This adds the CPUFreq driver for mobile AMD K6-2+ and mobile + AMD K6-3+ processors. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_X86_P4_CLOCKMOD + This adds the CPUFreq driver for Intel Pentium 4 / XEON + processors. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_ELAN_CPUFREQ + This adds the CPUFreq driver for AMD Elan SC400 and SC410 + processors. + + You need to specify the processor maximum speed as a boot + parameter (or as module parameter): + elanfreq=maxspeed + with the argument "maxspeed" given in kHz. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_X86_LONGHAUL + This adds the CPUFreq driver for VIA Samuel/CyrixIII, + VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T + processors. + + If you do not want to scale the Front Side Bus or voltage, + pass the module parameter "dont_scale_fsb=1" or + "dont_scale_voltage=1". Additionally, it is advised that + you pass the current Front Side Bus speed (in MHz) to + this module as module parameter "current_fsb", e.g. + "current_fsb=133" for a Front Side Bus speed of 133 MHz. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_X86_SPEEDSTEP + This adds the CPUFreq driver for certain mobile Intel Pentium III + (Coppermine), all mobile Intel Pentium III-M (Tulatin) and all + mobile Intel Pentium 4 P4-Ms. + + If you use a Coppermine Pentium III which is capable of + SpeedStep, you need to pass the boot or module parameter + "speedstep_coppermine=1" to the kernel. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_X86_LONGRUN + This adds the CPUFreq driver for Transmeta Crusoe processors which + support LongRun. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +CONFIG_X86_GX_SUSPMOD + This add the CPUFreq driver for NatSemi Geode processors which + support suspend modulation. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + SiS CONFIG_DRM_SIS Choose this option if you have a SIS graphics card. AGP support is @@ -26250,7 +26555,7 @@ Slave has its own LEDs CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS - Enable if the slave has it's own LEDs. + Enable if the slave has its own LEDs. ATA/IDE support CONFIG_ETRAX_IDE @@ -26420,6 +26725,90 @@ If unsure, say N. +NatSemi SCx200 support +CONFIG_SCx200 + This provides basic support for the National Semiconductor SCx200 + processor. Right now this is just a driver for the GPIO pins. + + If you don't know what to do here, say N. + + This support is also available as a module. If compiled as a + module, it will be called scx200.o. + +NatSemi SCx200 Watchdog +CONFIG_SCx200_WDT + Enable the built-in watchdog timer support on the National + Semiconductor SCx200 processors. + + If compiled as a module, it will be called scx200_watchdog.o. + +Flash device mapped with DOCCS on NatSemi SCx200 +CONFIG_MTD_SCx200_DOCFLASH + Enable support for a flash chip mapped using the DOCCS signal on a + National Semiconductor SCx200 processor. + + If you don't know what to do here, say N. + + If compiled as a module, it will be called scx200_docflash.o. + +NatSemi SCx200 I2C using GPIO pins +CONFIG_SCx200_I2C + Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. + + If you don't know what to do here, say N. + + If compiled as a module, it will be called scx200_i2c.o. + +GPIO pin used for SCL +CONFIG_SCx200_I2C_SCL + Enter the GPIO pin number used for the SCL signal. This value can + also be specified with a module parameter. + +GPIO pin used for SDA +CONFIG_SCx200_I2C_SDA + Enter the GPIO pin number used for the SSA signal. This value can + also be specified with a module parameter. + +NatSemi SCx200 ACCESS.bus +CONFIG_SCx200_ACB + Enable the use of the ACCESS.bus controllers of a SCx200 processor. + + If you don't know what to do here, say N. + + If compiled as a module, it will be called scx200_acb.o. + +IPMI top-level message handler +CONFIG_IPMI_HANDLER + This enables the central IPMI message handler, required for IPMI + to work. Note that you must have this enabled to do any other IPMI + things. + + IPMI is a standard for managing sensors (temperature, + voltage, etc.) in a system. + + See Documentation/IPMI.txt for more details on the driver. + + If unsure, say N. + +Generate a panic event to all BMCs on a panic +CONFIG_IPMI_PANIC_EVENT + When a panic occurs, this will cause the IPMI message handler to + generate an IPMI event describing the panic to each interface + registered with the message handler. + +Device interface for IPMI +CONFIG_IPMI_DEVICE_INTERFACE + This provides an IOCTL interface to the IPMI message handler so + userland processes may use IPMI. It supports poll() and select(). + +IPMI KCS handler +CONFIG_IPMI_KCS + Provides a driver for a KCS-style interface to a BMC. + +IPMI Watchdog Timer +CONFIG_IPMI_WATCHDOG + This enables the IPMI watchdog timer. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/cpufreq linux.21pre4-ac6/Documentation/cpufreq --- linux.21pre4/Documentation/cpufreq 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/Documentation/cpufreq 2003-01-06 16:33:44.000000000 +0000 @@ -0,0 +1,363 @@ + CPU frequency and voltage scaling code in the Linux(TM) kernel + + + L i n u x C P U F r e q + + + + + Dominik Brodowski + David Kimdon + + + + Clock scaling allows you to change the clock speed of the CPUs on the + fly. This is a nice method to save battery power, because the lower + the clock speed, the less power the CPU consumes. + + + +Contents: +--------- +1. Supported architectures +2. User interface +2.1 /proc/cpufreq interface [2.6] +2.2. /proc/sys/cpu/ interface [2.4] +3. CPUFreq core and interfaces +3.1 General information +3.2 CPUFreq notifiers +3.3 CPUFreq architecture drivers +4. Mailing list and Links + + + +1. Supported architectures +========================== + +ARM: + ARM Integrator, SA 1100, SA1110 +-------------------------------- + No known issues. + + +AMD Elan: + SC400, SC410 +-------------------------------- + You need to specify the highest allowed CPU frequency as + a module parameter ("max_freq") or as boot parameter + ("elanfreq="). Else the available speed range will be + limited to the speed at which the CPU runs while this + module is loaded. + + +VIA Cyrix Longhaul: + VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3, + VIA Cyrix Ezra, VIA Cyrix Ezra-T +-------------------------------- + If you do not want to scale the Front Side Bus or voltage, + pass the module parameter "dont_scale_fsb=1" or + "dont_scale_voltage=1". Additionally, it is advised that + you pass the current Front Side Bus speed (in MHz) to + this module as module parameter "current_fsb", e.g. + "current_fsb=133" for a Front Side Bus speed of 133 MHz. + + +Intel SpeedStep: + certain mobile Intel Pentium III (Coppermine), and all mobile + Intel Pentium III-M (Tualatin) and mobile Intel Pentium 4 P4-Ms. +-------------------------------- + Unfortunately, only modern Intel ICH2-M and ICH3-M chipsets are + supported yet. + + +P4 CPU Clock Modulation: + Intel Pentium 4 Xeon processors +--------------------------------- + Note that you can only switch the speed of two logical CPUs at + once - but each phyiscal CPU may have different throttling levels. + + +PowerNow! K6: + mobile AMD K6-2+ / mobile K6-3+: +-------------------------------- + No known issues. + + +Transmeta Crusoe Longrun: + Transmeta Crusoe processors: +-------------------------------- + It is recommended to use the 2.6. /proc/cpufreq interface when + using this driver + + + +2. User Interface +================= + +2.1 /proc/cpufreq interface [2.6] +*********************************** + +Starting in the patches for kernel 2.5.33, CPUFreq uses a "policy" +interface /proc/cpufreq. + +When you "cat" this file, you'll find something like: + +-- + minimum CPU frequency - maximum CPU frequency - policy +CPU 0 1200000 ( 75%) - 1600000 (100%) - performance +-- + +This means the current policy allows this CPU to be run anywhere +between 1.2 GHz (the value is in kHz) and 1.6 GHz with an eye towards +performance. + +To change the policy, "echo" the desired new policy into +/proc/cpufreq. Use one of the following formats: + +cpu_nr:min_freq:max_freq:policy +cpu_nr%min_freq%max_freq%policy +min_freq:max_freq:policy +min_freq%max_freq%policy + +with cpu_nr being the CPU which shall be affected, min_freq and +max_freq the lower and upper limit of the CPU core frequency in kHz, +and policy either "performance" or "powersave". +A few examples: + +root@notebook:#echo -n "0:0:0:powersave" > /proc/cpufreq + sets the CPU #0 to the lowest supported frequency. + +root@notebook:#echo -n "1%100%100%performance" > /proc/cpufreq + sets the CPU #1 to the highest supported frequency. + +root@notebook:#echo -n "1000000:2000000:performance" > /proc/cpufreq + to set the frequency of all CPUs between 1 GHz and 2 GHz and to + the policy "performance". + +Please note that the values you "echo" into /proc/cpufreq are +validated first, and may be limited by hardware or thermal +considerations. Because of this, a read from /proc/cpufreq might +differ from what was written into it. + + +When you read /proc/cpufreq for the first time after a CPUFreq driver +has been initialized, you'll see the "default policy" for this +driver. If this does not suit your needs, you can pass a boot +parameter to the cpufreq core. Use the following syntax for this: + "cpufreq=min_freq:max_freq:policy", i.e. you may not chose a +specific CPU and you need to specify the limits in kHz and not in +per cent. + + +2.2 /proc/cpufreq interface [2.4] +*********************************** + +Previsiously (and still available as a config option), CPUFreq used +a "sysctl" interface which is located in + /proc/sys/cpu/0/ + /proc/sys/cpu/1/ ... (SMP only) + +In these directories, you will find three files of importance for +CPUFreq: speed-max, speed-min and speed: + +speed shows the current CPU frequency in kHz, +speed-min the minimum supported CPU frequency, and +speed-max the maximum supported CPU frequency. + + +To change the CPU frequency, "echo" the desired CPU frequency (in kHz) +to speed. For example, to set the CPU speed to the lowest/highest +allowed frequency do: + +root@notebook:# cat /proc/sys/cpu/0/speed-min > /proc/sys/cpu/0/speed +root@notebook:# cat /proc/sys/cpu/0/speed-max > /proc/sys/cpu/0/speed + + + +3. CPUFreq core and interfaces +=============================== + +3.1 General information +************************* + +The CPUFreq core code is located in linux/kernel/cpufreq.c. This +cpufreq code offers a standardized interface for the CPUFreq +architecture drivers (those pieces of code that do actual +frequency transitions), as well as to "notifiers". These are device +drivers or other part of the kernel that need to be informed of +policy changes (like thermal modules like ACPI) or of all +frequency changes (like timing code) or even need to force certain +speed limits (like LCD drivers on ARM architecture). Additionally, the +kernel "constant" loops_per_jiffy is updated on frequency changes +here. + + +3.2 CPUFreq notifiers +*********************** + +CPUFreq notifiers conform to the standard kernel notifier interface. +See linux/include/linux/notifier.h for details on notifiers. + +There are two different CPUFreq notifiers - policy notifiers and +transition notifiers. + + +3.2.1 CPUFreq policy notifiers +****************************** + +These are notified when a new policy is intended to be set. Each +CPUFreq policy notifier is called three times for a policy transition: + +1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if + they see a need for this - may it be thermal considerations or + hardware limitations. + +2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid + hardware failure. + +3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy + - if two hardware drivers failed to agree on a new policy before this + stage, the incompatible hardware shall be shut down, and the user + informed of this. + +The phase is specified in the second argument to the notifier. + +The third argument, a void *pointer, points to a struct cpufreq_policy +consisting of five values: cpu, min, max, policy and max_cpu_freq. Min +and max are the lower and upper frequencies (in kHz) of the new +policy, policy the new policy, cpu the number of the affected CPU or +CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported +CPU frequency. This value is given for informational purposes only. + + +3.2.2 CPUFreq transition notifiers +********************************** + +These are notified twice when the CPUfreq driver switches the CPU core +frequency and this change has any external implications. + +The second argument specifies the phase - CPUFREQ_PRECHANGE or +CPUFREQ_POSTCHANGE. + +The third argument is a struct cpufreq_freqs with the following +values: +cpu - number of the affected CPU or CPUFREQ_ALL_CPUS +old - old frequency +new - new frequency + + +3.3 CPUFreq architecture drivers +********************************** + +CPUFreq architecture drivers are the pieces of kernel code that +actually perform CPU frequency transitions. These need to be +initialized separately (separate initcalls), and may be +modularized. They interact with the CPUFreq core in the following way: + +cpufreq_register() +------------------ +cpufreq_register registers an arch driver to the CPUFreq core. Please +note that only one arch driver may be registered at any time. -EBUSY +is returned when an arch driver is already registered. The argument to +cpufreq_register, struct cpufreq_driver *driver, is described later. + +cpufreq_unregister() +-------------------- +cpufreq_unregister unregisters an arch driver, e.g. on module +unloading. Please note that there is no check done that this is called +from the driver which actually registered itself to the core, so +please only call this function when you are sure the arch driver got +registered correctly before. + +cpufreq_notify_transition() +--------------------------- +On "dumb" hardware where only fixed frequency can be set, the driver +must call cpufreq_notify_transition() once before, and once after the +actual transition. + +struct cpufreq_driver +--------------------- +On initialization, the arch driver is supposed to pass a pointer +to a struct cpufreq_driver *cpufreq_driver consisting of the following +entries: + +cpufreq_verify_t verify: This is a pointer to a function with the + following definition: + int verify_function (struct cpufreq_policy *policy). + This function must verify the new policy is within the limits + supported by the CPU, and at least one supported CPU is within + this range. It may be useful to use cpufreq.h / + cpufreq_verify_within_limits for this. If this is called with + CPUFREQ_ALL_CPUS, and there is no common subset of frequencies + for all CPUs, exit with an error. + +cpufreq_setpolicy_t setpolicy: This is a pointer to a function with + the following definition: + int setpolicy_function (struct cpufreq_policy *policy). + This function must set the CPU to the new policy. If it is a + "dumb" CPU which only allows fixed frequencies to be set, it + shall set it to the lowest within the limit for + CPUFREQ_POLICY_POWERSAVE, and to the highest for + CPUFREQ_POLICY_PERFORMANCE. Once CONFIG_CPU_FREQ_DYNAMIC is + implemented, it can use a dynamic method to adjust the speed + between the lower and upper limit. + +struct cpufreq_policy *policy: This is an array of NR_CPUS struct + cpufreq_policies, containing the current policies set for these + CPUs. Note that policy[cpu].max_cpu_freq must contain the + absolute maximum CPU frequency supported by the specified cpu. + +In case the driver is expected to run with the 2.4.-style API +(/proc/sys/cpu/.../), two more values must be passed +#ifdef CONFIG_CPU_FREQ_24_API + unsigned int cpu_min_freq[NR_CPUS]; + unsigned int cpu_cur_freq[NR_CPUS]; +#endif + with cpu_min_freq[cpu] being the minimum CPU frequency + supported by the CPU; and the entries in cpu_cur_freq + reflecting the current speed of the appropriate CPU. + +Some Requirements to CPUFreq architecture drivers +------------------------------------------------- +* Only call cpufreq_register() when the ability to switch CPU + frequencies is _verified_ or can't be missing. Also, all + other initialization must be done beofre this call, as + cpfureq_register calls the driver's verify and setpolicy code for + each CPU. +* cpufreq_unregister() may only be called if cpufreq_register() has + been successfully(!) called before. +* kfree() the struct cpufreq_driver only after the call to + cpufreq_unregister(), unless cpufreq_register() failed. + + + +4. Mailing list and Links +************************* + + +Mailing List +------------ +There is a CPU frequency changing CVS commit and general list where +you can report bugs, problems or submit patches. To post a message, +send an email to cpufreq@www.linux.org.uk, to subscribe go to +http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the +mailing list are available to subscribers at +http://www.linux.org.uk/mailman/private/cpufreq/. + + +Links +----- +the FTP archives: +* ftp://ftp.linux.org.uk/pub/linux/cpufreq/ + +how to access the CVS repository: +* http://cvs.arm.linux.org.uk/ + +the CPUFreq Mailing list: +* http://www.linux.org.uk/mailman/listinfo/cpufreq + +Clock and voltage scaling for the SA-1100: +* http://www.lart.tudelft.nl/projects/scaling + +CPUFreq project homepage +* http://www.brodo.de/cpufreq/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/DocBook/videobook.tmpl linux.21pre4-ac6/Documentation/DocBook/videobook.tmpl --- linux.21pre4/Documentation/DocBook/videobook.tmpl 2003-01-29 16:27:24.000000000 +0000 +++ linux.21pre4-ac6/Documentation/DocBook/videobook.tmpl 2003-01-08 15:25:42.000000000 +0000 @@ -146,16 +146,17 @@ int __init myradio_init(struct video_init *v) { - if(check_region(io, MY_IO_SIZE)) + if(!request_region(io, MY_IO_SIZE, "myradio")) { printk(KERN_ERR "myradio: port 0x%03X is in use.\n", io); return -EBUSY; } - if(video_device_register(&my_radio, VFL_TYPE_RADIO)==-1) + if(video_device_register(&my_radio, VFL_TYPE_RADIO)==-1) { + release_region(io, MY_IO_SIZE); return -EINVAL; - request_region(io, MY_IO_SIZE, "myradio"); + } return 0; } @@ -920,7 +921,7 @@ int __init mycamera_init(struct video_init *v) { - if(check_region(io, MY_IO_SIZE)) + if(!request_region(io, MY_IO_SIZE, "mycamera")) { printk(KERN_ERR "mycamera: port 0x%03X is in use.\n", io); @@ -928,9 +929,10 @@ } if(video_device_register(&my_camera, - VFL_TYPE_GRABBER)==-1) + VFL_TYPE_GRABBER)==-1) { + release_region(io, MY_IO_SIZE); return -EINVAL; - request_region(io, MY_IO_SIZE, "mycamera"); + } return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/DriverFixers linux.21pre4-ac6/Documentation/DriverFixers --- linux.21pre4/Documentation/DriverFixers 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/Documentation/DriverFixers 2003-01-06 15:44:42.000000000 +0000 @@ -0,0 +1,75 @@ +People who fix drivers as a business - ie for money. (No recommendation, +business association or other relationship implied. This for the benefit of +American lawyers is just a list of people who have asked to be listed - nothing +more). + +Companies Who Will Do Small Contract Work +----------------------------------------- + +Company: BitWizard +Contact: Rogier Wolff +E-Mail: R.E.Wolff@BitWizard.nl + +Company: Caederus +Contact: Justin Mitchell +E-Mail: info@caederus.com +Location: Swansea, Wales, UK +URL: http://www.caederus.com/ + +Company: Calsoft Inc +Contact: Anupam Bhide +E-Mail: anupam@calsoftinc.com +URL: http://www.calsoftinc.com +Location: Pune, India + +Company: Hansen Partnership Inc +Contact: James Bottomley +E-Mail: James.Bottomley@HansenPartnership.com +Location: 1, Partridge Square, Oswego, Illinois 60543, USA + +Company: Linking +Contact: Elmer Joandi +E-Mail: elmer@linkingsoft.com + +Company: Penguru Consulting, LLC +Contact: Komron Takmil +E-Mail: komron@penguru.net +Location: Salt Lake City, UT USA + +Company: 7Chips +Contact: Vadim Lebedev +E-Mail: vadim@7chips.com +Location: Paris, France +Notes: Experienced in Linux and uClinux on x86/ARM/Motorola + +Company: Weinigel Ingenjörsbyrå AB +Contact: Christer Weinigel +E-Mail: christer@weinigel.se +Location: Stockholm, Sweden + +Company: WildOpenSource +Contact: Martin Hicks +E-Mail: info@wildopensource.com + + +Companies Only Interested In Larger ($10000+) Jobs +-------------------------------------------------- + + + +Companies Only Interested In Very Large ($100000+) Jobs +------------------------------------------------------- + + +To be added to the list: email giving the +following information + +Company: CompanyName [Required] +Contact: ContactName [Required] +E-Mail: An email address [Required] +URL: Web site [Optional] +Location: Area/Country [Optional] +Telephone: Contact phone number [Optional] +Speciality: Any specific speciality [Optional] +Notes: Any other notes (eg certifications, specialities) + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/i386/zero-page.txt linux.21pre4-ac6/Documentation/i386/zero-page.txt --- linux.21pre4/Documentation/i386/zero-page.txt 2003-01-29 16:27:24.000000000 +0000 +++ linux.21pre4-ac6/Documentation/i386/zero-page.txt 2003-01-08 15:33:39.000000000 +0000 @@ -31,6 +31,7 @@ 0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb 0x1e8 char number of entries in E820MAP (below) +0x1e9 unsigned char number of entries in EDDBUF (below) 0x1f1 char size of setup.S, number of sectors 0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0) 0x1f4 unsigned short size of compressed kernel-part in the @@ -66,6 +67,7 @@ 0x220 4 bytes (setup.S) 0x224 unsigned short setup.S heap end pointer 0x2d0 - 0x600 E820MAP +0x600 - 0x7D4 EDDBUF (setup.S) 0x800 string, 2K max COMMAND_LINE, the kernel commandline as copied using CL_OFFSET. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/IPMI.txt linux.21pre4-ac6/Documentation/IPMI.txt --- linux.21pre4/Documentation/IPMI.txt 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/Documentation/IPMI.txt 2003-02-21 15:41:43.000000000 +0000 @@ -5,6 +5,18 @@ +The Intelligent Platform Management Interface, or IPMI, is a +standard for controlling intelligent devices that monitor a system. +It provides for dynamic discovery of sensors in the system and the +ability to monitor the sensors and be informed when the sensor's +values change or go outside certain boundaries. It also has a +standardized database for field-replacable units (FRUs) and a watchdog +timer. + +To use this, you need an interface to an IPMI controller in your +system (called a Baseboard Management Controller, or BMC) and +management software that can use the IPMI system. + This document describes how to use the IPMI driver for Linux. If you are not familiar with IPMI itself, see the web site at http://www.intel.com/design/servers/ipmi/index.htm. IPMI is a big @@ -307,7 +319,7 @@ used to control it: insmod ipmi_watchdog timeout= pretimeout= action= - preaction= + preaction= preop= The timeout is the number of seconds to the action, and the pretimeout is the amount of seconds before the reset that the pre-timeout panic will @@ -319,7 +331,18 @@ The preaction may be "pre_smi" for an indication through the SMI interface, "pre_int" for an indication through the SMI with an -interrupts, and "pre_nmi" for a NMI on a preaction. +interrupts, and "pre_nmi" for a NMI on a preaction. This is how +the driver is informed of the pretimeout. + +The preop may be set to "preop_none" for no operation on a pretimeout, +"preop_panic" to set the preoperation to panic, or "preop_give_data" +to provide data to read from the watchdog device when the pretimeout +occurs. A "pre_nmi" setting CANNOT be used with "preop_give_data" +because you can't do data operations from an NMI. + +When preop is set to "preop_give_data", one byte comes ready to read +on the device when the pretimeout occurs. Select and fasync work on +the device, as well. When compiled into the kernel, the kernel command line is available for configuring the watchdog: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/networking/00-INDEX linux.21pre4-ac6/Documentation/networking/00-INDEX --- linux.21pre4/Documentation/networking/00-INDEX 2003-01-29 16:27:21.000000000 +0000 +++ linux.21pre4-ac6/Documentation/networking/00-INDEX 2003-01-06 15:38:40.000000000 +0000 @@ -97,7 +97,8 @@ sis900.txt - SiS 900/7016 Fast Ethernet device driver info. sk98lin.txt - - SysKonnect SK-NET (SK-98xx) Gigabit Ethernet driver info. + - SysKonnect SK-98xx and SK-98xx Gigabit Ethernet Adapter family + driver info. skfp.txt - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. smc9.txt diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/networking/generic-hdlc.txt linux.21pre4-ac6/Documentation/networking/generic-hdlc.txt --- linux.21pre4/Documentation/networking/generic-hdlc.txt 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/Documentation/networking/generic-hdlc.txt 2003-01-28 16:39:15.000000000 +0000 @@ -1,11 +1,13 @@ -Generic HDLC layer for Linux kernel 2.4/2.5 +Generic HDLC layer Krzysztof Halasa -May, 2001 +January, 2003 Generic HDLC layer currently supports: -- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP), -- raw HDLC (IPv4 only), +- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP). + Normal (routed) and Ethernet-bridged (Ethernet device emulation) + interfaces can share a single PVC. +- raw HDLC - either IP (IPv4) interface or Ethernet device emulation. - Cisco HDLC, - PPP (uses syncppp.c), - X.25 (uses X.25 routines). @@ -15,6 +17,10 @@ - RISCom/N2 by SDL Communications Inc. - and others, some not in the official kernel. +Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible +with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). + + Make sure the hdlc.o and the hardware driver are loaded. It should create a number of "hdlc" (hdlc0 etc) network devices, one for each WAN port. You'll need the "sethdlc" utility, get it from: @@ -58,6 +64,9 @@ no-parity / crc16 / crc16-pr0 (CRC16 with preset zeros) / crc32-itu crc16-itu (CRC16 with ITU-T polynomial) / crc16-itu-pr0 - sets parity +* hdlc-eth - Ethernet device emulation using HDLC. Parity and encoding + as above. + * cisco - sets Cisco HDLC mode (IP, IPv6 and IPX supported) interval - time in seconds between keepalive packets timeout - time in seconds after last received keepalive packet before @@ -77,7 +86,12 @@ n392 - error threshold - both user and network n393 - monitored events count - both user and network -* create | delete n - FR only - adds / deletes PVC interface with DLCI #n. +Frame-Relay only: +* create n | delete n - adds / deletes PVC interface with DLCI #n. + Newly created interface will be named pvc0, pvc1 etc. + +* create ether n | delete ether n - adds a device for Ethernet-bridged + frames. The device will be named pvceth0, pvceth1 etc. @@ -104,11 +118,11 @@ If you have a problem with N2 or C101 card, you can issue the "private" -command to see port's packet descriptor rings: +command to see port's packet descriptor rings (in kernel logs): sethdlc hdlc0 private -The hardware driver have to be build with CONFIG_HDLC_DEBUG_RINGS. +The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS. Attaching this info to bug reports would be helpful. Anyway, let me know if you have problems using this. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/networking/sk98lin.txt linux.21pre4-ac6/Documentation/networking/sk98lin.txt --- linux.21pre4/Documentation/networking/sk98lin.txt 2003-01-29 16:27:21.000000000 +0000 +++ linux.21pre4-ac6/Documentation/networking/sk98lin.txt 2003-01-06 15:38:40.000000000 +0000 @@ -1,120 +1,158 @@ -(C)Copyright 1999-2001 SysKonnect GmbH. +(C)Copyright 1999-2002 SysKonnect GmbH. All rights reserved =========================================================================== -sk98lin.txt created 28-May-2001 +sk98lin.txt created 19-Dec-2002 -Readme File for sk98lin v4.06 -SK-NET Gigabit Ethernet PCI driver for LINUX +Readme File for sk98lin v6.02 +SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX This file contains -(1) OVERVIEW -(2) REQUIRED FILES -(3) INSTALLATION -(4) INCLUSION OF ADAPTER AT SYSTEM START -(5) DRIVER PARAMETERS -(6) LARGE FRAME SUPPORT -(7) TROUBLESHOOTING -(8) HISTORY + 1 Overview + 2 Required Files + 3 Installation + 3.1 Driver Installation + 3.2 Inclusion of adapter at system start + 4 Driver Parameters + 4.1 Per-Port Parameters + 4.2 Adapter Parameters + 5 Large Frame Support + 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) + 7 Troubleshooting + 8 History =========================================================================== -(1) OVERVIEW -============ +1 Overview +=========== -The sk98lin driver supports the SysKonnect SK-NET Gigabit Ethernet -Adapter SK-98xx family on Linux 2.2.x and above. -It has been tested with Linux on Intel/x86 machines. -From v3.02 on, the driver is integrated in the linux kernel source. +The sk98lin driver supports the SysKonnect SK-98xx and SK-95xx family +on Linux. It has been tested with Linux on Intel/x86 machines. *** -(2) REQUIRED FILES -================== +2 Required Files +================= The linux kernel source. No additional files required. *** -(3) INSTALLATION -================ +3 Installation +=============== + +It is recommended to download the latest version of the driver from the +SysKonnect web site www.syskonnect.com. If you have downloaded the latest +driver, the Linux kernel has to be patched before the driver can be +installed. For details on how to patch a Linux kernel, refer to the +patch.txt file. + +3.1 Driver Installation +------------------------ The following steps describe the actions that are required to install the driver and to start it manually. These steps should be carried out for the initial driver setup. Once confirmed to be ok, they can -be included in the system start which is described in the next -chapter. +be included in the system start. -NOTE 1: You must have 'root' access to the system to perform - the following tasks. -NOTE 2: IMPORTANT: In case of problems, please read the section - "Troubleshooting" below. - -1) The driver can either be integrated into the kernel or it can - be compiled as a module. - Select the appropriate option during the kernel configuration. - For use as a module, your kernel must have - 'loadable module support' enabled. - For automatic driver start, you also need 'Kernel module loader' - enabled. - Configure those options, build and install the new kernel. If you - choose to use the driver as a module, do "make modules" and - "make modules_install". - Reboot your system. - -2) Load the module manually by entering: - modprobe sk98lin - If the SysKonnect SK-98xx adapter is installed in your - computer and you have a /proc filesystem, running the command - 'more /proc/net/dev' should produce an output containing a - line with the following format: - eth0: 0 0 ... - which means that your adapter has been found and initialized. +NOTE 1: To perform the following tasks you need 'root' access. + +NOTE 2: In case of problems, please read the section "Troubleshooting" + below. + +The driver can either be integrated into the kernel or it can be compiled +as a module. Select the appropriate option during the kernel +configuration. + +Compile/use the driver as a module +---------------------------------- +To compile the driver, go to the directory /usr/src/linux and +execute the command "make menuconfig" or "make xconfig" and proceed as +follows: + +To integrate the driver permanently into the kernel, proceed as follows: + +1. Select the menu "Network device support" and then "Ethernet(1000Mbit)" +2. Mark "SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter + family support" with (*) +3. Build a new kernel when the configuration of the above options is + finished. +4. Install the new kernel. +5. Reboot your system. + +To use the driver as a module, proceed as follows: + +1. Enable 'loadable module support' in the kernel. +2. For automatic driver start, enable the 'Kernel module loader'. +3. Select the menu "Network device support" and then "Ethernet(1000Mbit)" +4. Mark "SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter + family support" with (M) +5. Execute the command "make modules". +6. Execute the command "make modules_install". + The appropiate modules will be installed. +7. Reboot your system. + + +Load the module manually +------------------------ +To load the module manually, proceed as follows: + +1. Enter "modprobe sk98lin". +2. If the SysKonnect SK-98xx adapter is installed in your computer and you + have a /proc file system, execute the command: + "ls /proc/net/sk98lin/" + This should produce an output containing a line with the following + format: + eth0 eth1 ... + which indicates that your adapter has been found and initialized. - NOTE 1: If you have more than one SysKonnect SK-98xx adapter, the - adapters will be listed as 'eth0', 'eth1', 'eth2', etc. - For each adapter, repeat the steps 3) and 4). - NOTE 2: If you have other Ethernet adapters installed, - your SysKonnect SK-98xx adapter can be mapped to 'eth1' or - 'eth2' ... - The module installation message (in system logfile or - on console, depending on /etc/syslog.conf) prints a line - for each adapter that is found, containing the - corresponding 'ethX'. + NOTE 1: If you have more than one SysKonnect SK-98xx adapter installed, + the adapters will be listed as 'eth0', 'eth1', 'eth2', etc. + For each adapter, repeat steps 3 and 4 below. + + NOTE 2: If you have other Ethernet adapters installed, your SysKonnect + SK-98xx adapter will be mapped to the next available number, + e.g. 'eth1'. The mapping is executed automatically. + The module installation message (displayed either in a system + log file or on the console) prints a line for each adapter + found containing the corresponding 'ethX'. -3) Select an IP address and assign it to the respective adapter by +3. Select an IP address and assign it to the respective adapter by entering: - ifconfig eth0 - This causes the adapter to connect to the ethernet. The solitary - yellow LED at the adapter is now active, the link status LED of - the primary port is on and the link status LED of the secondary - port (on dual port adapters) is blinking (only if the laters are - connected to a switch or hub). - You will also get a status message on the console saying - "ethX: network connection up using port Y" and indicating - the selected connection parameters. + ifconfig eth0 + With this command, the adapter is connected to the Ethernet. + SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter + is now active, the link status LED of the primary port is active and + the link status LED of the secondary port (on dual port adapters) is + blinking (if the ports are connected to a switch or hub). + SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active. + In addition, you will receive a status message on the console stating + "ethX: network connection up using port Y" and showing the selected + connection parameters (x stands for the ethernet device number + (0,1,2, etc), y stands for the port name (A or B)). + NOTE: If you are in doubt about IP addresses, ask your network administrator for assistance. + +4. Your adapter should now be fully operational. + Use 'ping ' to verify the connection to other computers + on your network. +5. To check the adapter configuration view /proc/net/sk98lin/[devicename]. + For example by executing: + "cat /proc/net/sk98lin/eth0" + +Unload the module +----------------- +To stop and unload the driver modules, proceed as follows: -4) Your adapter should now be fully operational. - Use 'ping ' to verify the connection to other - computers on your network. - By viewing /proc/net/sk98lin/[devicename], you can check some - information regarding to the adapter configuration. - - -5) The driver module can be stopped and unloaded using the following - commands: - ifconfig eth0 down - rmmod sk98lin -*** - +1. Execute the command "ifconfig eth0 down". +2. Execute the command "rmmod sk98lin". -(4) INCLUSION OF ADAPTER AT SYSTEM START -======================================== +3.2 Inclusion of adapter at system start +----------------------------------------- Since a large number of different Linux distributions are available, we are unable to describe a general installation procedure @@ -122,41 +160,45 @@ Because the driver is now integrated in the kernel, installation should be easy, using the standard mechanism of your distribution. Refer to the distribution's manual for installation of ethernet adapters. + *** +4 Driver Parameters +==================== -(5) DRIVER PARAMETERS -===================== +Parameters can be set at the command line after the module has been +loaded with the command 'modprobe'. +In some distributions, the configuration tools are able to pass parameters +to the driver module. -Parameters can be set at the command line while loading the -module with 'modprobe'. The configuration tools of some distributions -can also give parameters to the driver module. If you use the kernel module loader, you can set driver parameters in the file /etc/modules.conf (or old name: /etc/conf.modules). -Insert a line of the form: - -options sk98lin ... +To set the driver parameters in this file, proceed as follows: -For "...", use the same syntax as described below for the command -line paramaters of modprobe. -You either have to reboot your computer or unload and reload -the driver to activate the new parameters. -The syntax of the driver parameters is: - -modprobe sk98lin parameter=value1[,value2[,value3...]] - -value1 is for the first adapter, value2 for the second one etc. -All Parameters are case sensitive, so write them exactly as -shown below. - -Sample: Suppose you have two adapters. You want to set AutoNegotiation - on Port A of the first adapter to ON and on Port A of the - second adapter to OFF. - You also want to set DuplexCapabilities on Port A of the first - adapter to FULL and on Port A of the second adapter to HALF. - You must enter: +1. Insert a line of the form : + options sk98lin ... + For "...", the same syntax is required as described for the command + line paramaters of modprobe below. +2. To activate the new parameters, either reboot your computer + or + unload and reload the driver. + The syntax of the driver parameters is: + + modprobe sk98lin parameter=value1[,value2[,value3...]] + + where value1 refers to the first adapter, value2 to the second etc. + +NOTE: All parameters are case sensitive. Write them exactly as shown + below. + +Example: +Suppose you have two adapters. You want to set auto-negotiation +on the first adapter to ON and on the second adapter to OFF. +You also want to set DuplexCapabilities on the first adapter +to FULL, and on the second adapter to HALF. +Then, you must enter: - modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half + modprobe sk98lin AutoNeg=On,Off DupCap=Full,Half NOTE: The number of adapters that can be configured this way is limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM). @@ -164,221 +206,324 @@ more adapters, adjust this and recompile. -5.1 Per-Port Parameters ------------------------ -Those setting are available for each port on the adapter. +4.1 Per-Port Parameters +------------------------ + +These settings are available for each port on the adapter. In the following description, '?' stands for the port for which you set the parameter (A or B). -- Auto Negotiation - Parameter: AutoNeg_? - Values: On, Off, Sense - Default: Sense +Speed +----- +Parameter: Speed_? +Values: 10, 100, 1000, Auto +Default: Auto + +This parameter is used to set the speed capabilities. It is only valid +for the SK-98xx V2.0 copper adapters. +Usually, the speed is negotiated between the two ports during link +establishment. If this fails, a port can be forced to a specific setting +with this parameter. + +Auto-Negotiation +---------------- +Parameter: AutoNeg_? +Values: On, Off, Sense +Default: On - The "Sense"-mode finds out automatically whether the link - partner supports autonegotiation or not. +The "Sense"-mode automatically detects whether the link partner supports +auto-negotiation or not. -- Duplex Capabilities - Parameter: DupCap_? - Values: Half, Full, Both - Default: Both - - This parameters is relevant only if autonegotiation for - this port is not "Sense". If autonegotiation is "On", all - three values are possible. If it is "Off", only "Full" and - "Half" are allowed. - It is usefull if your link partner does not support all - possible combinations. - -- Flow Control - Parameter: FlowCtrl_? - Values: Sym, SymOrRem, LocSend, None - Default: SymOrRem - - This parameter can be used to set the flow control capabilities - that the port reports during autonegotiation. - The meaning of the different modes is: --- Sym = Symetric: both link partners are allowed to send PAUSE frames --- SymOrRem = SymetricOrRemote: both or only remote partner are allowed - to send PAUSE frames --- LocSend = LocalSend: only local link partner is allowed to send - PAUSE frames --- None: no link partner is allowed to send PAUSE frames +Duplex Capabilities +------------------- +Parameter: DupCap_? +Values: Half, Full, Both +Default: Both + +This parameters is only relevant if auto-negotiation for this port is +not set to "Sense". If auto-negotiation is set to "On", all three values +are possible. If it is set to "Off", only "Full" and "Half" are allowed. +This parameter is usefull if your link partner does not support all +possible combinations. + +Flow Control +------------ +Parameter: FlowCtrl_? +Values: Sym, SymOrRem, LocSend, None +Default: SymOrRem + +This parameter can be used to set the flow control capabilities the +port reports during auto-negotiation. It can be set for each port +individually. +Possible modes: + -- Sym = Symetric: both link partners are allowed to send + PAUSE frames + -- SymOrRem = SymetricOrRemote: both or only remote partner + are allowed to send PAUSE frames + -- LocSend = LocalSend: only local link partner is allowed + to send PAUSE frames + -- None = no link partner is allowed to send PAUSE frames - NOTE: This parameter is ignored if autonegotiation is set to "Off". +NOTE: This parameter is ignored if auto-negotiation is set to "Off". -- Role in Master-Slave-Negotiation (1000Base-T only). - Parameter: Role_? - Values: Auto, Master, Slave - Default: Auto - - This parameter is only valid for the SK-9821 and SK-9822 adapters. - For two 1000Base-T ports to communicate, one must take the role as - master (providing timing information), while the other must be slave. - Normally, this is negotiated between the two ports during link - establishment. If this should ever fail, you can force a port to a - specific setting with this parameter. - +Role in Master-Slave-Negotiation (1000Base-T only) +-------------------------------------------------- +Parameter: Role_? +Values: Auto, Master, Slave +Default: Auto + +This parameter is only valid for the SK-9821 and SK-9822 adapters. +For two 1000Base-T ports to communicate, one must take the role of the +master (providing timing information), while the other must be the +slave. Usually, this is negotiated between the two ports during link +establishment. If this fails, a port can be forced to a specific setting +with this parameter. -5.2 Per-Adapter Parameters --------------------------- -- Preferred Port - Parameter: PrefPort - Values: A, B - Default: A - - This is used to force the preferred port to A or B (on two-port NICs). - The preferred port is the one that is used if both are detected as - fully functional. - -- RLMT (Redundant Link Management Technology) Mode - Parameter: RlmtMode - Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet - Default: CheckLinkState - - RLMT (the driver part that decides which port to use) knows three - ways of checking if a port is available for use: - --- CheckLinkState = Check link state only: RLMT uses the link state - reported by the adapter hardware for each individual port to determine - whether a port can be used for all network traffic or not. - --- CheckLocalPort - Check other port on adapter: RLMT sends test frames - from each port to each other port and checks if they are received by - the other port, respectively. Thus, the ports must be connected to the - network such that LLC test frames can be exchanged between them - (i.e. there must be no routers between the ports). - --- CheckSeg - Check other port and segmentation: RLMT checks the other port - and in addition requests information from the Gigabit Ethernet - switch next to each port to see if the network is segmented between - the ports. Thus, this mode is only to be used if you have Gigabit - Ethernet switches installed in your network that have been configured - to use the Spanning Tree protocol. - --- DualNet - Both ports A and B are used as separate devices at the same - time. So if you have a dual port adapter, port A will show up as eth0 - and port B as eth1. Both ports can be used independend with distinct - IP addresses. - The preferred port setting is not used. Rlmt is turned off. - +4.2 Adapter Parameters +----------------------- - NOTE: The modes CheckLocalPort and CheckSeg are meant to operate in - configurations where a network path between the ports on one - adapter exists. Especially, they are not designed to work where - adapters are connected back-to-back. +Preferred Port +-------------- +Parameter: PrefPort +Values: A, B +Default: A + +This is used to force the preferred port to A or B (on dual-port network +adapters). The preferred port is the one that is used if both are detected +as fully functional. + +RLMT Mode (Redundant Link Management Technology) +------------------------------------------------ +Parameter: RlmtMode +Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet +Default: CheckLinkState + +RLMT monitors the status of the port. If the link of the active port +fails, RLMT switches immediately to the standby link. The virtual link is +maintained as long as at least one 'physical' link is up. + +Possible modes: + + -- CheckLinkState - Check link state only: RLMT uses the link state + reported by the adapter hardware for each individual port to + determine whether a port can be used for all network traffic or + not. + + -- CheckLocalPort - In this mode, RLMT monitors the network path + between the two ports of an adapter by regularly exchanging packets + between them. This mode requires a network configuration in which + the two ports are able to "see" each other (i.e. there must not be + any router between the ports). + + -- CheckSeg - Check local port and segmentation: This mode supports the + same functions as the CheckLocalPort mode and additionally checks + network segmentation between the ports. Therefore, this mode is only + to be used if Gigabit Ethernet switches are installed on the network + that have been configured to use the Spanning Tree protocol. + + -- DualNet - In this mode, ports A and B are used as separate devices. + If you have a dual port adapter, port A will be configured as eth0 + and port B as eth1. Both ports can be used independently with + distinct IP addresses. The preferred port setting is not used. + RLMT is turned off. + +NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations + where a network path between the ports on one adapter exists. + Moreover, they are not designed to work where adapters are connected + back-to-back. *** -(6) LARGE FRAME SUPPORT -======================= +5 Large Frame Support +====================== -Large frames (also called jumbo frames) are now supported by the -driver. This can result in a greatly improved throughput if -transfering large amounts of data. -To enable large frames, set the MTU (maximum transfer unit) -of the interface to the value you wish (up to 9000). The command -for this is: - ifconfig eth0 mtu 9000 +The driver supports large frames (also called jumbo frames). Using large +frames can result in an improved throughput if transferring large amounts +of data. +To enable large frames, set the MTU (maximum transfer unit) of the +interface to the desired value (up to 9000), execute the following +command: + ifconfig eth0 mtu 9000 This will only work if you have two adapters connected back-to-back -or if you use a switch that supports large frames. When using a -switch, it should be configured to allow large frames, without -autonegotiating for them. -The setting must be done on all adapters that can be reached by -the large frames. If one adapter is not set to receive large frames, -it will simply drop them. +or if you use a switch that supports large frames. When using a switch, +it should be configured to allow large frames and auto-negotiation should +be set to OFF. The setting must be configured on all adapters that can be +reached by the large frames. If one adapter is not set to receive large +frames, it will simply drop them. + +You can switch back to the standard ethernet frame size by executing the +following command: + ifconfig eth0 mtu 1500 -You can switch back to the standard ethernet frame size with: - ifconfig eth0 mtu 1500 - -To make this setting persitent, add a script with the 'ifconfig' -line to the system startup sequence (named something like "S99sk98lin" +To permanently configure this setting, add a script with the 'ifconfig' +line to the system startup sequence (named something like "S99sk98lin" in /etc/rc.d/rc2.d). *** -(7) TROUBLESHOOTING -=================== +6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) +================================================================== + +The SysKonnect Linux drivers are able to support VLAN and Link Aggregation +according to IEEE standards 802.1, 802.1q, and 802.3ad. These features are +only available after installation of open source modules available on the +Internet: +For VLAN go to: http://scry.wanfear.com/~greear/vlan.html +For Link Aggregation go to: http://www.st.rim.or.jp/~yumo + +NOTE: SysKonnect GmbH does not offer any support for these open source + modules and does not take the responsibility for any kind of + failures or problems arising in connection with these modules. + +NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may + cause problems when unloading the driver. + + +7 Troubleshooting +================== + +If any problems occur during the installation process, check the +following list: -If you run into problems during installation, check those items: Problem: The SK-98xx adapter can not be found by the driver. -Reason: Look in /proc/pci for the following entry: +Solution: In /proc/pci search for the following entry: 'Ethernet controller: SysKonnect SK-98xx ...' - If this entry exists, then the SK-98xx adapter has been - found by the system and should be able to be used. - If this entry does not exist or if the file '/proc/pci' - is not there, then you may have a hardware problem or PCI - support may not be enabled in your kernel. - The adapter can be checked using the diagnostic program - which is available from the SysKonnect web site: - www.syskonnect.de - Some COMPAQ machines have a problem with PCI under - Linux. This is described in the 'PCI howto' document - (included in some distributions or available from the - www, e.g. at 'www.linux.org'). This might be fixed in the - 2.2.x kernel series (I've not tested it). - -Problem: Programs such as 'ifconfig' or 'route' can not be found or - you get an error message 'Operation not permitted'. -Reason: You are not logged in as user 'root'. Logout and - login as root or change to root via 'su'. - -Problem: Using the command 'ping
', you get a message - "ping: sendto: Network is unreachable". -Reason: Your route is not set up correct. - If you are using RedHat, you probably forgot - to set up the route in 'network configuration'. - Check the existing routes with the 'route' command - and check if there is an entry for 'eth0' and if - it is correct. - -Problem: The driver can be started, the adapter is connected - to the network, but you can not receive or transmit - any packet; e.g. 'ping' does not work. -Reason: You have an incorrect route in your routing table. - Check the routing table with the command 'route' and - read the manual pages about route ('man route'). -NOTE: Although the 2.2.x kernel versions generate the routing - entry automatically, you may have problems of this kind - here, too. We found a case where the driver started correct - at system boot, but after removing and reloading the driver, - the route of the adapter's network pointed to the 'dummy0' - device and had to be corrected manually. - -Problem: You want to use your computer as a router between - multiple IP subnetworks (using multiple adapters), but - you can not reach computers in other subnetworks. -Reason: Either the router's kernel is not configured for IP - forwarding or there is a problem with the routing table - and gateway configuration in at least one of the - computers. - -Problem: At the start of the driver, you get an error message: - "eth0: -- ERROR -- - Class: internal Software error - Nr: 0xcc - Msg: SkGeInitPort() cannot init running ports" -Reason: You are using a driver compiled for single processor - machines on an multiprocessor machine with SMP (Symetric - MultiProcessor) kernel. - Configure your kernel appropriate and recompile the kernel or - the modules. + If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has + been found by the system and should be operational. + If this entry does not exist or if the file '/proc/pci' is not + found, there may be a hardware problem or the PCI support may + not be enabled in your kernel. + The adapter can be checked using the diagnostics program which + is available on the SysKonnect web site: + www.syskonnect.com + + Some COMPAQ machines have problems dealing with PCI under Linux. + Linux. This problem is described in the 'PCI howto' document + (included in some distributions or available from the + web, e.g. at 'www.linux.org'). + + +Problem: Programs such as 'ifconfig' or 'route' can not be found or the + error message 'Operation not permitted' is displayed. +Reason: You are not logged in as user 'root'. +Solution: Logout and login as 'root' or change to 'root' via 'su'. + + +Problem: Upon use of the command 'ping
' the message + "ping: sendto: Network is unreachable" is displayed. +Reason: Your route is not set correctly. +Solution: If you are using RedHat, you probably forgot to set up the + route in the 'network configuration'. + Check the existing routes with the 'route' command and check + if an entry for 'eth0' exists, and if so, if it is set correctly. + + +Problem: The driver can be started, the adapter is connected to the + network, but you cannot receive or transmit any packets; + e.g. 'ping' does not work. +Reason: There is an incorrect route in your routing table. +Solution: Check the routing table with the command 'route' and read the + manual help pages dealing with routes (enter 'man route'). + +NOTE: Although the 2.2.x kernel versions generate the routing entry + automatically, problems of this kind may occur here as well. We've + come across a situation in which the driver started correctly at + system start, but after the driver has been removed and reloaded, + the route of the adapter's network pointed to the 'dummy0'device + and had to be corrected manually. + + +Problem: Your computer should act as a router between multiple + IP subnetworks (using multiple adapters), but computers in + other subnetworks cannot be reached. +Reason: Either the router's kernel is not configured for IP forwarding + or the routing table and gateway configuration of at least one + computer is not working. + +Problem: Upon driver start, the following error message is displayed: + "eth0: -- ERROR -- + Class: internal Software error + Nr: 0xcc + Msg: SkGeInitPort() cannot init running ports" +Reason: You are using a driver compiled for single processor machines + on a multiprocessor machine with SMP (Symetric MultiProcessor) + kernel. +Solution: Configure your kernel appropriately and recompile the kernel or + the modules. + + If your problem is not listed here, please contact SysKonnect's technical support for help (linux@syskonnect.de). -When contacting our technical support, please ensure that the -following information is available: +When contacting our technical support, please ensure that the following +information is available: - System Manufacturer and Model - Boards in your system - Distribution - Kernel version +- Driver version *** +8 History +========== -(8) HISTORY -=========== +VERSION 6.00 (In-Kernel version) +New Features: +- Support for SK-98xx V2.0 adapters +- Support for gmac +- Support for kernel 2.4.x and kernel 2.2.x +- Zerocopy support for kernel 2.4.x with sendfile() +- Support for scatter-gather functionality with sendfile() +- Speed support for SK-98xx V2.0 adapters +- New ProcFs entries +- New module parameters +Problems fixed: +- ProcFS initialization +- csum packet error +- Ierror/crc counter error (#10767) +- rx_too_long counter error (#10751) +Known limitations: +- None + +VERSION 4.11 +New Features: +- none +Problems fixed: +- Error statistic counter fix (#10620) +- RLMT-Fixes (#10659, #10639, #10650) +- LM80 sensor initialization fix (#10623) +- SK-CSUM memory fixes (#10610). +Known limitations: +- None + +VERSION 4.10 +New Features: +- New ProcFs entries +Problems fixed: +- Corrected some printk's +Known limitations: +- None + +VERSION 4.09 +New Features: +- IFF_RUNNING support (link status) +- New ProcFs entries +Problems fixed: +- too long counters +- too short counters +- Kernel error compilation +Known limitations: +- None + +VERSION 4.06 (In-Kernel version) +Problems fixed: +- MTU init problems + +VERSION 4.04 +Problems fixed: +- removed VLAN error messages VERSION 4.02 (In-Kernel version) New Features: @@ -518,3 +663,4 @@ ***End of Readme File*** + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/sched-coding.txt linux.21pre4-ac6/Documentation/sched-coding.txt --- linux.21pre4/Documentation/sched-coding.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/Documentation/sched-coding.txt 2003-01-06 19:13:57.000000000 +0000 @@ -0,0 +1,129 @@ + Reference for various scheduler-related methods in the O(1) scheduler + Robert Love , MontaVista Software + + +Note most of these methods are local to kernel/sched.c - this is by design. +The scheduler is meant to be self-contained and abstracted away. This document +is primarily for understanding the scheduler, not interfacing to it. Some of +the discussed interfaces, however, are general process/scheduling methods. +They are typically defined in include/linux/sched.h. + + +Main Scheduling Methods +----------------------- + +void load_balance(runqueue_t *this_rq, int idle) + Attempts to pull tasks from one cpu to another to balance cpu usage, + if needed. This method is called explicitly if the runqueues are + inbalanced or periodically by the timer tick. Prior to calling, + the current runqueue must be locked and interrupts disabled. + +void schedule() + The main scheduling function. Upon return, the highest priority + process will be active. + + +Locking +------- + +Each runqueue has its own lock, rq->lock. When multiple runqueues need +to be locked, lock acquires must be ordered by ascending &runqueue value. + +A specific runqueue is locked via + + task_rq_lock(task_t pid, unsigned long *flags) + +which disables preemption, disables interrupts, and locks the runqueue pid is +running on. Likewise, + + task_rq_unlock(task_t pid, unsigned long *flags) + +unlocks the runqueue pid is running on, restores interrupts to their previous +state, and reenables preemption. + +The routines + + double_rq_lock(runqueue_t *rq1, runqueue_t *rq2) + +and + + double_rq_unlock(runqueue_t *rq1, runqueue_t rq2) + +safely lock and unlock, respectively, the two specified runqueues. They do +not, however, disable and restore interrupts. Users are required to do so +manually before and after calls. + + +Values +------ + +MAX_PRIO + The maximum priority of the system, stored in the task as task->prio. + Lower priorities are higher. Normal (non-RT) priorities range from + MAX_RT_PRIO to (MAX_PRIO - 1). +MAX_RT_PRIO + The maximum real-time priority of the system. Valid RT priorities + range from 0 to (MAX_RT_PRIO - 1). +MAX_USER_RT_PRIO + The maximum real-time priority that is exported to user-space. Should + always be equal to or less than MAX_RT_PRIO. Setting it less allows + kernel threads to have higher priorities than any user-space task. +MIN_TIMESLICE +MAX_TIMESLICE + Respectively, the minimum and maximum timeslices (quanta) of a process. + +Data +---- + +struct runqueue + The main per-CPU runqueue data structure. +struct task_struct + The main per-process data structure. + + +General Methods +--------------- + +cpu_rq(cpu) + Returns the runqueue of the specified cpu. +this_rq() + Returns the runqueue of the current cpu. +task_rq(task) + Returns the runqueue which holds the specified task. +cpu_curr(cpu) + Returns the task currently running on the given cpu. +rt_task(task) + Returns true if task is real-time, false if not. +task_cpu(task) + + +Process Control Methods +----------------------- + +void set_user_nice(task_t *p, long nice) + Sets the "nice" value of task p to the given value. +int setscheduler(pid_t pid, int policy, struct sched_param *param) + Sets the scheduling policy and parameters for the given pid. +void set_cpus_allowed(task_t *p, unsigned long new_mask) + Sets a given task's CPU affinity and migrates it to a proper cpu. + Callers must have a valid reference to the task and assure the + task not exit prematurely. No locks can be held during the call. +set_task_state(tsk, state_value) + Sets the given task's state to the given value. +set_current_state(state_value) + Sets the current task's state to the given value. +void set_tsk_need_resched(struct task_struct *tsk) + Sets need_resched in the given task. +void clear_tsk_need_resched(struct task_struct *tsk) + Clears need_resched in the given task. +void set_need_resched() + Sets need_resched in the current task. +void set_task_cpu(task, cpu) + Sets task->cpu to cpu on SMP. Noop on UP. +void clear_need_resched() + Clears need_resched in the current task. +int need_resched() + Returns true if need_resched is set in the current task, false + otherwise. +yield() + Place the current process at the end of the runqueue and call schedule. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/sched-design.txt linux.21pre4-ac6/Documentation/sched-design.txt --- linux.21pre4/Documentation/sched-design.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/Documentation/sched-design.txt 2003-01-06 19:13:57.000000000 +0000 @@ -0,0 +1,165 @@ + Goals, Design and Implementation of the + new ultra-scalable O(1) scheduler + + + This is an edited version of an email Ingo Molnar sent to + lkml on 4 Jan 2002. It describes the goals, design, and + implementation of Ingo's new ultra-scalable O(1) scheduler. + Last Updated: 18 April 2002. + + +Goal +==== + +The main goal of the new scheduler is to keep all the good things we know +and love about the current Linux scheduler: + + - good interactive performance even during high load: if the user + types or clicks then the system must react instantly and must execute + the user tasks smoothly, even during considerable background load. + + - good scheduling/wakeup performance with 1-2 runnable processes. + + - fairness: no process should stay without any timeslice for any + unreasonable amount of time. No process should get an unjustly high + amount of CPU time. + + - priorities: less important tasks can be started with lower priority, + more important tasks with higher priority. + + - SMP efficiency: no CPU should stay idle if there is work to do. + + - SMP affinity: processes which run on one CPU should stay affine to + that CPU. Processes should not bounce between CPUs too frequently. + + - plus additional scheduler features: RT scheduling, CPU binding. + +and the goal is also to add a few new things: + + - fully O(1) scheduling. Are you tired of the recalculation loop + blowing the L1 cache away every now and then? Do you think the goodness + loop is taking a bit too long to finish if there are lots of runnable + processes? This new scheduler takes no prisoners: wakeup(), schedule(), + the timer interrupt are all O(1) algorithms. There is no recalculation + loop. There is no goodness loop either. + + - 'perfect' SMP scalability. With the new scheduler there is no 'big' + runqueue_lock anymore - it's all per-CPU runqueues and locks - two + tasks on two separate CPUs can wake up, schedule and context-switch + completely in parallel, without any interlocking. All + scheduling-relevant data is structured for maximum scalability. + + - better SMP affinity. The old scheduler has a particular weakness that + causes the random bouncing of tasks between CPUs if/when higher + priority/interactive tasks, this was observed and reported by many + people. The reason is that the timeslice recalculation loop first needs + every currently running task to consume its timeslice. But when this + happens on eg. an 8-way system, then this property starves an + increasing number of CPUs from executing any process. Once the last + task that has a timeslice left has finished using up that timeslice, + the recalculation loop is triggered and other CPUs can start executing + tasks again - after having idled around for a number of timer ticks. + The more CPUs, the worse this effect. + + Furthermore, this same effect causes the bouncing effect as well: + whenever there is such a 'timeslice squeeze' of the global runqueue, + idle processors start executing tasks which are not affine to that CPU. + (because the affine tasks have finished off their timeslices already.) + + The new scheduler solves this problem by distributing timeslices on a + per-CPU basis, without having any global synchronization or + recalculation. + + - batch scheduling. A significant proportion of computing-intensive tasks + benefit from batch-scheduling, where timeslices are long and processes + are roundrobin scheduled. The new scheduler does such batch-scheduling + of the lowest priority tasks - so nice +19 jobs will get + 'batch-scheduled' automatically. With this scheduler, nice +19 jobs are + in essence SCHED_IDLE, from an interactiveness point of view. + + - handle extreme loads more smoothly, without breakdown and scheduling + storms. + + - O(1) RT scheduling. For those RT folks who are paranoid about the + O(nr_running) property of the goodness loop and the recalculation loop. + + - run fork()ed children before the parent. Andrea has pointed out the + advantages of this a few months ago, but patches for this feature + do not work with the old scheduler as well as they should, + because idle processes often steal the new child before the fork()ing + CPU gets to execute it. + + +Design +====== + +the core of the new scheduler are the following mechanizms: + + - *two*, priority-ordered 'priority arrays' per CPU. There is an 'active' + array and an 'expired' array. The active array contains all tasks that + are affine to this CPU and have timeslices left. The expired array + contains all tasks which have used up their timeslices - but this array + is kept sorted as well. The active and expired array is not accessed + directly, it's accessed through two pointers in the per-CPU runqueue + structure. If all active tasks are used up then we 'switch' the two + pointers and from now on the ready-to-go (former-) expired array is the + active array - and the empty active array serves as the new collector + for expired tasks. + + - there is a 64-bit bitmap cache for array indices. Finding the highest + priority task is thus a matter of two x86 BSFL bit-search instructions. + +the split-array solution enables us to have an arbitrary number of active +and expired tasks, and the recalculation of timeslices can be done +immediately when the timeslice expires. Because the arrays are always +access through the pointers in the runqueue, switching the two arrays can +be done very quickly. + +this is a hybride priority-list approach coupled with roundrobin +scheduling and the array-switch method of distributing timeslices. + + - there is a per-task 'load estimator'. + +one of the toughest things to get right is good interactive feel during +heavy system load. While playing with various scheduler variants i found +that the best interactive feel is achieved not by 'boosting' interactive +tasks, but by 'punishing' tasks that want to use more CPU time than there +is available. This method is also much easier to do in an O(1) fashion. + +to establish the actual 'load' the task contributes to the system, a +complex-looking but pretty accurate method is used: there is a 4-entry +'history' ringbuffer of the task's activities during the last 4 seconds. +This ringbuffer is operated without much overhead. The entries tell the +scheduler a pretty accurate load-history of the task: has it used up more +CPU time or less during the past N seconds. [the size '4' and the interval +of 4x 1 seconds was found by lots of experimentation - this part is +flexible and can be changed in both directions.] + +the penalty a task gets for generating more load than the CPU can handle +is a priority decrease - there is a maximum amount to this penalty +relative to their static priority, so even fully CPU-bound tasks will +observe each other's priorities, and will share the CPU accordingly. + +the SMP load-balancer can be extended/switched with additional parallel +computing and cache hierarchy concepts: NUMA scheduling, multi-core CPUs +can be supported easily by changing the load-balancer. Right now it's +tuned for my SMP systems. + +i skipped the prev->mm == next->mm advantage - no workload i know of shows +any sensitivity to this. It can be added back by sacrificing O(1) +schedule() [the current and one-lower priority list can be searched for a +that->mm == current->mm condition], but costs a fair number of cycles +during a number of important workloads, so i wanted to avoid this as much +as possible. + +- the SMP idle-task startup code was still racy and the new scheduler +triggered this. So i streamlined the idle-setup code a bit. We do not call +into schedule() before all processors have started up fully and all idle +threads are in place. + +- the patch also cleans up a number of aspects of sched.c - moves code +into other areas of the kernel where it's appropriate, and simplifies +certain code paths and data constructs. As a result, the new scheduler's +code is smaller than the old one. + + Ingo diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/sonypi.txt linux.21pre4-ac6/Documentation/sonypi.txt --- linux.21pre4/Documentation/sonypi.txt 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/Documentation/sonypi.txt 2003-02-24 00:00:39.000000000 +0000 @@ -1,6 +1,6 @@ Sony Programmable I/O Control Device Driver Readme -------------------------------------------------- - Copyright (C) 2001-2002 Stelian Pop + Copyright (C) 2001-2003 Stelian Pop Copyright (C) 2001-2002 Alcôve Copyright (C) 2001 Michael Ashley Copyright (C) 2001 Junichi Morita @@ -44,7 +44,7 @@ to /etc/modules.conf file, when the driver is compiled as a module or by adding the following to the kernel command line (in your bootloader): - sonypi=minor[,verbose[,fnkeyinit[,camera[,compat[,mask]]]]] + sonypi=minor[,verbose[,fnkeyinit[,camera[,compat[,mask[,useinput]]]]]] where: @@ -97,6 +97,11 @@ SONYPI_MEYE_MASK 0x0400 SONYPI_MEMORYSTICK_MASK 0x0800 + useinput: if set (which is the default) jogdial events are + forwarded to the input subsystem as mouse wheel + events. + + Module use: ----------- diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/usb/auerswald.txt linux.21pre4-ac6/Documentation/usb/auerswald.txt --- linux.21pre4/Documentation/usb/auerswald.txt 2003-01-29 16:27:25.000000000 +0000 +++ linux.21pre4-ac6/Documentation/usb/auerswald.txt 2003-02-21 15:46:06.000000000 +0000 @@ -23,8 +23,15 @@ ... mknod -m 666 /dev/usb/auer15 c 180 127 -Future plans +ISDN support ============ -- Connection to ISDN4LINUX (the hisax interface) +If you enable CONFIG_USB_AUERISDN, you will get full +ISDN modem support via the HISAX ISDN4LINUX driver. + +Of course, as for every USB-based ISDN adaptor, you +will have to modify your hotplug scripts to load +the isdn subsystem and configure the network interfaces. +Same procedure as for the ST5481 driver. + The maintainer of this driver is wolfgang@iksw-muees.de diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/usb/ehci.txt linux.21pre4-ac6/Documentation/usb/ehci.txt --- linux.21pre4/Documentation/usb/ehci.txt 2003-01-29 16:27:25.000000000 +0000 +++ linux.21pre4-ac6/Documentation/usb/ehci.txt 2003-02-04 15:00:43.000000000 +0000 @@ -1,4 +1,4 @@ -26-Apr-2002 +27-Dec-2002 The EHCI driver is used to talk to high speed USB 2.0 devices using USB 2.0-capable host controller hardware. The USB 2.0 standard is @@ -21,11 +21,15 @@ At this writing, this driver has been seen to work with implementations of EHCI from (in alphabetical order): Intel, NEC, Philips, and VIA. +Other EHCI implementations are becoming available from other vendors; +you should expect this driver to work with them too. -At this writing, high speed devices are finally beginning to appear. -While usb-storage devices have been available for some time (working +While usb-storage devices have been available since mid-2001 (working quite speedily on the 2.4 version of this driver), hubs have only -very recently become available. +been available since late 2001, and other kinds of high speed devices +appear to be on hold until more systems come with USB 2.0 built-in. +Such new systems have been available since early 2002, and became much +more typical in the second half of 2002. Note that USB 2.0 support involves more than just EHCI. It requires other changes to the Linux-USB core APIs, including the hub driver, @@ -43,26 +47,29 @@ It's believed to do all the right PCI magic so that I/O works even on systems with interesting DMA mapping issues. -At this writing the driver should comfortably handle all control and bulk -transfers, including requests to USB 1.1 devices through transaction -translators (TTs) in USB 2.0 hubs. However, there some situations where -the hub driver needs to clear TT error state, which it doesn't yet do. - -Interrupt transfer support is newly functional and not yet as robust as -control and bulk traffic. As yet there is no support for split transaction -scheduling for interrupt transfers, which means among other things that -connecting USB 1.1 hubs, keyboards, and mice to USB 2.0 hubs won't work. -Connect them to USB 1.1 hubs, or to a root hub. - -Isochronous (ISO) transfer support is also newly functional. No production -high speed devices are available which would need it (though high quality -webcams are in the works!). Note that split transaction support for ISO +Transfer Types + +At this writing the driver should comfortably handle all control, bulk, +and interrupt transfers, including requests to USB 1.1 devices through +transaction translators (TTs) in USB 2.0 hubs. But you may find bugs. + +High Speed Isochronous (ISO) transfer support is also functional, but +at this writing no Linux drivers have been using that support. + +Full Speed Isochronous transfer support, through transaction translators, +is not yet available. Note that split transaction support for ISO transfers can't share much code with the code for high speed ISO transfers, since EHCI represents these with a different data structure. So for now, -most USB audio and video devices have the same restrictions as hubs, mice, -and keyboards: don't connect them using high speed USB hubs. +most USB audio and video devices can't be connected to high speed buses. + +Driver Behavior -The EHCI root hub code should hand off USB 1.1 devices to its companion +Transfers of all types can be queued. This means that control transfers +from a driver on one interface (or through usbfs) won't interfere with +ones from another driver, and that interrupt transfers can use periods +of one frame without risking data loss due to interrupt processing costs. + +The EHCI root hub code hands off USB 1.1 devices to its companion controller. This driver doesn't need to know anything about those drivers; a OHCI or UHCI driver that works already doesn't need to change just because the EHCI driver is also present. @@ -70,6 +77,11 @@ There are some issues with power management; suspend/resume doesn't behave quite right at the moment. +Also, some shortcuts have been taken with the scheduling periodic +transactions (interrupt and isochronous transfers). These place some +limits on the number of periodic transactions that can be scheduled, +and prevent use of polling intervals of less than one frame. + USE BY @@ -83,10 +95,10 @@ # rmmod ehci-hcd You should also have a driver for a "companion controller", such as -"ohci-hcd", "usb-ohci", "usb-uhci", or "uhci". In case of any trouble -with the EHCI driver, remove its module and then the driver for that -companion controller will take over (at lower speed) all the devices -that were previously handled by the EHCI driver. +"ohci-hcd" or "uhci-hcd". In case of any trouble with the EHCI driver, +remove its module and then the driver for that companion controller will +take over (at lower speed) all the devices that were previously handled +by the EHCI driver. Module parameters (pass to "modprobe") include: @@ -96,9 +108,20 @@ is 6, indicating 2^6 = 64 microframes. This controls how often the EHCI controller can issue interrupts. -The EHCI interrupt handler just acknowledges interrupts and schedules -a tasklet to handle whatever needs handling. That keeps latencies low, -no matter how often interrupts are issued. +If you're using this driver on a 2.5 kernel, and you've enabled USB +debugging support, you'll see three files in the "sysfs" directory for +any EHCI controller: + + "async" dumps the asynchronous schedule, used for control + and bulk transfers. Shows each active qh and the qtds + pending, usually one qtd per urb. (Look at it with + usb-storage doing disk I/O; watch the request queues!) + "periodic" dumps the periodic schedule, used for interrupt + and isochronous transfers. Doesn't show qtds. + "registers" show controller register state, and + +The contents of those files can help identify driver problems. + Device drivers shouldn't care whether they're running over EHCI or not, but they may want to check for "usb_device->speed == USB_SPEED_HIGH". @@ -107,6 +130,11 @@ Also, some values in device descriptors (such as polling intervals for periodic transfers) use different encodings when operating at high speed. +However, do make a point of testing device drivers through USB 2.0 hubs. +Those hubs report some failures, such as disconnections, differently when +transaction translators are in use; some drivers have been seen to behave +badly when they see different faults than OHCI or UHCI report. + PERFORMANCE @@ -122,13 +150,18 @@ and at most 13 of those fit into one USB 2.0 microframe. Eight USB 2.0 microframes fit in a USB 1.1 frame; a microframe is 1 msec/8 = 125 usec. +So more than 50 MByte/sec is available for bulk transfers, when both +hardware and device driver software allow it. Periodic transfer modes +(isochronous and interrupt) allow the larger packet sizes which let you +approach the quoted 480 MBit/sec transfer rate. + Hardware Performance At this writing, individual USB 2.0 devices tend to max out at around 20 MByte/sec transfer rates. This is of course subject to change; and some devices now go faster, while others go slower. -The NEC implementation of EHCI seems to have a hardware bottleneck +The first NEC implementation of EHCI seems to have a hardware bottleneck at around 28 MByte/sec aggregate transfer rate. While this is clearly enough for a single device at 20 MByte/sec, putting three such devices onto one bus does not get you 60 MByte/sec. The issue appears to be @@ -136,9 +169,11 @@ so that it's only trying six (or maybe seven) USB transactions each microframe rather than thirteen. (Seems like a reasonable trade off for a product that beat all the others to market by over a year!) + It's expected that newer implementations will better this, throwing more silicon real estate at the problem so that new motherboard chip -sets will get closer to that 60 MByte/sec target. +sets will get closer to that 60 MByte/sec target. That includes an +updated implementation from NEC, as well as other vendors' silicon. There's a minimum latency of one microframe (125 usec) for the host to receive interrupts from the EHCI controller indicating completion @@ -161,10 +196,16 @@ sequence of 128 KB chunks would waste a lot less. But rather than depending on such large I/O buffers to make synchronous -I/O be efficient, it's better to just queue all several (bulk) requests +I/O be efficient, it's better to just queue up several (bulk) requests to the HC, and wait for them all to complete (or be canceled on error). Such URB queuing should work with all the USB 1.1 HC drivers too. +In the Linux 2.5 kernels, new usb_sg_*() api calls have been defined; they +queue all the buffers from a scatterlist. They also use scatterlist DMA +mapping (which might apply an IOMMU) and IRQ reduction, all of which will +help make high speed transfers run as fast as they can. + + TBD: Interrupt and ISO transfer performance issues. Those periodic transfers are fully scheduled, so the main issue is likely to be how to trigger "high bandwidth" modes. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/video4linux/meye.txt linux.21pre4-ac6/Documentation/video4linux/meye.txt --- linux.21pre4/Documentation/video4linux/meye.txt 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/Documentation/video4linux/meye.txt 2003-02-24 00:01:05.000000000 +0000 @@ -1,6 +1,6 @@ Vaio Picturebook Motion Eye Camera Driver Readme ------------------------------------------------ - Copyright (C) 2001-2002 Stelian Pop + Copyright (C) 2001-2003 Stelian Pop Copyright (C) 2001-2002 Alcôve Copyright (C) 2000 Andrew Tridgell diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/Documentation/vm/overcommit-accounting linux.21pre4-ac6/Documentation/vm/overcommit-accounting --- linux.21pre4/Documentation/vm/overcommit-accounting 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/Documentation/vm/overcommit-accounting 2003-01-06 15:38:40.000000000 +0000 @@ -0,0 +1,70 @@ +* This describes the overcommit management facility in the latest kernel + tree (FIXME: actually it also describes the stuff that isnt yet done) + +The Linux kernel supports four overcommit handling modes + +0 - Heuristic overcommit handling. Obvious overcommits of + address space are refused. Used for a typical system. It + ensures a seriously wild allocation fails while allowing + overcommit to reduce swap usage + +1 - No overcommit handling. Appropriate for some scientific + applications + +2 - (NEW) strict overcommit. The total address space commit + for the system is not permitted to exceed swap + half ram. + In almost all situations this means a process will not be + killed while accessing pages but only by malloc failures + that are reported back by the kernel mmap/brk code. + +3 - (NEW) paranoid overcommit The total address space commit + for the system is not permitted to exceed swap. The machine + will never kill a process accessing pages it has mapped + except due to a bug (ie report it!) + +Gotchas +------- + +The C language stack growth does an implicit mremap. If you want absolute +guarantees and run close to the edge you MUST mmap your stack for the +largest size you think you will need. For typical stack usage is does +not matter much but its a corner case if you really really care + +In modes 2 and 3 the MAP_NORESERVE flag is ignored. + + +How It Works +------------ + +The overcommit is based on the following rules + +For a file backed map + SHARED or READ-only - 0 cost (the file is the map not swap) + PRIVATE WRITABLE - size of mapping per instance + +For an anonymous or /dev/zero map + SHARED - size of mapping + PRIVATE READ-only - 0 cost (but of little use) + PRIVATE WRITABLE - size of mapping per instance + +Additional accounting + Pages made writable copies by mmap + shmfs memory drawn from the same pool + +Status +------ + +o We account mmap memory mappings +o We account mprotect changes in commit +o We account mremap changes in size +o We account brk +o We account munmap +o We report the commit status in /proc +o Account and check on fork +o Review stack handling/building on exec +o SHMfs accounting +o Implement actual limit enforcement + +To Do +----- +o Account ptrace pages (this is hard) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/atm/atmdev_init.c linux.21pre4-ac6/drivers/atm/atmdev_init.c --- linux.21pre4/drivers/atm/atmdev_init.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/atm/atmdev_init.c 2003-01-10 16:19:21.000000000 +0000 @@ -19,9 +19,6 @@ #ifdef CONFIG_ATM_HORIZON extern int hrz_detect(void); #endif -#ifdef CONFIG_ATM_IA -extern int ia_detect(void); -#endif #ifdef CONFIG_ATM_FORE200E extern int fore200e_detect(void); #endif @@ -53,9 +50,6 @@ #ifdef CONFIG_ATM_HORIZON devs += hrz_detect(); #endif -#ifdef CONFIG_ATM_IA - devs += ia_detect(); -#endif #ifdef CONFIG_ATM_FORE200E devs += fore200e_detect(); #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/atm/iphase.c linux.21pre4-ac6/drivers/atm/iphase.c --- linux.21pre4/drivers/atm/iphase.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/atm/iphase.c 2003-02-06 16:04:53.000000000 +0000 @@ -1889,7 +1889,7 @@ return -EINVAL; } if (vcc->qos.txtp.max_pcr > iadev->LineRate) { - IF_CBR(printk("PCR is not availble\n");) + IF_CBR(printk("PCR is not available\n");) return -1; } vc->type = CBR; @@ -1899,7 +1899,7 @@ } } else - printk("iadev: Non UBR, ABR and CBR traffic not supportedn"); + printk("iadev: Non UBR, ABR and CBR traffic not supported\n"); iadev->testTable[vcc->vci]->vc_status |= VC_ACTIVE; IF_EVENT(printk("ia open_tx returning \n");) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/cdrom/cdu31a.c linux.21pre4-ac6/drivers/cdrom/cdu31a.c --- linux.21pre4/drivers/cdrom/cdu31a.c 2003-01-29 16:26:55.000000000 +0000 +++ linux.21pre4-ac6/drivers/cdrom/cdu31a.c 2003-02-07 15:19:15.000000000 +0000 @@ -1361,6 +1361,8 @@ res_reg[0] = 0; res_reg[1] = 0; *res_size = 0; + /* Make sure that bytesleft doesn't exceed the buffer size */ + if (nblocks > 4) nblocks = 4; bytesleft = nblocks * 512; offset = 0; @@ -1384,9 +1386,9 @@ readahead_buffer + (2048 - readahead_dataleft), readahead_dataleft); - readahead_dataleft = 0; bytesleft -= readahead_dataleft; offset += readahead_dataleft; + readahead_dataleft = 0; } else { /* The readahead will fill the whole buffer, get the data and return. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/agp/agpgart_be.c linux.21pre4-ac6/drivers/char/agp/agpgart_be.c --- linux.21pre4/drivers/char/agp/agpgart_be.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/agp/agpgart_be.c 2003-01-06 18:22:56.000000000 +0000 @@ -577,7 +577,7 @@ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) SetPageReserved(page); - agp_bridge.gatt_table_real = (unsigned long *) table; + agp_bridge.gatt_table_real = (u32 *) table; agp_gatt_table = (void *)table; #ifdef CONFIG_X86 err = change_page_attr(virt_to_page(table), 1< - + (c) Copyright 2002,2003 Andi Kleen, SuSE Labs + derived from Hardware driver for Intel i810 Random Number Generator (RNG) @@ -238,13 +239,14 @@ */ static struct pci_device_id rng_pci_tbl[] __initdata = { { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, }, + { 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, }; MODULE_DEVICE_TABLE (pci, rng_pci_tbl); -MODULE_AUTHOR("Alan Cox, Jeff Garzik, Philipp Rumpf, Matt Sottek"); -MODULE_DESCRIPTION("AMD 768 Random Number Generator (RNG) driver"); +MODULE_AUTHOR("Alan Cox, Jeff Garzik, Philipp Rumpf, Matt Sottek, Andi Kleen"); +MODULE_DESCRIPTION("AMD 768/8111 Random Number Generator (RNG) driver"); MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/cd1865/cd1865.c linux.21pre4-ac6/drivers/char/cd1865/cd1865.c --- linux.21pre4/drivers/char/cd1865/cd1865.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/cd1865/cd1865.c 2003-01-11 19:09:03.000000000 +0000 @@ -0,0 +1,2913 @@ +/* -*- linux-c -*- */ +/* + * This code was modified from + * specialix.c -- specialix IO8+ multiport serial driver. + * + * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * Modifications (C) 2002 Telford Tools, Inc. (martillo@telfordtools.com) + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + */ + +#define VERSION "2.11" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdsiolx.h" +#include "../cd1865.h" /* will move all files up one level */ +#include "siolx.h" +#include "plx9060.h" + +#define SIOLX_NORMAL_MAJOR 254 /* One is needed */ +#define SIOLX_ID 0x10 +#define CD186x_MSMR 0x61 /* modem/timer iack */ +#define CD186x_TSMR 0x62 /* tx iack */ +#define CD186x_RSMR 0x63 /* rx iack */ + +/* Configurable options: */ + +/* Am I paranoid or not ? ;-) */ +#define SIOLX_PARANOIA_CHECK + +/* Do I trust the IRQ from the card? (enabeling it doesn't seem to help) + When the IRQ routine leaves the chip in a state that is keeps on + requiring attention, the timer doesn't help either. */ +#undef SIOLX_TIMER +/* + * The following defines are mostly for testing purposes. But if you need + * some nice reporting in your syslog, you can define them also. + */ +#undef SIOLX_REPORT_FIFO +#undef SIOLX_REPORT_OVERRUN + +#ifdef CONFIG_SIOLX_RTSCTS /* may need to set this */ +#define SIOLX_CRTSCTS(bla) 1 +#else +#define SIOLX_CRTSCTS(tty) C_CRTSCTS(tty) +#endif + +/* Used to be outb (0xff, 0x80); */ +#define short_pause() udelay (1) + +#define SIOLX_LEGAL_FLAGS \ + (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ + ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ + ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +DECLARE_TASK_QUEUE(tq_siolx); + +#undef RS_EVENT_WRITE_WAKEUP +#define RS_EVENT_WRITE_WAKEUP 0 + +#define SIOLX_TYPE_NORMAL 1 +#define SIOLX_TYPE_CALLOUT 2 + +#define BD_8000P 1 +#define BD_16000P 2 +#define BD_8000C 3 +#define BD_16000C 4 +#define BD_MAX BD_16000C + +static struct siolx_board *SiolxIrqRoot[SIOLX_NUMINTS]; + +static char *sio16_board_type[] = +{ + "unknown", + " 8000P ", + "16000P ", + " 8000C ", + "16000C " +}; +static struct tty_driver siolx_driver, siolx_callout_driver; +static int siolx_refcount; +static unsigned char * tmp_buf; +static DECLARE_MUTEX(tmp_buf_sem); +static unsigned long baud_table[] = +{ + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 115200, 0, +}; +static int siolx_debug = 0; /* turns on lots of */ + /* debugging messages*/ +static int siolx_major = SIOLX_NORMAL_MAJOR; +#ifdef MODULE +static int siolx_minorstart = 256; +#endif +static int siolx_vendor_id = PCI_VENDOR_ID_PLX; +static int siolx_device_id = PCI_DEVICE_ID_PLX_9060SD; +static int siolx_subsystem_vendor = AURASUBSYSTEM_VENDOR_ID; +static int siolx_subsystem_pci_device = AURASUBSYSTEM_MPASYNCPCI; +static int siolx_subsystem_cpci_device = AURASUBSYSTEM_MPASYNCcPCI; +static int siolx_bhindex = SIOLX_BH; /* if this softinterrupt slot is filled */ + +MODULE_PARM(siolx_vendor_id, "i"); +MODULE_PARM(siolx_device_id, "i"); +#ifdef MODULE +MODULE_PARM(siolx_minorstart, "i"); +#endif +MODULE_PARM(siolx_major, "i"); +MODULE_PARM(siolx_subsystem_vendor, "i"); +MODULE_PARM(siolx_subsystem_pci_device, "i"); +MODULE_PARM(siolx_subsystem_cpci_device, "i"); +MODULE_PARM(siolx_bhindex, "i"); + +static struct siolx_board *siolx_board_root; +static struct siolx_board *siolx_board_last; +static struct siolx_port *siolx_port_root; +static struct siolx_port *siolx_port_last; +static unsigned int NumSiolxPorts; +static struct tty_struct **siolx_table; /* make dynamic */ +static struct termios **siolx_termios; +static struct termios **siolx_termios_locked; +static int siolx_driver_registered; +static int siolx_callout_driver_registered; + +#ifdef SIOLX_TIMER +static struct timer_list missed_irq_timer; +static void siolx_interrupt(int irq, void * dev_id, struct pt_regs * regs); +#endif + +extern struct tty_driver *get_tty_driver(kdev_t device); + +static inline int port_No_by_chip (struct siolx_port const * port) +{ + return SIOLX_PORT(port->boardport); +} + +/* Describe the current board and port configuration */ + +static int siolx_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct siolx_port *port = siolx_port_root; + off_t begin = 0; + int len = 0; + unsigned int typeno; + char *revision = "$Revision: 1.11 $"; + + len += sprintf(page, "SIOLX Version %s. %s\n", VERSION, revision); + len += sprintf(page+len, "TTY MAJOR = %d, CUA MAJOR = %d.\n", + siolx_driver.major, siolx_callout_driver.major); + + for (port = siolx_port_root; port != NULL; port = port->next_by_global_list) + { + typeno = port->board->boardtype; + if(typeno > BD_MAX) + { + typeno = 0; + } + len += sprintf(page+len, + "%3.3d: bd %2.2d: %s: ch %d: pt %2.2d/%d: tp %4.4d%c: bs %2.2d: sl %2.2d: ir %2.2d: fl %c%c%c%c%c\n", + siolx_driver.minor_start + port->driverport, + port->board->boardnumber, + sio16_board_type[typeno], + port->board->chipnumber, + port->boardport, + port_No_by_chip(port), /* port relative to chip */ + port->board->chiptype, + port->board->chiprev, + port->board->pdev.bus->number, + PCI_SLOT(port->board->pdev.devfn), + port->board->irq, + (port->flags & ASYNC_INITIALIZED) ? 'I' : ' ', + (port->flags & ASYNC_CALLOUT_ACTIVE) ? 'D' : ' ', + (port->flags & ASYNC_NORMAL_ACTIVE) ? 'T' : ' ', + (port->flags & ASYNC_CLOSING) ? 'C' : ' ', + port->board->reario ? 'R' : ' '); + if (len+begin > off+count) + { + goto done; + } + if (len+begin < off) + { + begin += len; + len = 0; + } + } + *eof = 1; + done: + if (off >= len+begin) + { + return 0; + } + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); +} + +#ifndef MODULE +static int GetMinorStart(void) /* minor start can be determined on fly when driver linked to kernel */ +{ + struct tty_driver *ttydriver; + int minor_start = 0; + kdev_t device; + + device = MKDEV(siolx_major, minor_start); + while(ttydriver = get_tty_driver(device), ttydriver != NULL) + { + minor_start += ttydriver->num; + device = MKDEV(TTY_MAJOR, minor_start); + } + return minor_start; + +} +#endif + +/* only once per board chain */ +void SiolxResetBoard(struct siolx_board * bp, struct pci_dev *pdev) +{ + register unsigned int regvalue; + unsigned char savedvalue; + /* + * Yuch. Here's the deal with the reset bits in the + * ECNTL register of the 9060SD. + * + * It appears that LCLRST resets the PLX local configuration + * registers (not the PCI configuration registers) to their + * default values. We need to use LCLRST because it + * is the command (I think) that pulls the local reset + * line on the local bus side of the 9060SD. + * + * Unfortunately, by resetting the PLX local configuration + * registers, we can't use the damn board. So we must + * reinitialize them. The easiest way to do that is to run + * the LDREG command. Unfortunately, it has the side effect + * of reinitializing the PCI configuration registers. It seems, + * however that only the value stowed in ILINE gets choked; all + * of the others seem to be properly preserved. + * + * So, what the code does now is to get a copy of ILINE by + * hand, and then restore it after reloading the registers. + */ + + bp->pdev = *pdev; + bp->plx_vaddr = (unsigned long) ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); + if(bp->plx_vaddr) + { + regvalue = readl(bp->plx_vaddr + PLX_ECNTL); + regvalue &= ~PLX_ECNTLLDREG; + regvalue |= PLX_ECNTLLCLRST; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + udelay(200); + regvalue &= ~PLX_ECNTLLCLRST; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &savedvalue); + regvalue |= PLX_ECNTLLDREG; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + udelay(200); + regvalue &= ~PLX_ECNTLLDREG; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, savedvalue); + regvalue |= PLX_ECNTLINITSTAT; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + writel(0, bp->plx_vaddr + PLX_ICSR); + } +} + +void SiolxShutdownBoard(struct siolx_board * bp) +{ + register unsigned int regvalue; + unsigned char savedvalue; + struct pci_dev *pdev; + + if(bp->chipnumber == 0) /* only shutdown first in a chain */ + { + pdev = &bp->pdev; + + writel(0, bp->plx_vaddr + PLX_ICSR); + regvalue = readl(bp->plx_vaddr + PLX_ECNTL); + regvalue &= ~PLX_ECNTLLDREG; + regvalue |= PLX_ECNTLLCLRST; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + udelay(200); + regvalue &= ~PLX_ECNTLLCLRST; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &savedvalue); + regvalue |= PLX_ECNTLLDREG; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + udelay(200); + regvalue &= ~PLX_ECNTLLDREG; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, savedvalue); + regvalue |= PLX_ECNTLINITSTAT; + writel(regvalue, bp->plx_vaddr + PLX_ECNTL); + writel(0, bp->plx_vaddr + PLX_ICSR); + iounmap((void*)bp->plx_vaddr); + bp->plx_vaddr = 0; + } +} + +static inline int siolx_paranoia_check(struct siolx_port const * port, + kdev_t device, const char *routine) +{ +#ifdef SIOLX_PARANOIA_CHECK + static const char *badmagic = + KERN_ERR "siolx: Warning: bad siolx port magic number for device %s in %s\n"; + static const char *badinfo = + KERN_ERR "siolx: Warning: null siolx port for device %s in %s\n"; + + if (!port) + { + printk(badinfo, kdevname(device), routine); + return 1; + } + if (port->magic != SIOLX_MAGIC) + { + printk(badmagic, kdevname(device), routine); + return 1; + } +#endif + return 0; +} + + +/* + * + * Service functions for siolx Aurora Asynchronous Adapter driver. + * + */ + +/* Get board number from pointer */ +static inline int board_No (struct siolx_board * bp) +{ + return bp->boardnumber; /* note same for all chips/boards in a chain */ +} + + +/* Get port number from pointer */ +static inline int port_No (struct siolx_port const * port) +{ + return port->driverport; /* offset from minor start */ +} + +/* Get pointer to board from pointer to port */ +static inline struct siolx_board * port_Board(struct siolx_port const * port) +{ + return port->board; /* same for ports on both chips on a board */ +} + + +/* Input Byte from CL CD186x register */ +static inline unsigned char siolx_in(struct siolx_board * bp, unsigned short reg) +{ + return readb (bp->base + reg); +} + + +/* Output Byte to CL CD186x register */ +static inline void siolx_out(struct siolx_board * bp, unsigned short reg, + unsigned char val) +{ + writeb(val, bp->base + reg); +} + + +/* Wait for Channel Command Register ready */ +static int siolx_wait_CCR(struct siolx_board * bp) +{ + unsigned long delay; + + for (delay = SIOLX_CCR_TIMEOUT; delay; delay--) + { + udelay(1); + if (!siolx_in(bp, CD186x_CCR)) + { + return 0; + } + } + printk(KERN_ERR "siolx:board %d: timeout waiting for CCR.\n", board_No(bp)); + return -1; +} + +/* Wait for ready */ +static int siolx_wait_GIVR(struct siolx_board * bp) +{ + unsigned long delay; + + for (delay = SIOLX_CCR_TIMEOUT; delay; delay--) + { + udelay(1); + if (siolx_in(bp, CD186x_GIVR) == (unsigned char) 0xff) + { + return 0; + } + } + printk(KERN_ERR "siolx: board %d: timeout waiting for GIVR.\n", board_No(bp)); + return -1; +} + +static inline void siolx_release_io_range(struct siolx_board * bp) +{ + if((bp->chipnumber == 0) && bp->vaddr) /* only release from first board in a chain */ + { + iounmap((void*)bp->vaddr); + bp->vaddr = 0; + } +} + +/* Must be called with enabled interrupts */ + +static inline void siolx_long_delay(unsigned long delay) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(delay); +} + +/* Reset and setup CD186x chip */ +static int siolx_init_CD186x(struct siolx_board * bp) +{ + unsigned long flags; + int scaler; + int rv = 1; + int rev; + int chip; + + save_flags(flags); /* not sure of need to turn off ints */ + cli(); + if(siolx_wait_CCR(bp)) + { + restore_flags(flags); + return 0; /* Wait for CCR ready */ + } + siolx_out(bp, CD186x_CAR, 0); + siolx_out(bp, CD186x_GIVR, 0); + siolx_out(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */ + if(siolx_wait_GIVR(bp)) + { + restore_flags(flags); + return 0; + } + sti(); + siolx_long_delay(HZ/20); /* Delay 0.05 sec */ + cli(); + siolx_out(bp, CD186x_GIVR, SIOLX_ID | (bp->chipnumber ? 0x80 : 0)); /* Set ID for this chip */ +#if 0 + siolx_out(bp, CD186x_GICR, 0); /* Clear all bits */ +#endif + scaler = SIOLX_OSCFREQ/1000; + siolx_out(bp, CD186x_PPRH, scaler >> 8); + siolx_out(bp, CD186x_PPRL, scaler & 0xff); + + /* Chip revcode pkgtype + GFRCR SRCR bit 7 + CD180 rev B 0x81 0 + CD180 rev C 0x82 0 + CD1864 rev A 0x82 1 + CD1865 rev A 0x83 1 -- Do not use!!! Does not work. + CD1865 rev B 0x84 1 + -- Thanks to Gwen Wang, Cirrus Logic. + */ + + switch (siolx_in(bp, CD186x_GFRCR)) + { + case 0x82: + chip = 1864; + rev='A'; + break; + case 0x83: + chip = 1865; + rev='A'; + break; + case 0x84: + chip = 1865; + rev='B'; + break; + case 0x85: + chip = 1865; + rev='C'; + break; /* Does not exist at this time */ + default: + chip=-1; + rev='x'; + break; + } + +#if SIOLX_DEBUG > 2 + printk (KERN_DEBUG " GFCR = 0x%02x\n", siolx_in(bp, CD186x_GFRCR) ); +#endif + + siolx_out(bp, CD186x_MSMR, CD186x_MRAR); /* load up match regs with address regs */ + siolx_out(bp, CD186x_TSMR, CD186x_TRAR); + siolx_out(bp, CD186x_RSMR, CD186x_RRAR); + +#if 0 + DEBUGPRINT((KERN_ALERT "match reg values are msmr %x, tsmr %x, rsmr %x.\n", + siolx_in(bp, CD186x_MSMR), + siolx_in(bp, CD186x_TSMR), + siolx_in(bp, CD186x_RSMR))); +#endif + + siolx_out(bp, CD186x_SRCR, SRCR_AUTOPRI | SRCR_GLOBPRI | SRCR_REGACKEN); + /* Setting up prescaler. We need 4 ticks per 1 ms */ + + printk(KERN_INFO"siolx: CD%4.4d%c detected at 0x%lx, IRQ %d, on Aurora asynchronous adapter board %d, chip number %d.\n", + chip, rev, bp->base, bp->irq, board_No(bp), bp->chipnumber); + + bp->chiptype = chip; + bp->chiprev = rev; + + restore_flags(flags); + return rv; +} + + +#ifdef SIOLX_TIMER +void missed_irq (unsigned long data) +{ + if (siolx_in ((struct siolx_board *)data, CD186x_SRSR) & + (SRSR_RREQint | + SRSR_TREQint | + SRSR_MREQint)) + { + printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); + siolx_interrupt (((struct siolx_board *)data)->irq, + NULL, NULL); + } + missed_irq_timer.expires = jiffies + HZ; + add_timer (&missed_irq_timer); +} +#endif + +/* Main probing routine, also sets irq. */ +static int siolx_probe(struct siolx_board *bp) +{ + unsigned char val1, val2; + + /* Are the I/O ports here ? */ + siolx_out(bp, CD186x_PPRL, 0x5a); + short_pause (); + val1 = siolx_in(bp, CD186x_PPRL); + + siolx_out(bp, CD186x_PPRL, 0xa5); + short_pause (); + val2 = siolx_in(bp, CD186x_PPRL); + + if ((val1 != 0x5a) || (val2 != 0xa5)) + { + printk(KERN_INFO + "siolx: cd serial chip not found at base %ld.\n", + bp->base); + return 1; + } + + /* Reset CD186x */ + if (!siolx_init_CD186x(bp)) + { + return -EIO; + } + +#ifdef SIOLX_TIMER + init_timer (&missed_irq_timer); + missed_irq_timer.function = missed_irq; + missed_irq_timer.data = (unsigned long) bp; + missed_irq_timer.expires = jiffies + HZ; + add_timer (&missed_irq_timer); +#endif + return 0; +} + +/* + * + * Interrupt processing routines. + * */ + +static inline void siolx_mark_event(struct siolx_port * port, int event) +{ + /* + * I'm not quite happy with current scheme all serial + * drivers use their own BH routine. + * It seems this easily can be done with one BH routine + * serving for all serial drivers. + * For now I must introduce another one - SIOLX_BH. + * Still hope this will be changed in near future. + * -- Dmitry. + */ + /* I use a module parameter that can be set at module + * load time so that this driver can be downloaded into + * a kernel where the value of SIOLX_BX has been allocated + * to something else. This kludge was not necessary + * in the ASLX driver because AURORA_BH had already + * been allocated for the sparc and there was no + * similar driver for x86 while the ASLX driver probably + * will not work for the SPARC and is not guaranteed to + * do so (at some point I should clean this situation up) -- Joachim*/ + set_bit(event, &port->event); + queue_task(&port->tqueue, &tq_siolx); + mark_bh(siolx_bhindex); +} + +static inline struct siolx_port * siolx_get_port(struct siolx_board * bp, + unsigned char const * what) +{ + unsigned char channel; + struct siolx_port * port; + + channel = siolx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; + if (channel < CD186x_NCH) + { + port = bp->portlist; + while(port) + { + if(channel == 0) + { + break; + } + port = port->next_by_board; + --channel; + } + + if(port && (port->flags & ASYNC_INITIALIZED)) /* port should be opened */ + { + return port; + } + } + printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", + board_No(bp), what, channel); + return NULL; +} + + +static inline void siolx_receive_exc(struct siolx_board * bp) +{ + struct siolx_port *port; + struct tty_struct *tty; + unsigned char status; + unsigned char ch; + + if (!(port = siolx_get_port(bp, "Receive"))) + return; + + tty = port->tty; + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + { + printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n", + board_No(bp), port_No(port)); + return; + } + +#ifdef SIOLX_REPORT_OVERRUN + status = siolx_in(bp, CD186x_RCSR); + if (status & RCSR_OE) + { + port->overrun++; +#if SIOLX_DEBUG + printk(KERN_DEBUG "sx%d: port %d: Overrun. Total %ld overruns.\n", + board_No(bp), port_No(port), port->overrun); +#endif + } + status &= port->mark_mask; +#else + status = siolx_in(bp, CD186x_RCSR) & port->mark_mask; +#endif + ch = siolx_in(bp, CD186x_RDR); + if (!status) + { + return; + } + if (status & RCSR_TOUT) + { + printk(KERN_INFO "siolx: board %d: chip %d: port %d: Receiver timeout. Hardware problems ?\n", + board_No(bp), bp->chipnumber, port_No(port)); + return; + + } + else if (status & RCSR_BREAK) + { +#ifdef SIOLX_DEBUG + printk(KERN_DEBUG "siolx: board %d: chip %d: port %d: Handling break...\n", + board_No(bp), bp->chipnumber, port_No(port)); +#endif + *tty->flip.flag_buf_ptr++ = TTY_BREAK; + if (port->flags & ASYNC_SAK) + { + do_SAK(tty); + } + + } + else if (status & RCSR_PE) + { + *tty->flip.flag_buf_ptr++ = TTY_PARITY; + } + else if (status & RCSR_FE) + { + *tty->flip.flag_buf_ptr++ = TTY_FRAME; + } + + else if (status & RCSR_OE) + { + *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; + } + + else + { + *tty->flip.flag_buf_ptr++ = 0; + } + + *tty->flip.char_buf_ptr++ = ch; + tty->flip.count++; + queue_task(&tty->flip.tqueue, &tq_timer); +} + + +static inline void siolx_receive(struct siolx_board * bp) +{ + struct siolx_port *port; + struct tty_struct *tty; + unsigned char count; + + if (!(port = siolx_get_port(bp, "Receive"))) + return; + + tty = port->tty; + + count = siolx_in(bp, CD186x_RDCR); + +#ifdef SIOLX_REPORT_FIFO + port->hits[count > 8 ? 9 : count]++; +#endif + + while (count--) + { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + { + printk(KERN_INFO "siolx: board %d: chip %d: port %d: Working around flip buffer overflow.\n", + board_No(bp), bp->chipnumber, port_No(port)); + break; + } + *tty->flip.char_buf_ptr++ = siolx_in(bp, CD186x_RDR); + *tty->flip.flag_buf_ptr++ = 0; + tty->flip.count++; + } + queue_task(&tty->flip.tqueue, &tq_timer); +} + +static inline void siolx_transmit(struct siolx_board * bp) +{ + struct siolx_port *port; + struct tty_struct *tty; + unsigned char count; + + if (!(port = siolx_get_port(bp, "Transmit"))) + return; + + tty = port->tty; + + if(port->IER & IER_TXEMPTY) + { + /* FIFO drained */ +#if 0 + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); +#endif + port->IER &= ~IER_TXEMPTY; + siolx_out(bp, CD186x_IER, port->IER); + return; + } + + if(((port->xmit_cnt <= 0) && !port->break_length) || + tty->stopped || tty->hw_stopped) + { +#if 0 + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); +#endif + port->IER &= ~IER_TXRDY; + siolx_out(bp, CD186x_IER, port->IER); + return; + } + + if (port->break_length) + { + if (port->break_length > 0) + { + if (port->COR2 & COR2_ETC) + { + siolx_out(bp, CD186x_TDR, CD186x_C_ESC); + siolx_out(bp, CD186x_TDR, CD186x_C_SBRK); + port->COR2 &= ~COR2_ETC; + } + count = MIN(port->break_length, 0xff); + siolx_out(bp, CD186x_TDR, CD186x_C_ESC); + siolx_out(bp, CD186x_TDR, CD186x_C_DELAY); + siolx_out(bp, CD186x_TDR, count); + if (!(port->break_length -= count)) + { + port->break_length--; + } + } + else + { + siolx_out(bp, CD186x_TDR, CD186x_C_ESC); + siolx_out(bp, CD186x_TDR, CD186x_C_EBRK); + siolx_out(bp, CD186x_COR2, port->COR2); + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_CORCHG2); + port->break_length = 0; + } + return; + } + + count = CD186x_NFIFO; + do + { + siolx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]); + port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); + if (--port->xmit_cnt <= 0) + { + break; + } + } while (--count > 0); + + if (port->xmit_cnt <= 0) + { +#if 0 + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); +#endif + port->IER &= ~IER_TXRDY; + siolx_out(bp, CD186x_IER, port->IER); + } + if (port->xmit_cnt <= port->wakeup_chars) + { + siolx_mark_event(port, RS_EVENT_WRITE_WAKEUP); + } +} + + +static inline void siolx_check_modem(struct siolx_board * bp) +{ + struct siolx_port *port; + struct tty_struct *tty; + unsigned char mcr; + +#ifdef SIOLX_DEBUG + printk (KERN_DEBUG "Modem intr. "); +#endif + if (!(port = siolx_get_port(bp, "Modem"))) + { + return; + } + + tty = port->tty; + + mcr = siolx_in(bp, CD186x_MCR); + DEBUGPRINT((KERN_ALERT "mcr = %02x.\n", mcr)); + + if ((mcr & MCR_CDCHG)) + { +#ifdef SIOLX_DEBUG + DEBUGPRINT((KERN_DEBUG "CD just changed... ")); +#endif + if (siolx_in(bp, CD186x_MSVR) & MSVR_CD) + { +#ifdef SIOLX_DEBUG + DEBUGPRINT(( "Waking up guys in open.\n")); +#endif + wake_up_interruptible(&port->open_wait); /* note no linefeed in previous print */ + } + else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) && + (port->flags & ASYNC_CALLOUT_NOHUP))) + { +#ifdef SIOLX_DEBUG + DEBUGPRINT(( "Sending HUP.\n")); /* note no linefeed in previous print */ +#endif + MOD_INC_USE_COUNT; + if (schedule_task(&port->tqueue_hangup) == 0) + { + MOD_DEC_USE_COUNT; + } + } + else + { +#ifdef SIOLX_DEBUG + DEBUGPRINT(("Don't need to send HUP.\n")); /* note no linefeed in previous print */ +#endif + } + } + +#ifdef SIOLX_BRAIN_DAMAGED_CTS + if (mcr & MCR_CTSCHG) + { + if (siolx_in(bp, CD186x_MSVR) & MSVR_CTS) + { + tty->hw_stopped = 0; + port->IER |= IER_TXRDY; + if (port->xmit_cnt <= port->wakeup_chars) + siolx_mark_event(port, RS_EVENT_WRITE_WAKEUP); + } + else + { + tty->hw_stopped = 1; + port->IER &= ~IER_TXRDY; + } + siolx_out(bp, CD186x_IER, port->IER); + } + if (mcr & MCR_DSSXHG) + { + if (siolx_in(bp, CD186x_MSVR) & MSVR_DSR) + { + tty->hw_stopped = 0; + port->IER |= IER_TXRDY; + if (port->xmit_cnt <= port->wakeup_chars) + { + siolx_mark_event(port, RS_EVENT_WRITE_WAKEUP); + } + } + else + { + tty->hw_stopped = 1; + port->IER &= ~IER_TXRDY; + } + siolx_out(bp, CD186x_IER, port->IER); + } +#endif /* SIOLX_BRAIN_DAMAGED_CTS */ + + /* Clear change bits */ + siolx_out(bp, CD186x_MCR, 0); +} + +/* The main interrupt processing routine */ +static void siolx_interrupt(int irq, void * dev_id, struct pt_regs * regs) +{ + unsigned char status; + unsigned char rcsr; + struct siolx_board *bp; + + if((irq < 0) || (irq >= SIOLX_NUMINTS)) + { + printk(KERN_ALERT "siolx: bad interrupt value %i.\n", irq); + return; + } + /* walk through all the cards on the interrupt that occurred. */ + for(bp = SiolxIrqRoot[irq]; bp != NULL; bp = bp->next_by_interrupt) + + { + while((readl(bp->intstatus) & PLX_ICSRINTACTIVE) != 0) /* work on on board */ + { + status = siolx_in(bp, CD186x_SRSR); + + if(status & SRSR_RREQint) + { + siolx_in(bp, CD186x_RRAR); + rcsr = siolx_in(bp, CD186x_RCSR); + if(rcsr == 0) + { + siolx_receive(bp); + } + else + { + siolx_receive_exc(bp); + } + } + else if (status & SRSR_TREQint) + { + siolx_in(bp, CD186x_TRAR); + siolx_transmit(bp); + } + else if (status & SRSR_MREQint) + { + siolx_in(bp, CD186x_MRAR); + siolx_check_modem(bp); + } + siolx_out(bp, CD186x_EOIR, 1); /* acknowledge the interrupt */ + bp = bp->next_by_chain; /* go to next chip on card -- maybe this one */ + } /* it does not matter if bp changes all in a chain have same next by interrupt */ + } +} + + +/* + * Setting up port characteristics. + * Must be called with disabled interrupts + */ +static void siolx_change_speed(struct siolx_board *bp, struct siolx_port *port) +{ + struct tty_struct *tty; + unsigned long baud; + long tmp; + unsigned char cor1 = 0, cor3 = 0; + unsigned char mcor1 = 0, mcor2 = 0; + static int again; + + tty = port->tty; + + if(!tty || !tty->termios) + { + return; + } + + port->IER = 0; + port->COR2 = 0; + /* Select port on the board */ + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + + /* The Siolx board doens't implement the RTS lines. + They are used to set the IRQ level. Don't touch them. */ + /* Must check how to apply these to sio16 boards */ + if (SIOLX_CRTSCTS(tty)) + { + port->MSVR = (MSVR_DTR | (siolx_in(bp, CD186x_MSVR) & MSVR_RTS)); + } + else + { + port->MSVR = (siolx_in(bp, CD186x_MSVR) & MSVR_RTS); + } +#ifdef DEBUG_SIOLX + DEBUGPRINT((KERN_DEBUG "siolx: got MSVR=%02x.\n", port->MSVR)); +#endif + baud = C_BAUD(tty); + + if (baud & CBAUDEX) + { + baud &= ~CBAUDEX; + if((baud < 1) || (baud > 2)) + { + port->tty->termios->c_cflag &= ~CBAUDEX; + } + else + { + baud += 15; + } + } + if (baud == 15) + { + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + { + baud ++; + } + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + { + baud += 2; + } + } + + + if (!baud_table[baud]) + { + /* Drop DTR & exit */ +#ifdef SIOLX_DEBUG + DEBUGPRINT((KERN_DEBUG "siolx: Dropping DTR... Hmm....\n")); +#endif + if (!SIOLX_CRTSCTS (tty)) + { + port->MSVR &= ~ MSVR_DTR; + siolx_out(bp, CD186x_MSVR, port->MSVR ); + } +#ifdef DEBUG_SIOLX + else + { + DEBUGPRINT((KERN_DEBUG "siolx: Can't drop DTR: no DTR.\n")); + } +#endif + return; + } + else + { + /* Set DTR on */ + if (!SIOLX_CRTSCTS (tty)) + { + port ->MSVR |= MSVR_DTR; + } + } + + /* + * Now we must calculate some speed depended things + */ + + /* Set baud rate for port */ + tmp = port->custom_divisor ; + if(tmp) + { + DEBUGPRINT((KERN_INFO "siolx: board %d: chip %d: port %d: Using custom baud rate divisor %ld. \n" + "This is an untested option, please be carefull.\n", + board_No(bp), + bp->chipnumber, + port_No(port), tmp)); + } + else + { + tmp = (((SIOLX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + + CD186x_TPC/2) / CD186x_TPC); + } + + if ((tmp < 0x10) && time_before(again, jiffies)) + { + again = jiffies + HZ * 60; + /* Page 48 of version 2.0 of the CL-CD1865 databook */ + if (tmp >= 12) + { + DEBUGPRINT((KERN_INFO "siolx: board %d: chip %d: port %d:Baud rate divisor is %ld. \n" + "Performance degradation is possible.\n" + "Read siolx.txt for more info.\n", + board_No(bp), bp->chipnumber, + port_No (port), tmp)); + } else + { + DEBUGPRINT((KERN_INFO "siolx: board %d: chip %d: port %d: Baud rate divisor is %ld. \n" + " Warning: overstressing Cirrus chip. " + " This might not work.\n" + " Read siolx.txt for more info.\n", + board_No(bp), bp->chipnumber, port_No (port), tmp)); + } + } + + siolx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); + siolx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); + siolx_out(bp, CD186x_RBPRL, tmp & 0xff); + siolx_out(bp, CD186x_TBPRL, tmp & 0xff); + + if (port->custom_divisor) + { + baud = (SIOLX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; + baud = ( baud + 5 ) / 10; + } else + { + baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ + } + + /* Two timer ticks seems enough to wakeup something like SLIP driver */ + tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; + port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? + SERIAL_XMIT_SIZE - 1 : tmp); + + /* Receiver timeout will be transmission time for 1.5 chars */ + tmp = (SIOLX_TPS + SIOLX_TPS/2 + baud/2) / baud; + tmp = (tmp > 0xff) ? 0xff : tmp; + siolx_out(bp, CD186x_RTPR, tmp); + + switch (C_CSIZE(tty)) + { + case CS5: + cor1 |= COR1_5BITS; + break; + case CS6: + cor1 |= COR1_6BITS; + break; + case CS7: + cor1 |= COR1_7BITS; + break; + case CS8: + cor1 |= COR1_8BITS; + break; + } + + if (C_CSTOPB(tty)) + { + cor1 |= COR1_2SB; + } + + cor1 |= COR1_IGNORE; + if (C_PARENB(tty)) + { + cor1 |= COR1_NORMPAR; + if (C_PARODD(tty)) + { + cor1 |= COR1_ODDP; + } + if (I_INPCK(tty)) + { + cor1 &= ~COR1_IGNORE; + } + } + /* Set marking of some errors */ + port->mark_mask = RCSR_OE | RCSR_TOUT; + if (I_INPCK(tty)) + { + port->mark_mask |= RCSR_FE | RCSR_PE; + } + if (I_BRKINT(tty) || I_PARMRK(tty)) + { + port->mark_mask |= RCSR_BREAK; + } + if (I_IGNPAR(tty)) + { + port->mark_mask &= ~(RCSR_FE | RCSR_PE); + } + if (I_IGNBRK(tty)) + { + port->mark_mask &= ~RCSR_BREAK; + if (I_IGNPAR(tty)) + { + /* Real raw mode. Ignore all */ + port->mark_mask &= ~RCSR_OE; + } + } + /* Enable Hardware Flow Control */ + if (C_CRTSCTS(tty)) + { +#ifdef SIOLX_BRAIN_DAMAGED_CTS + port->IER |= IER_DSR | IER_CTS; + mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; + mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; + tty->hw_stopped = !(siolx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR)); +#else + port->COR2 |= COR2_CTSAE; +#endif + } + /* Enable Software Flow Control. FIXME: I'm not sure about this */ + /* Some people reported that it works, but I still doubt it */ + if (I_IXON(tty)) + { + port->COR2 |= COR2_TXIBE; + cor3 |= (COR3_FCT | COR3_SCDE); + if (I_IXANY(tty)) + { + port->COR2 |= COR2_IXM; + } + siolx_out(bp, CD186x_SCHR1, START_CHAR(tty)); + siolx_out(bp, CD186x_SCHR2, STOP_CHAR(tty)); + siolx_out(bp, CD186x_SCHR3, START_CHAR(tty)); + siolx_out(bp, CD186x_SCHR4, STOP_CHAR(tty)); + } + if (!C_CLOCAL(tty)) + { + /* Enable CD check */ + port->IER |= IER_CD; + mcor1 |= MCOR1_CDZD; + mcor2 |= MCOR2_CDOD; + } + + if (C_CREAD(tty)) + { + /* Enable receiver */ + port->IER |= IER_RXD; + } + + /* Set input FIFO size (1-8 bytes) */ + cor3 |= SIOLX_RXFIFO; + /* Setting up CD186x channel registers */ + siolx_out(bp, CD186x_COR1, cor1); + siolx_out(bp, CD186x_COR2, port->COR2); + siolx_out(bp, CD186x_COR3, cor3); + /* Make CD186x know about registers change */ + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); + /* Setting up modem option registers */ +#ifdef DEBUG_SIOLX + DEBUGPRINT((KERN_ALERT "siolx: Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2)); +#endif + siolx_out(bp, CD186x_MCOR1, mcor1); + siolx_out(bp, CD186x_MCOR2, mcor2); + /* Enable CD186x transmitter & receiver */ + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN); + /* Enable interrupts */ + siolx_out(bp, CD186x_IER, port->IER); + /* And finally set the modem lines... */ + siolx_out(bp, CD186x_MSVR, port->MSVR); +} + + +/* Must be called with interrupts enabled */ +static int siolx_setup_port(struct siolx_board *bp, struct siolx_port *port) +{ + unsigned long flags; + + if (port->flags & ASYNC_INITIALIZED) + { + return 0; + } + + if (!port->xmit_buf) + { + /* We may sleep in get_free_page() */ + unsigned long tmp; + + if (!(tmp = get_free_page(GFP_KERNEL))) + { + return -ENOMEM; + } + + if (port->xmit_buf) + { + free_page(tmp); + return -ERESTARTSYS; + } + port->xmit_buf = (unsigned char *) tmp; + } + + save_flags(flags); cli(); + + if (port->tty) + { + clear_bit(TTY_IO_ERROR, &port->tty->flags); + } + + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + siolx_change_speed(bp, port); + port->flags |= ASYNC_INITIALIZED; + + restore_flags(flags); + return 0; +} + + +/* Must be called with interrupts disabled */ +static void siolx_shutdown_port(struct siolx_board *bp, struct siolx_port *port) +{ + struct tty_struct *tty; + + if (!(port->flags & ASYNC_INITIALIZED)) + { + return; + } + +#ifdef SIOLX_REPORT_OVERRUN + DEBUGPRINT((KERN_INFO "siolx: board %d: chip %d: port %d: Total %ld overruns were detected.\n", + board_No(bp), bp->chipnumber, port_No(port), port->overrun)); +#endif +#ifdef SIOLX_REPORT_FIFO + { + int i; + + DEBUGPRINT((KERN_INFO "siolx: board %d: chip %d: port %d: FIFO hits [ ", + board_No(bp), bp->chipnumber, port_No(port))); + for (i = 0; i < 10; i++) + { + DEBUGPRINT(("%ld ", port->hits[i])); + } + DEBUGPRINT(("].\n")); + } +#endif + if (port->xmit_buf) + { + free_page((unsigned long) port->xmit_buf); + port->xmit_buf = NULL; + } + + /* Select port */ + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + + if (!(tty = port->tty) || C_HUPCL(tty)) + { + /* Drop DTR */ + siolx_out(bp, CD186x_MSVDTR, 0); + } + + /* Reset port */ + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_SOFTRESET); + /* Disable all interrupts from this port */ + port->IER = 0; + siolx_out(bp, CD186x_IER, port->IER); + + if (tty) + { + set_bit(TTY_IO_ERROR, &tty->flags); + } + port->flags &= ~ASYNC_INITIALIZED; + + /* + * If this is the last opened port on the board + * shutdown whole board + */ + MOD_DEC_USE_COUNT; +} + + +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct siolx_port *port) +{ + DECLARE_WAITQUEUE(wait, current); + struct siolx_board *bp = port_Board(port); + int retval; + int do_clocal = 0; + int CD; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) + { + interruptible_sleep_on(&port->close_wait); + if (port->flags & ASYNC_HUP_NOTIFY) + { + return -EAGAIN; + } + else + { + return -ERESTARTSYS; + } + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SIOLX_TYPE_CALLOUT) + { + if (port->flags & ASYNC_NORMAL_ACTIVE) + { + return -EBUSY; + } + if ((port->flags & ASYNC_CALLOUT_ACTIVE) && + (port->flags & ASYNC_SESSION_LOCKOUT) && + (port->session != current->session)) + { + return -EBUSY; + } + if ((port->flags & ASYNC_CALLOUT_ACTIVE) && + (port->flags & ASYNC_PGRP_LOCKOUT) && + (port->pgrp != current->pgrp)) + { + return -EBUSY; + } + port->flags |= ASYNC_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) + { + if (port->flags & ASYNC_CALLOUT_ACTIVE) + { + return -EBUSY; + } + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (port->flags & ASYNC_CALLOUT_ACTIVE) + { + if (port->normal_termios.c_cflag & CLOCAL) + { + do_clocal = 1; + } + } + else + { + if (C_CLOCAL(tty)) + { + do_clocal = 1; + } + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&port->open_wait, &wait); + cli(); + if (!tty_hung_up_p(filp)) + { + port->count--; + } + sti(); + port->blocked_open++; + while (1) + { + cli(); + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + CD = siolx_in(bp, CD186x_MSVR) & MSVR_CD; + if (!(port->flags & ASYNC_CALLOUT_ACTIVE)) + { + if (SIOLX_CRTSCTS (tty)) + { + /* Activate RTS */ + port->MSVR |= MSVR_DTR; + siolx_out (bp, CD186x_MSVR, port->MSVR); + } + else + { + /* Activate DTR */ + port->MSVR |= MSVR_DTR; + siolx_out (bp, CD186x_MSVR, port->MSVR); + } + } + sti(); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) + { + if (port->flags & ASYNC_HUP_NOTIFY) + { + retval = -EAGAIN; + } + else + { + retval = -ERESTARTSYS; + } + break; + } + if (!(port->flags & ASYNC_CALLOUT_ACTIVE) && + !(port->flags & ASYNC_CLOSING) && + (do_clocal || CD)) + { + break; + } + if (signal_pending(current)) + { + retval = -ERESTARTSYS; + break; + } + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&port->open_wait, &wait); + if (!tty_hung_up_p(filp)) + { + port->count++; + } + port->blocked_open--; + if (retval) + { + return retval; + } + + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static inline struct siolx_port *siolx_portstruc(register int line) +{ + register struct siolx_port *pp; + + line -= siolx_driver.minor_start; + for(pp = siolx_port_root; (pp != NULL) && (line >= 0); --line, pp = pp->next_by_global_list) + { + if(line == 0) + { + return pp; + } + } + return NULL; +} + + +static int siolx_open(struct tty_struct * tty, struct file * filp) +{ + int error; + struct siolx_port * port; + struct siolx_board * bp; + unsigned long flags; + + port = siolx_portstruc(MINOR(tty->device)); + + if(port == NULL) + { + return -ENODEV; + } + bp = port->board; + if(bp == NULL) + { + return -ENODEV; + } + +#ifdef DEBUG_SIOLX + printk (KERN_DEBUG "Board = %d, bp = %p, port = %p, portno = %d.\n", + bp->boardnumber, bp, port, siolx_portstruc(MINOR(tty->device))); +#endif + + if (siolx_paranoia_check(port, tty->device, "siolx_open")) + return -ENODEV; + + MOD_INC_USE_COUNT; + + port->count++; + tty->driver_data = port; + port->tty = tty; + + if ((error = siolx_setup_port(bp, port))) + return error; + + if ((error = block_til_ready(tty, filp, port))) + return error; + + if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SIOLX_TYPE_NORMAL) + *tty->termios = port->normal_termios; + else + *tty->termios = port->callout_termios; + save_flags(flags); cli(); + siolx_change_speed(bp, port); + restore_flags(flags); + } + + port->session = current->session; + port->pgrp = current->pgrp; + return 0; +} + + +static void siolx_close(struct tty_struct * tty, struct file * filp) +{ + struct siolx_port *port = (struct siolx_port *) tty->driver_data; + struct siolx_board *bp; + unsigned long flags; + unsigned long timeout; + + if (!port || siolx_paranoia_check(port, tty->device, "close")) + return; + + save_flags(flags); cli(); + if (tty_hung_up_p(filp)) { + restore_flags(flags); + return; + } + + bp = port_Board(port); + if ((tty->count == 1) && (port->count != 1)) { + printk(KERN_ERR "sx%d: siolx_close: bad port count;" + " tty->count is 1, port count is %d\n", + board_No(bp), port->count); + port->count = 1; + } + if (--port->count < 0) { + printk(KERN_ERR "sx%d: siolx_close: bad port count for tty%d: %d\n", + board_No(bp), port_No(port), port->count); + port->count = 0; + } + if (port->count) { + restore_flags(flags); + return; + } + port->flags |= ASYNC_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (port->flags & ASYNC_NORMAL_ACTIVE) + port->normal_termios = *tty->termios; + if (port->flags & ASYNC_CALLOUT_ACTIVE) + port->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, port->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + port->IER &= ~IER_RXD; + if (port->flags & ASYNC_INITIALIZED) { + port->IER &= ~IER_TXRDY; + port->IER |= IER_TXEMPTY; + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + siolx_out(bp, CD186x_IER, port->IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + timeout = jiffies+HZ; + while(port->IER & IER_TXEMPTY) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(port->timeout); + if (time_after(jiffies, timeout)) { + printk (KERN_INFO "siolx: Timeout waiting for close\n"); + break; + } + } + + } + siolx_shutdown_port(bp, port); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + port->event = 0; + port->tty = 0; + if (port->blocked_open) { + if (port->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(port->close_delay); + } + wake_up_interruptible(&port->open_wait); + } + port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| + ASYNC_CLOSING); + wake_up_interruptible(&port->close_wait); + restore_flags(flags); +} + + +static int siolx_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + struct siolx_board *bp; + int c, total = 0; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_write")) + return 0; + + bp = port_Board(port); + + if (!tty || !port->xmit_buf || !tmp_buf) + return 0; + + save_flags(flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } + + cli(); + c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c); + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } + memcpy(port->xmit_buf + port->xmit_head, buf, c); + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + } + + cli(); + if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && + !(port->IER & IER_TXRDY)) { + port->IER |= IER_TXRDY; + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + siolx_out(bp, CD186x_IER, port->IER); + } + restore_flags(flags); + return total; +} + + +static void siolx_put_char(struct tty_struct * tty, unsigned char ch) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_put_char")) + return; + + if (!tty || !port->xmit_buf) + return; + + save_flags(flags); cli(); + + if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { + restore_flags(flags); + return; + } + + port->xmit_buf[port->xmit_head++] = ch; + port->xmit_head &= SERIAL_XMIT_SIZE - 1; + port->xmit_cnt++; + restore_flags(flags); +} + + +static void siolx_flush_chars(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_flush_chars")) + return; + + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !port->xmit_buf) + return; + + save_flags(flags); cli(); + port->IER |= IER_TXRDY; + siolx_out(port_Board(port), CD186x_CAR, port_No_by_chip(port)); + siolx_out(port_Board(port), CD186x_IER, port->IER); + restore_flags(flags); +} + + +static int siolx_write_room(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + int ret; + + if (siolx_paranoia_check(port, tty->device, "siolx_write_room")) + return 0; + + ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + + +static int siolx_chars_in_buffer(struct tty_struct *tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + + if (siolx_paranoia_check(port, tty->device, "siolx_chars_in_buffer")) + return 0; + + return port->xmit_cnt; +} + + +static void siolx_flush_buffer(struct tty_struct *tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_flush_buffer")) + return; + + save_flags(flags); cli(); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + restore_flags(flags); + + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + + +static int siolx_get_modem_info(struct siolx_port * port, unsigned int *value) +{ + struct siolx_board * bp; + unsigned char status; + unsigned int result; + unsigned long flags; + + bp = port_Board(port); + save_flags(flags); cli(); + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + status = siolx_in(bp, CD186x_MSVR); + restore_flags(flags); +#ifdef DEBUG_SIOLX + printk (KERN_DEBUG "Got msvr[%d] = %02x, car = %d.\n", + port_No(port), status, siolx_in (bp, CD186x_CAR)); + printk (KERN_DEBUG "siolx_port = %p, port = %p\n", siolx_port, port); +#endif + if (SIOLX_CRTSCTS(port->tty)) { + result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ + | ((status & MSVR_DTR) ? TIOCM_RTS : 0) + | ((status & MSVR_CD) ? TIOCM_CAR : 0) + |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ + | ((status & MSVR_CTS) ? TIOCM_CTS : 0); + } else { + result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ + | ((status & MSVR_DTR) ? TIOCM_DTR : 0) + | ((status & MSVR_CD) ? TIOCM_CAR : 0) + |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ + | ((status & MSVR_CTS) ? TIOCM_CTS : 0); + } + put_user(result,(unsigned int *) value); + return 0; +} + + +static int siolx_set_modem_info(struct siolx_port * port, unsigned int cmd, + unsigned int *value) +{ + int error; + unsigned int arg; + unsigned long flags; + struct siolx_board *bp = port_Board(port); + + error = verify_area(VERIFY_READ, value, sizeof(int)); + if (error) + return error; + + get_user(arg, (unsigned long *) value); + switch (cmd) { + case TIOCMBIS: + /* if (arg & TIOCM_RTS) + port->MSVR |= MSVR_RTS; */ + /* if (arg & TIOCM_DTR) + port->MSVR |= MSVR_DTR; */ + + if (SIOLX_CRTSCTS(port->tty)) { + if (arg & TIOCM_RTS) + port->MSVR |= MSVR_DTR; + } else { + if (arg & TIOCM_DTR) + port->MSVR |= MSVR_DTR; + } + break; + case TIOCMBIC: + /* if (arg & TIOCM_RTS) + port->MSVR &= ~MSVR_RTS; */ + /* if (arg & TIOCM_DTR) + port->MSVR &= ~MSVR_DTR; */ + if (SIOLX_CRTSCTS(port->tty)) { + if (arg & TIOCM_RTS) + port->MSVR &= ~MSVR_DTR; + } else { + if (arg & TIOCM_DTR) + port->MSVR &= ~MSVR_DTR; + } + break; + case TIOCMSET: + /* port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) : + (port->MSVR & ~MSVR_RTS); */ + /* port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | MSVR_DTR) : + (port->MSVR & ~MSVR_DTR); */ + if (SIOLX_CRTSCTS(port->tty)) { + port->MSVR = (arg & TIOCM_RTS) ? + (port->MSVR | MSVR_DTR) : + (port->MSVR & ~MSVR_DTR); + } else { + port->MSVR = (arg & TIOCM_DTR) ? + (port->MSVR | MSVR_DTR): + (port->MSVR & ~MSVR_DTR); + } + break; + default: + return -EINVAL; + } + save_flags(flags); cli(); + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + siolx_out(bp, CD186x_MSVR, port->MSVR); + restore_flags(flags); + return 0; +} + + +static inline void siolx_send_break(struct siolx_port * port, unsigned long length) +{ + struct siolx_board *bp = port_Board(port); + unsigned long flags; + + save_flags(flags); cli(); + port->break_length = SIOLX_TPS / HZ * length; + port->COR2 |= COR2_ETC; + port->IER |= IER_TXRDY; + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + siolx_out(bp, CD186x_COR2, port->COR2); + siolx_out(bp, CD186x_IER, port->IER); + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_CORCHG2); + siolx_wait_CCR(bp); + restore_flags(flags); +} + + +static inline int siolx_set_serial_info(struct siolx_port * port, + struct serial_struct * newinfo) +{ + struct serial_struct tmp; + struct siolx_board *bp = port_Board(port); + int change_speed; + unsigned long flags; + int error; + + error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp)); + if (error) + return error; + + if (copy_from_user(&tmp, newinfo, sizeof(tmp))) + return -EFAULT; + +#if 0 + if ((tmp.irq != bp->irq) || + (tmp.port != bp->base) || + (tmp.type != PORT_CIRRUS) || + (tmp.baud_base != (SIOLX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) || + (tmp.custom_divisor != 0) || + (tmp.xmit_fifo_size != CD186x_NFIFO) || + (tmp.flags & ~SIOLX_LEGAL_FLAGS)) + return -EINVAL; +#endif + + change_speed = ((port->flags & ASYNC_SPD_MASK) != + (tmp.flags & ASYNC_SPD_MASK)); + change_speed |= (tmp.custom_divisor != port->custom_divisor); + + if (!capable(CAP_SYS_ADMIN)) { + if ((tmp.close_delay != port->close_delay) || + (tmp.closing_wait != port->closing_wait) || + ((tmp.flags & ~ASYNC_USR_MASK) != + (port->flags & ~ASYNC_USR_MASK))) + return -EPERM; + port->flags = ((port->flags & ~ASYNC_USR_MASK) | + (tmp.flags & ASYNC_USR_MASK)); + port->custom_divisor = tmp.custom_divisor; + } else { + port->flags = ((port->flags & ~ASYNC_FLAGS) | + (tmp.flags & ASYNC_FLAGS)); + port->close_delay = tmp.close_delay; + port->closing_wait = tmp.closing_wait; + port->custom_divisor = tmp.custom_divisor; + } + if (change_speed) { + save_flags(flags); cli(); + siolx_change_speed(bp, port); + restore_flags(flags); + } + return 0; +} + + +static inline int siolx_get_serial_info(struct siolx_port * port, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + struct siolx_board *bp = port_Board(port); + int error; + + error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)); + if (error) + return error; + + memset(&tmp, 0, sizeof(tmp)); + tmp.type = PORT_CIRRUS; + tmp.line = port->driverport; + tmp.port = bp->base; + tmp.irq = bp->irq; + tmp.flags = port->flags; + tmp.baud_base = (SIOLX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; + tmp.close_delay = port->close_delay * HZ/100; + tmp.closing_wait = port->closing_wait * HZ/100; + tmp.custom_divisor = port->custom_divisor; + tmp.xmit_fifo_size = CD186x_NFIFO; + if (copy_to_user(retinfo, &tmp, sizeof(tmp))) + return -EFAULT; + return 0; +} + + +static int siolx_ioctl(struct tty_struct * tty, struct file * filp, + unsigned int cmd, unsigned long arg) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + int error; + int retval; + + if (siolx_paranoia_check(port, tty->device, "siolx_ioctl")) + return -ENODEV; + + switch (cmd) { + case TCSBRK: /* SVID version: non-zero arg --> no break */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + if (!arg) + siolx_send_break(port, HZ/4); /* 1/4 second */ + return 0; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + siolx_send_break(port, arg ? arg*(HZ/10) : HZ/4); + return 0; + case TIOCGSOFTCAR: + error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long)); + if (error) + return error; + put_user(C_CLOCAL(tty) ? 1 : 0, + (unsigned long *) arg); + return 0; + case TIOCSSOFTCAR: + get_user(arg, (unsigned long *) arg); + tty->termios->c_cflag = + ((tty->termios->c_cflag & ~CLOCAL) | + (arg ? CLOCAL : 0)); + return 0; + case TIOCMGET: + error = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(unsigned int)); + if (error) + return error; + return siolx_get_modem_info(port, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return siolx_set_modem_info(port, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return siolx_get_serial_info(port, (struct serial_struct *) arg); + case TIOCSSERIAL: + return siolx_set_serial_info(port, (struct serial_struct *) arg); + default: + return -ENOIOCTLCMD; + } + return 0; +} + + +static void siolx_throttle(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + struct siolx_board *bp; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_throttle")) + return; + + bp = port_Board(port); + + save_flags(flags); cli(); + + /* Use DTR instead of RTS ! */ + if (SIOLX_CRTSCTS (tty)) + { + port->MSVR &= ~MSVR_DTR; + } + else + { + /* Auch!!! I think the system shouldn't call this then. */ + /* Or maybe we're supposed (allowed?) to do our side of hw + handshake anyway, even when hardware handshake is off. + When you see this in your logs, please report.... */ + printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n", + port_No (port)); + } + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + if (I_IXOFF(tty)) + { + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_SSCH2); + siolx_wait_CCR(bp); + } + siolx_out(bp, CD186x_MSVR, port->MSVR); + restore_flags(flags); +} + + +static void siolx_unthrottle(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + struct siolx_board *bp; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_unthrottle")) + return; + + bp = port_Board(port); + + save_flags(flags); cli(); + /* XXXX Use DTR INSTEAD???? */ + if (SIOLX_CRTSCTS(tty)) { + port->MSVR |= MSVR_DTR; + } /* Else clause: see remark in "siolx_throttle"... */ + + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + if (I_IXOFF(tty)) { + siolx_wait_CCR(bp); + siolx_out(bp, CD186x_CCR, CCR_SSCH1); + siolx_wait_CCR(bp); + } + siolx_out(bp, CD186x_MSVR, port->MSVR); + restore_flags(flags); +} + + +static void siolx_stop(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + struct siolx_board *bp; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_stop")) + return; + + bp = port_Board(port); + + save_flags(flags); cli(); + port->IER &= ~IER_TXRDY; + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + siolx_out(bp, CD186x_IER, port->IER); + restore_flags(flags); +} + + +static void siolx_start(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + struct siolx_board *bp; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_start")) + return; + + bp = port_Board(port); + + save_flags(flags); cli(); + if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { + port->IER |= IER_TXRDY; + siolx_out(bp, CD186x_CAR, port_No_by_chip(port)); + siolx_out(bp, CD186x_IER, port->IER); + } + restore_flags(flags); +} + + +/* + * This routine is called from the scheduler tqueue when the interrupt + * routine has signalled that a hangup has occurred. The path of + * hangup processing is: + * + * serial interrupt routine -> (scheduler tqueue) -> + * do_siolx_hangup() -> tty->hangup() -> siolx_hangup() + * + */ +static void do_siolx_hangup(void *private_) +{ + struct siolx_port *port = (struct siolx_port *) private_; + struct tty_struct *tty; + + tty = port->tty; + if (tty) + { + tty_hangup(tty); /* FIXME: module removal race here */ + } + MOD_DEC_USE_COUNT; +} + + +static void siolx_hangup(struct tty_struct * tty) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + struct siolx_board *bp; + + if (siolx_paranoia_check(port, tty->device, "siolx_hangup")) + return; + + bp = port_Board(port); + + siolx_shutdown_port(bp, port); + port->event = 0; + port->count = 0; + port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + port->tty = 0; + wake_up_interruptible(&port->open_wait); +} + + +static void siolx_set_termios(struct tty_struct * tty, struct termios * old_termios) +{ + struct siolx_port *port = (struct siolx_port *)tty->driver_data; + unsigned long flags; + + if (siolx_paranoia_check(port, tty->device, "siolx_set_termios")) + return; + + if (tty->termios->c_cflag == old_termios->c_cflag && + tty->termios->c_iflag == old_termios->c_iflag) + return; + + save_flags(flags); cli(); + siolx_change_speed(port_Board(port), port); + restore_flags(flags); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + siolx_start(tty); + } +} + + +static void do_siolx_bh(void) +{ + run_task_queue(&tq_siolx); +} + + +static void do_softint(void *private_) +{ + struct siolx_port *port = (struct siolx_port *) private_; + struct tty_struct *tty; + + if(!(tty = port->tty)) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + } +} + +static int siolx_finish_init_drivers(void) +{ + register struct siolx_board *bp; + register unsigned int count; + unsigned int maxport; + struct siolx_port *port; + struct siolx_port *lastport; + int error; + + bp = siolx_board_root; + + while(bp) + { + if(bp->chipnumber == 0) + { + maxport = SIOLX_NPORT; + } + else if((bp->boardtype == BD_16000C) && bp->reario) /* must be second chip of 16000C */ + { + maxport = SIOLX_NPORT/2; + } + else + { + maxport = SIOLX_NPORT; /* must be second chip of 16000P */ + } + + port = NULL; /* probably unnecessary */ + lastport = NULL; + for(count = 0; count < maxport; ++count) + { + port = (struct siolx_port*)kmalloc(sizeof(struct siolx_port), GFP_KERNEL); + if(port == NULL) + { + printk(KERN_ALERT + "siolx: Failed to create port structure on board %p.\n", bp); + break; /* no memory available */ + } + memset(port, 0, sizeof(struct siolx_port)); + + port->callout_termios = siolx_callout_driver.init_termios; + port->normal_termios = siolx_driver.init_termios; + port->magic = SIOLX_MAGIC; + port->tqueue.routine = do_softint; + port->tqueue.data = port; + port->tqueue_hangup.routine = do_siolx_hangup; + port->tqueue_hangup.data = port; + port->close_delay = 50 * HZ/100; + port->closing_wait = 3000 * HZ/100; + init_waitqueue_head(&port->open_wait); + init_waitqueue_head(&port->close_wait); + + port->board = bp; + port->driverport = NumSiolxPorts; + port->boardport = (count + (port->board->chipnumber*SIOLX_NPORT)); /* 0-16 */ + + if(count == 0) + { + bp->portlist = port; + } + else if(lastport) /* if count != 0 lastport should be non-null */ + { + lastport->next_by_board = port; + } + if(siolx_port_root == NULL) + { + siolx_port_root = port; + siolx_port_last = port; + } + else + { + siolx_port_last->next_by_global_list = port; + siolx_port_last = port; + } + lastport = port; + ++NumSiolxPorts; + } + bp = bp->next_by_global_list; + } + + siolx_driver.num = NumSiolxPorts; + + siolx_table = (struct tty_struct **) kmalloc(NumSiolxPorts*sizeof(struct tty_struct *), GFP_KERNEL); + if(siolx_table == NULL) + { + printk(KERN_ALERT "siolx: Could not allocate memory for siolx_table.\n"); + return 1; + } + memset(siolx_table, 0, NumSiolxPorts*sizeof(struct tty_struct *)); + + siolx_termios = (struct termios **) kmalloc(NumSiolxPorts*sizeof(struct termios *), GFP_KERNEL); + if(siolx_termios == NULL) + { + printk(KERN_ALERT "siolx: Could not allocate memory for siolx_termios.\n"); + return 1; + } + memset(siolx_termios, 0, NumSiolxPorts*sizeof(struct termios *)); + + siolx_termios_locked = (struct termios **) kmalloc(NumSiolxPorts*sizeof(struct termios *), GFP_KERNEL); + if(siolx_termios_locked == NULL) + { + printk(KERN_ALERT "siolx: Could not allocate memory for siolx_termios_locked.\n"); + return 1; + } + memset(siolx_termios_locked, 0, NumSiolxPorts*sizeof(struct termios *)); + + siolx_driver.table = siolx_table; /* will be changed */ + siolx_driver.termios = siolx_termios; /* will be changed */ + siolx_driver.termios_locked = siolx_termios_locked; /* will be changed */ + + if ((error = tty_register_driver(&siolx_driver))) + { + if(tmp_buf) + { + free_page((unsigned long)tmp_buf); + tmp_buf = 0; + } + printk(KERN_ERR "siolx: Couldn't register Aurora Asynchronous Adapter driver, error = %d\n", + error); + return 1; + } + if ((error = tty_register_driver(&siolx_callout_driver))) + { + if(tmp_buf) + { + free_page((unsigned long)tmp_buf); + tmp_buf = NULL; + } + tty_unregister_driver(&siolx_driver); + printk(KERN_ERR "siolx: Couldn't register Aurora Asynchronous Adapter callout driver, error = %d\n", + error); + return 1; + } + siolx_driver_registered = 1; + siolx_callout_driver_registered = 1; + return 0; /* success */ +} + +static int siolx_init_drivers(void) +{ + if (!(tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL))) + { + printk(KERN_ERR "siolx: Couldn't get free page.\n"); + return 1; + } + init_bh(siolx_bhindex, do_siolx_bh); + memset(&siolx_driver, 0, sizeof(siolx_driver)); + siolx_driver.magic = TTY_DRIVER_MAGIC; + + siolx_driver.driver_name = "aurasiolx"; + siolx_driver.name = "ttyS"; + siolx_driver.major = siolx_major; +#ifdef MODULE + siolx_driver.minor_start = siolx_minorstart; /* changed from command line */ +#else + siolx_driver.minor_start = GetMinorStart(); +#endif + siolx_driver.num = 0; /* will be changed */ + + siolx_driver.type = TTY_DRIVER_TYPE_SERIAL; + siolx_driver.subtype = SIOLX_TYPE_NORMAL; + siolx_driver.init_termios = tty_std_termios; + siolx_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + siolx_driver.flags = TTY_DRIVER_REAL_RAW; + siolx_driver.refcount = &siolx_refcount; + + siolx_driver.table = siolx_table; /* will be changed */ + siolx_driver.termios = siolx_termios; /* will be changed */ + siolx_driver.termios_locked = siolx_termios_locked; /* will be changed */ + + siolx_driver.open = siolx_open; + siolx_driver.close = siolx_close; + siolx_driver.write = siolx_write; + siolx_driver.put_char = siolx_put_char; + siolx_driver.flush_chars = siolx_flush_chars; + siolx_driver.write_room = siolx_write_room; + siolx_driver.chars_in_buffer = siolx_chars_in_buffer; + siolx_driver.flush_buffer = siolx_flush_buffer; + siolx_driver.ioctl = siolx_ioctl; + siolx_driver.throttle = siolx_throttle; + siolx_driver.unthrottle = siolx_unthrottle; + siolx_driver.set_termios = siolx_set_termios; + siolx_driver.stop = siolx_stop; + siolx_driver.start = siolx_start; + siolx_driver.hangup = siolx_hangup; + + siolx_callout_driver = siolx_driver; + siolx_callout_driver.name = "cuw"; + siolx_callout_driver.major = (siolx_major+1); + siolx_callout_driver.subtype = SIOLX_TYPE_CALLOUT; + + siolx_driver.read_proc = siolx_read_proc; + return 0; +} + + +static void siolx_release_drivers(void) +{ + unsigned int intr_val; + struct siolx_board *bp; + + if(tmp_buf) + { + free_page((unsigned long)tmp_buf); + tmp_buf = NULL; + } + if(siolx_driver_registered) + { + tty_unregister_driver(&siolx_driver); + siolx_driver_registered = 0; + } + if(siolx_callout_driver_registered) + { + tty_unregister_driver(&siolx_callout_driver); + siolx_callout_driver_registered = 0; + } + /* unallocate and turn off ints */ + for(intr_val = 0; intr_val < SIOLX_NUMINTS; ++intr_val) + { + if(SiolxIrqRoot[intr_val] != NULL) + { + for(bp = SiolxIrqRoot[intr_val]; bp != NULL; + bp = bp->next_by_interrupt) + { + SiolxShutdownBoard(bp); /* turn off int; release the plx vaddr space */ + } + free_irq(intr_val, &SiolxIrqRoot[intr_val]); + } + } + +} + +static void siolx_release_memory(void) +{ + register struct siolx_board *bp; + register struct siolx_port *port; + + while(siolx_board_root) + { + bp = siolx_board_root; + siolx_board_root = bp->next_by_global_list; + siolx_release_io_range(bp); /* releases the chip vaddr */ + kfree(bp); + } + while(siolx_port_root) + { + port = siolx_port_root; + if(port->xmit_buf) + { /* should have been done when port shutdown */ + free_page((unsigned long) port->xmit_buf); + port->xmit_buf = NULL; + } + siolx_port_root = port->next_by_global_list; + kfree(port); + } + if(siolx_table) + { + kfree(siolx_table); + siolx_table = NULL; + } + if(siolx_termios) + { + kfree(siolx_termios); + siolx_termios = NULL; + } + if(siolx_termios_locked) + { + kfree(siolx_termios_locked); + siolx_termios_locked = NULL; + } + +#ifdef SIOLX_TIMER + del_timer (&missed_irq_timer); +#endif +} + + +static void siolx_cleanup(void) +{ + siolx_release_drivers(); + siolx_release_memory(); +} + +/* + * This routine must be called by kernel at boot time + */ + +static int __init siolx_init(void) +{ + unsigned char bus; + unsigned char devfn; + struct siolx_board *bp; + struct siolx_board *bp2; + unsigned int boardcount; + struct pci_dev *pdev = NULL; + unsigned int ecntl; + unsigned int intr_val; + + printk(KERN_ALERT "aurora interea miseris mortalibus almam extulerat lucem\n"); + printk(KERN_ALERT " referens opera atque labores\n"); + printk(KERN_INFO "siolx: Siolx Aurora Asynchronous Adapter driver v" VERSION ", (c) Telford Tools, Inc.\n"); +#ifdef CONFIG_SIOLX_RTSCTS + printk (KERN_INFO "siolx: DTR/RTS pin is always RTS.\n"); +#else + printk (KERN_INFO "siolx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); +#endif + memset(SiolxIrqRoot, 0, sizeof(SiolxIrqRoot)); + tmp_buf = NULL; + siolx_board_root = NULL; /* clear out the global pointers */ + siolx_board_last = NULL; + siolx_port_root = NULL; + siolx_port_last = NULL; + NumSiolxPorts = 0; + siolx_table = NULL; /* make dynamic */ + siolx_termios = NULL; + siolx_termios_locked = NULL; + siolx_driver_registered = 0; + siolx_callout_driver_registered = 0; + + boardcount = 0; + + if (siolx_init_drivers()) + { + printk(KERN_INFO "siolx: Could not initialize drivers.\n"); + return -EIO; + } + + if (!pci_present()) + { + printk(KERN_INFO "siolx: Could not find PCI bus.\n"); + return -EIO; /* no PCI bus no Aurora cards */ + } + + while(1) + { + pdev = pci_find_device (siolx_vendor_id, siolx_device_id, pdev); + if (!pdev) + { + break; /* found no devices */ + } + + DEBUGPRINT((KERN_ALERT "%s\n", pdev->name)); + DEBUGPRINT((KERN_ALERT "subsystem vendor is %x.\n", + pdev->subsystem_vendor)); + DEBUGPRINT((KERN_ALERT "subsystem device is %x.\n", + pdev->subsystem_device)); + DEBUGPRINT((KERN_ALERT + "BAR0 = %lx\nBAR1 = %lx\nBAR2 = %lx\nBAR3 = %lx\nBAR4 = %lx\nBAR5 = %lx\n", + pci_resource_start(pdev, 0), + pci_resource_start(pdev, 1), + pci_resource_start(pdev, 2), + pci_resource_start(pdev, 3), + pci_resource_start(pdev, 4), + pci_resource_start(pdev, 5))); + DEBUGPRINT((KERN_ALERT + "LAS0 = %lx\nLAS1 = %lx\nLAS2 = %lx\nLAS3 = %lx\nLAS4 = %lx\nLAS5 = %lx\n", + pci_resource_len(pdev, 0), + pci_resource_len(pdev, 1), + pci_resource_len(pdev, 2), + pci_resource_len(pdev, 3), + pci_resource_len(pdev, 4), + pci_resource_len(pdev, 5))); + + if(pdev->subsystem_vendor == siolx_subsystem_vendor) + { + if(pdev->subsystem_device == siolx_subsystem_pci_device) + { + bp = (struct siolx_board*)kmalloc(sizeof(struct siolx_board), GFP_KERNEL); + if(bp == NULL) + { + printk(KERN_ALERT "siolx: Failed to create board structure on board %d.\n", boardcount); + break; /* no memory available */ + } + memset(bp, 0, sizeof(struct siolx_board)); + bp->boardtype = BD_8000P; + } + else if(pdev->subsystem_device == siolx_subsystem_cpci_device) + { + bp = (struct siolx_board*)kmalloc(sizeof(struct siolx_board), GFP_KERNEL); + if(bp == NULL) + { + printk(KERN_ALERT + "siolx: Failed to create board structure on board%p.\n", bp); + break; /* no memory available */ + } + memset(bp, 0, sizeof(struct siolx_board)); + bp->boardtype = BD_8000C; + } + else + { + continue; + } + } + else + { + continue; + } + + DEBUGPRINT((KERN_ALERT "siolx: interrupt is %i.\n", pdev->irq)); + bus = pdev->bus->number; + devfn = pdev->devfn; + DEBUGPRINT((KERN_ALERT "siolx: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn))); + + if (pci_enable_device(pdev)) + { + kfree(bp); + continue; /* enable failed */ + } + pci_set_master(pdev); + + bp->irq = pdev->irq; + SiolxResetBoard(bp, pdev); /* make sure the board is in a known state */ + if(bp->plx_vaddr == 0) + { + printk(KERN_ALERT "siolx: failed to remap plx address space.\n"); + kfree(bp); + continue; + } + bp->vaddr = (unsigned long) ioremap_nocache(pci_resource_start(pdev, 2), + pci_resource_len(pdev, 2)); + if(bp->vaddr) + { + bp->base = (bp->vaddr + MPASYNC_CHIP1_OFFSET); + bp->boardnumber = boardcount; + if (siolx_probe(bp)) /* failure is nonzero */ + { + iounmap((void*)bp->plx_vaddr); + bp->plx_vaddr = 0; + iounmap((void*)bp->vaddr); + bp->vaddr = 0; + kfree(bp); /* something wrong with board */ + continue; + } + intr_val = bp->irq; + if((intr_val < 0) || (intr_val >= SIOLX_NUMINTS)) + { + printk(KERN_ALERT "siolx: bad interrupt %i board %p.\n", intr_val, bp); + iounmap((void*)bp->plx_vaddr); /* but plx space was remapped */ + bp->plx_vaddr = 0; + iounmap((void*)bp->vaddr); /* release chip space */ + bp->vaddr = 0; + kfree(bp); /* release the board structure */ + continue; + } + bp->next_by_interrupt = SiolxIrqRoot[intr_val]; + SiolxIrqRoot[intr_val] = bp; + if(siolx_board_last == NULL) + { + siolx_board_root = bp; + siolx_board_last = bp; + } + else + { + siolx_board_last->next_by_global_list = bp; + siolx_board_last = bp; + } + bp->chipnumber = 0; + bp->intstatus = bp->plx_vaddr + PLX_ICSR; + bp->next_by_chain = bp; /* one item chain */ + ecntl = readl(bp->plx_vaddr + PLX_ECNTL); + boardcount++; /* added a board */ + if(pci_resource_len(pdev, 2) > MPASYNC_CHIP2_OFFSET) + { + ++(bp->boardtype); /* works because how types are defined 8000X --> 16000X*/ + if(bp->boardtype == BD_16000C) + { + if((ecntl & PLX_ECNTLUSERI) == 0) + { + bp->reario = 1; + } + } + bp2 = (struct siolx_board*)kmalloc(sizeof(struct siolx_board), GFP_KERNEL); + if(bp2 == NULL) + { + printk(KERN_ALERT + "siolx: Failed to create second board structure on board %p.\n", bp); + /* fall through because must turn on ints for other chip */ + } + else + { + memset(bp2, 0, sizeof(struct siolx_board)); /* unnecessary */ + *bp2 = *bp; /* note that all guys in chain point to same next_by interrupt */ + bp->next_by_chain = bp2; /* circular list */ + bp2->next_by_chain = bp;/* now chain two elements*/ + ++(bp2->chipnumber); /* chipnumber 1 */ + bp2->base = (bp2->vaddr + MPASYNC_CHIP2_OFFSET); + if(siolx_probe(bp2)) + { + printk(KERN_ALERT "siolx: Failed to probe second board structure on board %p.\n", bp); + kfree(bp2); + /* fall through because must turn on ints for other chip */ + /* don't release pci memory remap -- still works for other chip */ + } + else if(siolx_board_last == NULL) + { + siolx_board_root = bp2; /* this case should not occur */ + siolx_board_last = bp2; + } + else + { + siolx_board_last->next_by_global_list = bp2; + siolx_board_last = bp2; + } + /* don't increment boardnumber */ + } + } + } + else /* could not remap the cd18xx space */ + { + iounmap((void*)bp->plx_vaddr); /* but plx space was remapped */ + bp->plx_vaddr = 0; + kfree(bp); + } + } + if (boardcount == 0) + { + printk(KERN_INFO "siolx: No Aurora Asynchronous Adapter boards detected.\n"); + siolx_cleanup(); /* don't need any allocated memory */ + return -EIO; + } + if (siolx_finish_init_drivers()) + { + printk(KERN_INFO "siolx: Could not finish driver initialization.\n"); + siolx_cleanup(); + return -EIO; + } + + for(intr_val = 0; intr_val < SIOLX_NUMINTS; ++intr_val) /* trying to install as few int handlers as possible */ + { /* one for each group of boards (actually chips) on a given irq */ + if(SiolxIrqRoot[intr_val] != NULL) + { + if (request_irq(intr_val, siolx_interrupt, SA_SHIRQ, "siolx Aurora Asynchronous Adapter", + &SiolxIrqRoot[intr_val]) == 0) + /* interrupts on perboard basis + * cycle through chips and then + * ports */ + /* NOTE PLX INTS ARE OFF -- so turn them on */ + { + for(bp = SiolxIrqRoot[intr_val]; bp != NULL; bp = bp->next_by_interrupt) + { + writel(PLX_ICSRLCLINTPCI | PLX_ICSRPCIINTS, bp->plx_vaddr + PLX_ICSR); /* enable interrupts */ + } + } + else + { + printk(KERN_ALERT "siolx: Unable to get interrupt, board set up not complete %i.\n", intr_val); + /* no interrupts but on all lists */ + } + } + } + return 0; +} + +module_init(siolx_init); +module_exit(siolx_cleanup); +MODULE_DESCRIPTION("multiport Aurora asynchronous driver"); +MODULE_AUTHOR("Joachim Martillo "); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/cd1865/cdsiolx.h linux.21pre4-ac6/drivers/char/cd1865/cdsiolx.h --- linux.21pre4/drivers/char/cd1865/cdsiolx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/cd1865/cdsiolx.h 2003-02-07 15:49:47.000000000 +0000 @@ -0,0 +1,136 @@ +/* -*- linux-c -*- */ +/* + * This file was modified from + * linux/drivers/char/siolx_io8.h -- + * Siolx IO8+ multiport serial driver. + * + * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * Modifications (C) 2002 Telford Tools, Inc. (martillo@telfordtools.com) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * */ + +#ifndef __LINUX_SIOLX_H +#define __LINUX_SIOLX_H + +#include + +#ifdef __KERNEL__ + +#define SIOLX_NBOARD 8 + +/* eight ports per chip. */ +#define SIOLX_NPORT 8 +#define SIOLX_PORT(line) ((line) & (SIOLX_NPORT - 1)) + +#define MHz *1000000 /* I'm ashamed of myself. */ + +/* On-board oscillator frequency */ +#define SIOLX_OSCFREQ (33 MHz) +/* oregano is in /1 which mace 66Mhz is in /2 mode */ + +/* Ticks per sec. Used for setting receiver timeout and break length */ +#define SIOLX_TPS 4000 + +/* Yeah, after heavy testing I decided it must be 6. + * Sure, You can change it if needed. + */ +#define SIOLX_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ + +#define SIOLX_MAGIC 0x0907 + +#define SIOLX_CCR_TIMEOUT 10000 /* CCR timeout. You may need to wait upto + 10 milliseconds before the internal + processor is available again after + you give it a command */ +#define SIOLX_NUMINTS 32 + +struct siolx_board +{ + unsigned long flags; + unsigned long base; + unsigned char irq; + unsigned char DTR; + unsigned long vaddr; + unsigned long plx_vaddr; + unsigned long intstatus; + struct siolx_board *next_by_chain; /* chains are circular */ + struct siolx_board *next_by_interrupt; /* only chip 0 */ + struct siolx_board *next_by_global_list; /* all boards not circular */ + struct siolx_port *portlist; + struct pci_dev pdev; + unsigned int chipnumber; /* for 8000X this structure really defines the board + * for 16000X the chain corresponds to a board and each + * structure corresponds to a dhip on a single board */ + unsigned int boardnumber; /* same for all boards/chips in a board chain */ + unsigned int boardtype; + unsigned int chiptype; + unsigned int chiprev; + unsigned int reario; + unsigned int rj45; +}; + +#define DRIVER_DEBUG() (siolx_debug) +#define DEBUGPRINT(arg) if(DRIVER_DEBUG()) printk arg + +struct siolx_port +{ + int magic; + int baud_base; + int flags; + struct tty_struct * tty; + int count; + int blocked_open; + int event; + int timeout; + int close_delay; + long session; + long pgrp; + unsigned char * xmit_buf; + int custom_divisor; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct termios normal_termios; + struct termios callout_termios; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + struct tq_struct tqueue; + struct tq_struct tqueue_hangup; + short wakeup_chars; + short break_length; + unsigned short closing_wait; + unsigned char mark_mask; + unsigned char IER; + unsigned char MSVR; + unsigned char COR2; +#ifdef SIOLX_REPORT_OVERRUN + unsigned long overrun; +#endif +#ifdef SIOLX_REPORT_FIFO + unsigned long hits[10]; +#endif + struct siolx_port *next_by_global_list; + struct siolx_port *next_by_board; + struct siolx_board *board; + unsigned int boardport; /* relative to chain 0-15 for 16000X */ + unsigned int driverport; /* maps to minor device number */ +}; + +#endif /* __KERNEL__ */ +#endif /* __LINUX_SIOLX_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/cd1865/Makefile linux.21pre4-ac6/drivers/char/cd1865/Makefile --- linux.21pre4/drivers/char/cd1865/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/cd1865/Makefile 2003-01-09 01:03:03.000000000 +0000 @@ -0,0 +1,27 @@ +# Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. + +# File: drivers/net/WAN/atiXX50/Makefile +# +# Makefile for the Aurora ESSC based cards +# Specifically the 2520, 4020, 4520, 8520 +# + +all: SILX.o + +O_TARGET := SILX.o + +obj-y := cd1865.o +obj-m := $(O_TARGET) + +EXTRA_CFLAGS += -I. + +include $(TOPDIR)/Rules.make + +clean: + rm -f core *.o *.a *.s *~ + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/cd1865/plx9060.h linux.21pre4-ac6/drivers/char/cd1865/plx9060.h --- linux.21pre4/drivers/char/cd1865/plx9060.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/cd1865/plx9060.h 2003-01-09 01:07:57.000000000 +0000 @@ -0,0 +1,97 @@ +#ifndef _PLX9060_H_ +#define _PLX9060_H_ +/* + * Aurora Cirrus CL-CD180/1865 Async Driver (sio16) + * + * This module contains the definitions for the PLX + * 9060SD PCI controller chip. + * + * COPYRIGHT (c) 1996-1998 BY AURORA TECHNOLOGIES, INC., WALTHAM, MA. + * Modifications Copyright (C) 2002 By Telford Tools, Inc., Boston, MA. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + * file: plx9060.h + * author: cmw + * created: 11/21/1996 + * info: $Id: plx9060.h,v 1.2 2002/06/11 02:50:02 martillo Exp $ + */ + +/* + * $Log: plx9060.h,v $ + * Revision 1.2 2002/06/11 02:50:02 martillo + * using silx_ and SILX_ instead of sx_ and SX_ + * + * Revision 1.1 2002/05/21 17:30:16 martillo + * first pass for the sio16 driver. + * + * Revision 1.4 1999/02/12 15:38:13 bkd + * Changed PLX_ECNTUSER0 to PLX_ECNTLUSERO and added PLX_ECNTLUSERI. + * + * Revision 1.3 1998/03/23 19:35:42 bkd + * Added definitions for all of the missing PLX9060SD registers. + * + * Revision 1.2 1998/03/13 21:02:16 bkd + * Updated copyright date to include 1998. + * + * Revision 1.1 1996/11/23 01:07:46 bkd + * cmw/bkd (PCI port): + * Initial check-in. + * + */ + +/* + * Register definitions + */ + +#define PLX_LAS0RR 0x00 +#define PLX_LAS0BAR 0x04 +#define PLX_LAR 0x08 +#define PLX_ENDR 0x0c +#define PLX_EROMRR 0x10 +#define PLX_EROMBAR 0x14 +#define PLX_LAS0BRD 0x18 +#define PLX_LAS1RR 0x30 +#define PLX_LAS1BAR 0x34 +#define PLX_LAS1BRD 0x38 + +#define PLX_MBR0 0x40 +#define PLX_MBR1 0x44 +#define PLX_MBR2 0x48 +#define PLX_MBR3 0x4c +#define PLX_PCI2LCLDBR 0x60 +#define PLX_LCL2PCIDBR 0x64 +#define PLX_ICSR 0x68 +#define PLX_ECNTL 0x6c + +/* + * Bit definitions + */ + +#define PLX_ECNTLUSERO 0x00010000 /* turn on user output */ +#define PLX_ECNTLUSERI 0x00020000 /* user input */ +#define PLX_ECNTLLDREG 0x20000000 /* reload configuration registers */ +#define PLX_ECNTLLCLRST 0x40000000 /* local bus reset */ +#define PLX_ECNTLINITSTAT 0x80000000 /* mark board init'ed */ + + +#define PLX_ICSRLSERR_ENA 0x00000001 /* enable local bus LSERR# */ +#define PLX_ICSRLSERRP_ENA 0x00000002 /* enable local bus LSERR# PCI */ +#define PLX_ICSRPCIINTS 0x00000100 /* enable PCI interrupts */ +#define PLX_ICSRLCLINTPCI 0x00000800 +#define PLX_ICSRINTACTIVE 0x00008000 /* RO: local interrupt active */ + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/cd1865/siolx.h linux.21pre4-ac6/drivers/char/cd1865/siolx.h --- linux.21pre4/drivers/char/cd1865/siolx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/cd1865/siolx.h 2003-01-09 01:13:34.000000000 +0000 @@ -0,0 +1,94 @@ +/* -*- linux-c -*- */ +#ifndef _SIOLX_H_ +#define _SIOLX_H_ + +/* + * Modifications Copyright (C) 2002 By Telford Tools, Inc., Boston, MA. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + */ + +#define AURASUBSYSTEM_VENDOR_ID 0x125c +#define AURASUBSYSTEM_MPASYNCPCI 0x0640 +#define AURASUBSYSTEM_MPASYNCcPCI 0x0641 + +/* + * Aurora Cirrus CL-CD180/1865 Async Driver (sio16) + * + */ + +/* + * Register sets. These must match the order of the registers specified + * in the prom on the board! + */ + +#define MPASYNC_REG_CSR 1 +#define MPASYNC_REG_CD 2 + +#define MPASYNC_CHIP1_OFFSET 0x080 +#define MPASYNC_CHIP2_OFFSET 0x100 + +#define MPASYNC_REG_NO_OBP_CSR 1 +#define MPASYNC_REG_NO_OBP_CD 3 + +#define TX_FIFO 0x8 /* how deep is the chip fifo */ + +/* + * state flags + */ + +/* + * the following defines the model types + */ + +#define OREGANO_MODEL(mod) ((mod) == BD_16000P || (mod) == BD_8000P) +#define MACE_MODEL(mod) ((mod) == BD_16000C || (mod) == BD_8000C) + +/* + * I/O options: + */ + +#define MACE8_STD 0x0 /* 8000CP -- standard I/O */ +#define MACE8_RJ45 0x1 /* 8000CP -- rear RJ45 I/O */ + +#define MACE16_STD 0x0 /* 16000CP -- standard I/O */ +#define MACE16_RJ45 0x1 /* 16000CP -- rear RJ45 I/O */ + +#define SE2_CLK ((unsigned int) 11059200) /* 11.0592 MHz */ +#define SE_CLK ((unsigned int) 14745600) /* 14.7456 MHz */ +#define SE3_CLK ((unsigned int) 33000000) /* 33.3333 MHz */ + +/* divide x by y, rounded */ +#define ROUND_DIV(x, y) (((x) + ((y) >> 1)) / (y)) + +/* Calculate a 16 bit baud rate divisor for the given "encoded" + * (multiplied by two) baud rate. + */ + +/* chip types: */ +#define CT_UNKNOWN 0x0 /* unknown */ +#define CT_CL_CD180 0x1 /* Cirrus Logic CD-180 */ +#define CT_CL_CD1864 0x2 /* Cirrus Logic CD-1864 */ +#define CT_CL_CD1865 0x3 /* Cirrus Logic CD-1864 */ + +/* chip revisions: */ +#define CR_UNKNOWN 0x0 /* unknown */ +#define CR_REVA 0x1 /* revision A */ +#define CR_REVB 0x2 /* revision B */ +#define CR_REVC 0x3 /* revision C */ +/* ...and so on ... */ + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/Config.in linux.21pre4-ac6/drivers/char/Config.in --- linux.21pre4/drivers/char/Config.in 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/Config.in 2003-01-28 16:43:43.000000000 +0000 @@ -35,6 +35,7 @@ fi bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then + tristate ' Aurora Technology, Inc. asynchronous PCI cards V2' CONFIG_ATI_CD1865 tristate ' Computone IntelliPort Plus serial support' CONFIG_COMPUTONE tristate ' Comtrol Rocketport support' CONFIG_ROCKETPORT tristate ' Cyclades async mux support' CONFIG_CYCLADES @@ -212,6 +213,7 @@ bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT tristate ' Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT + tristate ' ALi M7101 PMU on ALi 1535D+ Watchdog Timer' CONFIG_ALIM1535_WDT tristate ' ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT tristate ' AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG @@ -258,7 +260,7 @@ dep_tristate 'NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 if [ "$CONFIG_X86" = "y" -o "$CONFIG_X86_64" = "y" ]; then - dep_tristate 'AMD 768 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI + dep_tristate 'AMD 768/8111 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI fi if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/Config.in linux.21pre4-ac6/drivers/char/drm/Config.in --- linux.21pre4/drivers/char/drm/Config.in 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/Config.in 2003-02-19 16:04:39.000000000 +0000 @@ -6,9 +6,9 @@ # tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX -#tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA +tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA tristate ' ATI Rage 128' CONFIG_DRM_R128 -dep_tristate ' ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP +tristate ' ATI Radeon' CONFIG_DRM_RADEON dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP dep_mbool ' Enabled XFree 4.1 ioctl interface by default' CONFIG_DRM_I810_XFREE_41 $CONFIG_DRM_I810 dep_tristate ' Intel 830M' CONFIG_DRM_I830 $CONFIG_AGP diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_agpsupport.h linux.21pre4-ac6/drivers/char/drm/drm_agpsupport.h --- linux.21pre4/drivers/char/drm/drm_agpsupport.h 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_agpsupport.h 2003-02-21 16:32:35.000000000 +0000 @@ -283,8 +283,6 @@ break; case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break; - case VIA_APOLLO_P4X400: head->chipset = "VIA Apollo P4X400"; - break; case SIS_GENERIC: head->chipset = "SiS"; break; case AMD_GENERIC: head->chipset = "AMD"; break; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_context.h linux.21pre4-ac6/drivers/char/drm/drm_context.h --- linux.21pre4/drivers/char/drm/drm_context.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_context.h 2003-02-21 16:32:35.000000000 +0000 @@ -554,7 +554,7 @@ /* Allocate a new queue */ down(&dev->struct_sem); - queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); + queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES); memset(queue, 0, sizeof(*queue)); atomic_set(&queue->use_count, 1); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_dma.h linux.21pre4-ac6/drivers/char/drm/drm_dma.h --- linux.21pre4/drivers/char/drm/drm_dma.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_dma.h 2003-02-21 16:32:35.000000000 +0000 @@ -30,7 +30,7 @@ */ #include "drmP.h" - +#include "drm_os_linux.h" #include /* For task queue support */ #ifndef __HAVE_DMA_WAITQUEUE @@ -537,8 +537,16 @@ dev->tq.data = dev; #endif +#if __HAVE_VBL_IRQ + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init( &dev->vbl_lock ); + + INIT_LIST_HEAD( &dev->vbl_sigs.head ); +#endif + /* Before installing handler */ - DRIVER_PREINSTALL(); + DRM(driver_irq_preinstall)(dev); /* Install handler */ ret = request_irq( dev->irq, DRM(dma_service), @@ -551,7 +559,7 @@ } /* After installing handler */ - DRIVER_POSTINSTALL(); + DRM(driver_irq_postinstall)(dev); return 0; } @@ -570,7 +578,7 @@ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - DRIVER_UNINSTALL(); + DRM(driver_irq_uninstall)( dev ); free_irq( irq, dev ); @@ -597,6 +605,117 @@ } } +#if __HAVE_VBL_IRQ + +int DRM(wait_vblank)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret = 0; + unsigned int flags; + + if (!dev->irq) + return -EINVAL; + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) { + case _DRM_VBLANK_RELATIVE: + vblwait.request.sequence += atomic_read( &dev->vbl_received ); + case _DRM_VBLANK_ABSOLUTE: + break; + default: + return -EINVAL; + } + + flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; + + if ( flags & _DRM_VBLANK_SIGNAL ) { + unsigned long irqflags; + drm_vbl_sig_t *vbl_sig = kmalloc( sizeof( drm_vbl_sig_t ), GFP_KERNEL ); + + if ( !vbl_sig ) + return -ENOMEM; + + memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) ); + + vbl_sig->sequence = vblwait.request.sequence; + vbl_sig->info.si_signo = vblwait.request.signal; + vbl_sig->task = current; + + vblwait.reply.sequence = atomic_read( &dev->vbl_received ); + + /* Hook signal entry into list */ + spin_lock_irqsave( &dev->vbl_lock, irqflags ); + + list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head ); + + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + } else { + ret = DRM(vblank_wait)( dev, &vblwait.request.sequence ); + + do_gettimeofday( &now ); + vblwait.reply.tval_sec = now.tv_sec; + vblwait.reply.tval_usec = now.tv_usec; + } + + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} + +void DRM(vbl_send_signals)( drm_device_t *dev ) +{ + struct list_head *entry, *tmp; + drm_vbl_sig_t *vbl_sig; + unsigned int vbl_seq = atomic_read( &dev->vbl_received ); + unsigned long flags; + + spin_lock_irqsave( &dev->vbl_lock, flags ); + + list_for_each_safe( entry, tmp, &dev->vbl_sigs.head ) { + + vbl_sig = (drm_vbl_sig_t *) entry; + + if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + + vbl_sig->info.si_code = atomic_read( &dev->vbl_received ); + send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); + + list_del( entry ); + + kfree( entry ); + } + } + + spin_unlock_irqrestore( &dev->vbl_lock, flags ); +} + +#endif /* __HAVE_VBL_IRQ */ + +#else + +int DRM(control)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_control_t ctl; + + if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) + return -EFAULT; + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + case DRM_UNINST_HANDLER: + return 0; + default: + return -EINVAL; + } +} + #endif /* __HAVE_DMA_IRQ */ #endif /* __HAVE_DMA */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_drv.h linux.21pre4-ac6/drivers/char/drm/drm_drv.h --- linux.21pre4/drivers/char/drm/drm_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_drv.h 2003-01-31 11:54:14.000000000 +0000 @@ -115,18 +115,34 @@ #ifndef DRIVER_FOPS #define DRIVER_FOPS \ static struct file_operations DRM(fops) = { \ - owner: THIS_MODULE, \ - open: DRM(open), \ - flush: DRM(flush), \ - release: DRM(release), \ - ioctl: DRM(ioctl), \ - mmap: DRM(mmap), \ - read: DRM(read), \ - fasync: DRM(fasync), \ - poll: DRM(poll), \ + .owner = THIS_MODULE, \ + .open = DRM(open), \ + .flush = DRM(flush), \ + .release = DRM(release), \ + .ioctl = DRM(ioctl), \ + .mmap = DRM(mmap), \ + .read = DRM(read), \ + .fasync = DRM(fasync), \ + .poll = DRM(poll), \ } #endif +#ifndef MODULE +/* DRM(options) is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ +/* Use an additional macro to avoid preprocessor troubles */ +#define DRM_OPTIONS_FUNC DRM(options) +static int __init DRM(options)( char *str ) +{ + DRM(parse_options)( str ); + return 1; +} + +__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC ); +#undef DRM_OPTIONS_FUNC +#endif /* * The default number of instances (minor numbers) to initialize. @@ -187,10 +203,8 @@ /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ -#if __HAVE_DMA_IRQ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, #endif -#endif #if __REALLY_HAVE_AGP [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 }, @@ -208,6 +222,10 @@ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 }, #endif +#if __HAVE_VBL_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 }, +#endif + DRIVER_IOCTLS }; @@ -292,7 +310,7 @@ dev->map_count = 0; dev->vmalist = NULL; - dev->lock.hw_lock = NULL; + dev->sigdata.lock = dev->lock.hw_lock = NULL; init_waitqueue_head( &dev->lock.lock_queue ); dev->queue_count = 0; dev->queue_reserved = 0; @@ -477,7 +495,7 @@ DRM(dma_takedown)( dev ); #endif if ( dev->lock.hw_lock ) { - dev->lock.hw_lock = NULL; /* SHM removed */ + dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.pid = 0; wake_up_interruptible( &dev->lock.lock_queue ); } @@ -705,7 +723,7 @@ int i; for (i = 0; i < DRM(numdevs); i++) { - if (MINOR(inode->i_rdev) == DRM(minor)[i]) { + if (minor(inode->i_rdev) == DRM(minor)[i]) { dev = &(DRM(device)[i]); break; } @@ -747,8 +765,8 @@ * Begin inline drm_release */ - DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count ); + DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count ); if ( dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && @@ -873,8 +891,9 @@ atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; - DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n", - current->pid, cmd, nr, dev->device, priv->authenticated ); + DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", + current->pid, cmd, nr, (long)dev->device, + priv->authenticated ); if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = -EINVAL; @@ -1027,6 +1046,25 @@ atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); +#if __HAVE_KERNEL_CTX_SWITCH + /* We no longer really hold it, but if we are the next + * agent to request it then we should just be able to + * take it immediately and not eat the ioctl. + */ + dev->lock.pid = 0; + { + __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; + unsigned int old, new, prev, ctx; + + ctx = lock.context; + do { + old = *plock; + new = ctx; + prev = cmpxchg(plock, old, new); + } while (prev != old); + } + wake_up_interruptible(&dev->lock.lock_queue); +#else DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); #if __HAVE_DMA_SCHEDULE @@ -1041,6 +1079,7 @@ DRM_ERROR( "\n" ); } } +#endif /* !__HAVE_KERNEL_CTX_SWITCH */ unblock_all_signals(); return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_fops.h linux.21pre4-ac6/drivers/char/drm/drm_fops.h --- linux.21pre4/drivers/char/drm/drm_fops.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_fops.h 2003-02-21 16:32:35.000000000 +0000 @@ -37,7 +37,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) { - kdev_t minor = MINOR(inode->i_rdev); + int minor = minor(inode->i_rdev); drm_file_t *priv; if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ @@ -94,25 +94,8 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count); - if ( dev->lock.hw_lock && - _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.pid == current->pid ) { - DRM_DEBUG( "Process %d closed fd, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); -#if __HAVE_RELEASE - DRIVER_RELEASE(); -#endif - DRM(lock_free)( dev, &dev->lock.hw_lock->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); - - /* FIXME: may require heavy-handed reset of - hardware at this point, possibly - processed via a callback to the X - server. */ - } + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count); return 0; } @@ -122,7 +105,7 @@ drm_device_t *dev = priv->dev; int retcode; - DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device); + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device); retcode = fasync_helper(fd, filp, on, &dev->buf_async); if (retcode < 0) return retcode; return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm.h linux.21pre4-ac6/drivers/char/drm/drm.h --- linux.21pre4/drivers/char/drm/drm.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm.h 2003-02-21 16:32:35.000000000 +0000 @@ -38,10 +38,27 @@ #if defined(__linux__) #include #include /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) && defined(XFree86Server) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl #include -#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #endif #define XFREE86_VERSION(major,minor,patch,snap) \ @@ -84,6 +101,10 @@ /* Warning: If you change this structure, make sure you change * XF86DRIClipRectRec in the server as well */ +/* KW: Actually it's illegal to change either for + * backwards-compatibility reasons. + */ + typedef struct drm_clip_rect { unsigned short x1; unsigned short y1; @@ -332,6 +353,32 @@ int funcnum; } drm_irq_busid_t; +typedef enum { + _DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */ + _DRM_VBLANK_SIGNAL = 0x80000000 /* Send signal instead of blocking */ +} drm_vblank_seq_type_t; + +#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL + +struct drm_wait_vblank_request { + drm_vblank_seq_type_t type; + unsigned int sequence; + unsigned long signal; +}; + +struct drm_wait_vblank_reply { + drm_vblank_seq_type_t type; + unsigned int sequence; + long tval_sec; + long tval_usec; +}; + +typedef union drm_wait_vblank { + struct drm_wait_vblank_request request; + struct drm_wait_vblank_reply reply; +} drm_wait_vblank_t; + typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; @@ -371,10 +418,9 @@ #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) #define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) @@ -427,86 +473,10 @@ #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) -/* MGA specific ioctls */ -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) -#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42) -#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) -#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) - -/* i810 specific ioctls */ -#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) -#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) -#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43) -#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44) -#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) -#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) -#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) -#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) -#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t) -#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a) -#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b) -#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t) -#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d ) - - -/* Rage 128 specific ioctls */ -#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) -#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) -#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) -#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) -#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) -#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) -#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) - -/* Radeon specific ioctls */ -#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) -#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) -#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) -#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) -#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) -#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) -#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) -#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) -#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) -#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) -#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) -#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) - -/* SiS specific ioctls */ -#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) -#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) -#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t) -#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t) -#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) -#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) -#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) -#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) - -/* I830 specific ioctls */ -#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t) -#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t) -#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t) -#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43) -#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44) -#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t) -#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) -#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) -#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t) + +/* Device specfic ioctls should only be in their respective headers + * The device specific ioctl range is 0x40 to 0x79. */ +#define DRM_COMMAND_BASE 0x40 #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_ioctl.h linux.21pre4-ac6/drivers/char/drm/drm_ioctl.h --- linux.21pre4/drivers/char/drm/drm_ioctl.h 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_ioctl.h 2003-02-21 16:32:35.000000000 +0000 @@ -111,7 +111,7 @@ do { struct pci_dev *pci_dev; - int b, d, f; + int domain, b, d, f; char *p; for(p = dev->unique; p && *p && *p != ':'; p++); @@ -123,6 +123,27 @@ f = (int)simple_strtoul(p+1, &p, 10); if (*p) break; + domain = b >> 8; + b &= 0xff; + +#ifdef __alpha__ + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + pci_dev; + pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) { + struct pci_controller *hose = pci_dev->sysdata; + + if (hose->index == domain) { + b += hose->bus->number; + break; + } + } +#endif + pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); if (pci_dev) { dev->pdev = pci_dev; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_lock.h linux.21pre4-ac6/drivers/char/drm/drm_lock.h --- linux.21pre4/drivers/char/drm/drm_lock.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_lock.h 2003-02-21 16:32:35.000000000 +0000 @@ -236,7 +236,7 @@ /* Allow signal delivery if lock isn't held */ - if (!_DRM_LOCK_IS_HELD(s->lock->lock) + if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock) || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1; /* Otherwise, set flag to force call to diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_memory.h linux.21pre4-ac6/drivers/char/drm/drm_memory.h --- linux.21pre4/drivers/char/drm/drm_memory.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_memory.h 2003-02-21 16:32:35.000000000 +0000 @@ -313,6 +313,29 @@ return pt; } +void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) +{ + void *pt; + + if (!size) { + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, + "Mapping 0 bytes at 0x%08lx\n", offset); + return NULL; + } + + if (!(pt = ioremap_nocache(offset, size))) { + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; + spin_unlock(&DRM(mem_lock)); + return NULL; + } + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; + spin_unlock(&DRM(mem_lock)); + return pt; +} + void DRM(ioremapfree)(void *pt, unsigned long size) { int alloc_count; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_os_linux.h linux.21pre4-ac6/drivers/char/drm/drm_os_linux.h --- linux.21pre4/drivers/char/drm/drm_os_linux.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/drm/drm_os_linux.h 2003-02-07 15:49:47.000000000 +0000 @@ -0,0 +1,56 @@ +#define __NO_VERSION__ + +#include /* For task queue support */ +#include + + +/* For data going from/to the kernel through the ioctl argument */ +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ + if ( copy_from_user(&arg1, arg2, arg3) ) \ + return -EFAULT +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ + if ( copy_to_user(arg1, &arg2, arg3) ) \ + return -EFAULT + + +#warning the author of this code needs to read up on list_entry +#define DRM_GETSAREA() \ +do { \ + struct list_head *list; \ + list_for_each( list, &dev->maplist->head ) { \ + drm_map_list_t *entry = (drm_map_list_t *)list; \ + if ( entry->map && \ + entry->map->type == _DRM_SHM && \ + (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \ + dev_priv->sarea = entry->map; \ + break; \ + } \ + } \ +} while (0) + +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +do { \ + DECLARE_WAITQUEUE(entry, current); \ + unsigned long end = jiffies + (timeout); \ + add_wait_queue(&(queue), &entry); \ + \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if((signed)(end - jiffies) <= 0) { \ + ret = -EBUSY; \ + break; \ + } \ + schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \ + if (signal_pending(current)) { \ + ret = -EINTR; \ + break; \ + } \ + } \ + set_current_state(TASK_RUNNING); \ + remove_wait_queue(&(queue), &entry); \ +} while (0) + + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drmP.h linux.21pre4-ac6/drivers/char/drm/drmP.h --- linux.21pre4/drivers/char/drm/drmP.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drmP.h 2003-02-21 16:32:35.000000000 +0000 @@ -53,6 +53,7 @@ #include #include /* For (un)lock_kernel */ #include +#include #if defined(__alpha__) || defined(__powerpc__) #include /* For pte_wrprotect */ #endif @@ -71,10 +72,7 @@ #include #include "drm.h" -/* page_to_bus for earlier kernels, not optimal in all cases */ -#ifndef page_to_bus -#define page_to_bus(page) ((unsigned int)(virt_to_bus(page_address(page)))) -#endif +#include "drm_os_linux.h" /* DRM template customization defaults */ @@ -209,6 +207,7 @@ (unsigned long)(n),sizeof(*(ptr)))) #endif /* i386 & alpha */ #endif +#define __REALLY_HAVE_SG (__HAVE_SG) /* Begin the DRM... */ @@ -251,41 +250,58 @@ #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) -#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) + /* Backward compatibility section */ +#ifndef minor +#define minor(x) MINOR((x)) +#endif -/* Macros to make printk easier */ +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif -#if ( __GNUC__ > 2 ) -#define DRM_ERROR(fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__, ##arg) -#define DRM_MEM_ERROR(area, fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \ - DRM(mem_stats)[area].name , ##arg) -#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) +#ifndef pte_offset_map +#define pte_offset_map pte_offset +#define pte_unmap(pte) +#endif -#if DRM_DEBUG_CODE -#define DRM_DEBUG(fmt, arg...) \ - do { \ - if ( DRM(flags) & DRM_FLAG_DEBUG ) \ - printk(KERN_DEBUG \ - "[" DRM_NAME ":%s] " fmt , \ - __FUNCTION__, \ - ##arg); \ - } while (0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) +static inline struct page * vmalloc_to_page(void * vmalloc_addr) +{ + unsigned long addr = (unsigned long) vmalloc_addr; + struct page *page = NULL; + pgd_t *pgd = pgd_offset_k(addr); + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, addr); + if (!pmd_none(*pmd)) { + ptep = pte_offset_map(pmd, addr); + pte = *ptep; + if (pte_present(pte)) + page = pte_page(pte); + pte_unmap(ptep); + } + } + return page; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define DRM_RPR_ARG(vma) #else -#define DRM_DEBUG(fmt, arg...) do { } while (0) +#define DRM_RPR_ARG(vma) vma, #endif -#else /* Gcc 2.x */ -/* Work around a C preprocessor bug */ +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) /* Macros to make printk easier */ #define DRM_ERROR(fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg) + printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg) #define DRM_MEM_ERROR(area, fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \ + printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \ DRM(mem_stats)[area].name , ##arg) #define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) @@ -294,16 +310,13 @@ do { \ if ( DRM(flags) & DRM_FLAG_DEBUG ) \ printk(KERN_DEBUG \ - "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ - ##arg); \ + "[" DRM_NAME ":%s] " fmt , \ + __FUNCTION__ , ##arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) #endif -#endif /* Gcc 2.x */ - - #define DRM_PROC_LIMIT (PAGE_SIZE-80) #define DRM_PROC_PRINT(fmt, arg...) \ @@ -318,6 +331,9 @@ #define DRM_IOREMAP(map) \ (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) +#define DRM_IOREMAP_NOCACHE(map) \ + (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size) + #define DRM_IOREMAPFREE(map) \ do { \ if ( (map)->handle && (map)->size ) \ @@ -599,6 +615,17 @@ drm_map_t *map; } drm_map_list_t; +#if __HAVE_VBL_IRQ + +typedef struct drm_vbl_sig { + struct list_head head; + unsigned int sequence; + struct siginfo info; + struct task_struct *task; +} drm_vbl_sig_t; + +#endif + typedef struct drm_device { const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ @@ -658,6 +685,12 @@ int last_context; /* Last current context */ unsigned long last_switch; /* jiffies at last context switch */ struct tq_struct tq; +#if __HAVE_VBL_IRQ + wait_queue_head_t vbl_queue; + atomic_t vbl_received; + spinlock_t vbl_lock; + drm_vbl_sig_t vbl_sigs; +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -725,16 +758,16 @@ /* Mapping support (drm_vm.h) */ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern void DRM(vm_open)(struct vm_area_struct *vma); extern void DRM(vm_close)(struct vm_area_struct *vma); extern void DRM(vm_shm_close)(struct vm_area_struct *vma); @@ -756,6 +789,7 @@ extern void DRM(free_pages)(unsigned long address, int order, int area); extern void *DRM(ioremap)(unsigned long offset, unsigned long size); +extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size); extern void DRM(ioremapfree)(void *pt, unsigned long size); #if __REALLY_HAVE_AGP @@ -885,6 +919,15 @@ extern int DRM(irq_uninstall)( drm_device_t *dev ); extern void DRM(dma_service)( int irq, void *device, struct pt_regs *regs ); +extern void DRM(driver_irq_preinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_postinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_uninstall)( drm_device_t *dev ); +#if __HAVE_VBL_IRQ +extern int DRM(wait_vblank)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); +extern void DRM(vbl_send_signals)( drm_device_t *dev ); +#endif #if __HAVE_DMA_IRQ_BH extern void DRM(dma_immediate_bh)( void *dev ); #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_proc.h linux.21pre4-ac6/drivers/char/drm/drm_proc.h --- linux.21pre4/drivers/char/drm/drm_proc.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_proc.h 2003-02-21 16:32:35.000000000 +0000 @@ -147,10 +147,10 @@ *eof = 0; if (dev->unique) { - DRM_PROC_PRINT("%s 0x%x %s\n", - dev->name, dev->device, dev->unique); + DRM_PROC_PRINT("%s 0x%lx %s\n", + dev->name, (long)dev->device, dev->unique); } else { - DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device); + DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device); } if (len > request + offset) return request; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_sarea.h linux.21pre4-ac6/drivers/char/drm/drm_sarea.h --- linux.21pre4/drivers/char/drm/drm_sarea.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/drm/drm_sarea.h 2003-01-06 17:25:49.000000000 +0000 @@ -0,0 +1,57 @@ +/* sarea.h -- SAREA definitions -*- linux-c -*- + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Michel Dänzer + */ + +#ifndef _DRM_SAREA_H_ +#define _DRM_SAREA_H_ + +#define SAREA_MAX_DRAWABLES 256 + +typedef struct _drm_sarea_drawable_t { + unsigned int stamp; + unsigned int flags; +} drm_sarea_drawable_t; + +typedef struct _dri_sarea_frame_t { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + unsigned int fullscreen; +} drm_sarea_frame_t; + +typedef struct _drm_sarea_t { + /* first thing is always the drm locking structure */ + drm_hw_lock_t lock; + /* NOT_DONE: Use readers/writer lock for drawable_lock */ + drm_hw_lock_t drawable_lock; + drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; + drm_sarea_frame_t frame; + drm_context_t dummy_context; +} drm_sarea_t; + +#endif /* _DRM_SAREA_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_stub.h linux.21pre4-ac6/drivers/char/drm/drm_stub.h --- linux.21pre4/drivers/char/drm/drm_stub.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_stub.h 2003-02-21 16:32:35.000000000 +0000 @@ -48,7 +48,7 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp) { - int minor = MINOR(inode->i_rdev); + int minor = minor(inode->i_rdev); int err = -ENODEV; struct file_operations *old_fops; @@ -65,8 +65,8 @@ } static struct file_operations DRM(stub_fops) = { - owner: THIS_MODULE, - open: DRM(stub_open) + .owner = THIS_MODULE, + .open = DRM(stub_open) }; static int DRM(stub_getminor)(const char *name, struct file_operations *fops, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/drm_vm.h linux.21pre4-ac6/drivers/char/drm/drm_vm.h --- linux.21pre4/drivers/char/drm/drm_vm.h 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/drm_vm.h 2003-02-21 16:32:35.000000000 +0000 @@ -70,7 +70,7 @@ * Find the right map */ - if(!dev->agp->cant_use_aperture) goto vm_nopage_error; + if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; list_for_each(list, &dev->maplist->head) { r_list = (drm_map_list_t *)list; @@ -141,9 +141,7 @@ return NOPAGE_OOM; get_page(page); -#if 0 /* XXX page_to_bus is not a portable interface available on all platforms. */ - DRM_DEBUG("0x%08lx => 0x%08llx\n", address, (u64)page_to_bus(page)); -#endif + DRM_DEBUG("shm_nopage 0x%lx\n", address); return page; } @@ -245,10 +243,7 @@ get_page(page); -#if 0 /* XXX page_to_bus is not a portable interface available on all platforms. */ - DRM_DEBUG("0x%08lx (page %lu) => 0x%08llx\n", address, page_nr, - (u64)page_to_bus(page)); -#endif + DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr); return page; } @@ -449,12 +444,12 @@ } offset = DRIVER_GET_REG_OFS(); #ifdef __sparc__ - if (io_remap_page_range(vma->vm_start, + if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma) + offset, vma->vm_end - vma->vm_start, vma->vm_page_prot, 0)) #else - if (remap_page_range(vma->vm_start, + if (remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma) + offset, vma->vm_end - vma->vm_start, vma->vm_page_prot)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/gamma_dma.c linux.21pre4-ac6/drivers/char/drm/gamma_dma.c --- linux.21pre4/drivers/char/drm/gamma_dma.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/gamma_dma.c 2003-01-31 11:54:14.000000000 +0000 @@ -31,33 +31,32 @@ #include "gamma.h" #include "drmP.h" +#include "drm.h" +#include "gamma_drm.h" #include "gamma_drv.h" #include /* For task queue support */ #include - static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); - while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) - ; + (drm_gamma_private_t *)dev->dev_private; + mb(); + while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); + GAMMA_WRITE(GAMMA_DMAADDRESS, address); + while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) cpu_relax(); GAMMA_WRITE(GAMMA_DMACOUNT, length / 4); } void gamma_dma_quiescent_single(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) cpu_relax(); - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); @@ -71,56 +70,50 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) cpu_relax(); - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); GAMMA_WRITE(GAMMA_BROADCASTMASK, 3); - GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - /* Read from first MX */ + /* Read from first MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) - ; + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - /* Read from second MX */ + /* Read from second MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) - ; + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG); } void gamma_dma_ready(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) cpu_relax(); } static inline int gamma_dma_is_ready(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - return !GAMMA_READ(GAMMA_DMACOUNT); + (drm_gamma_private_t *)dev->dev_private; + return(!GAMMA_READ(GAMMA_DMACOUNT)); } void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { - drm_device_t *dev = (drm_device_t *)device; - drm_device_dma_t *dma = dev->dma; + drm_device_t *dev = (drm_device_t *)device; + drm_device_dma_t *dma = dev->dma; drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; + (drm_gamma_private_t *)dev->dev_private; atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ + + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); @@ -164,7 +157,9 @@ } buf = dma->next_buffer; - address = (unsigned long)buf->address; + /* WE NOW ARE ON LOGICAL PAGES!! - using page table setup in dma_init */ + /* So we pass the buffer index value into the physical page offset */ + address = buf->idx << 12; length = buf->used; DRM_DEBUG("context %d, buffer %d (%ld bytes)\n", @@ -231,6 +226,9 @@ buf->time_dispatched = get_cycles(); #endif + /* WE NOW ARE ON LOGICAL PAGES!!! - overriding address */ + address = buf->idx << 12; + gamma_dma_dispatch(dev, address, length); gamma_free_buffer(dev, dma->this_buffer); dma->this_buffer = buf; @@ -523,11 +521,11 @@ } } if (retcode) { - DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n", + DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d %d/%d\n", d->context, last_buf->waiting, last_buf->pending, - DRM_WAITCOUNT(dev, d->context), + (long)DRM_WAITCOUNT(dev, d->context), last_buf->idx, last_buf->list, last_buf->pid, @@ -581,3 +579,267 @@ return retcode; } + +/* ============================================================= + * DMA initialization, cleanup + */ + +static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) +{ + drm_gamma_private_t *dev_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + int i; + struct list_head *list; + unsigned long *pgt; + + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + dev_priv = DRM(alloc)( sizeof(drm_gamma_private_t), + DRM_MEM_DRIVER ); + if ( !dev_priv ) + return -ENOMEM; + + dev->dev_private = (void *)dev_priv; + + memset( dev_priv, 0, sizeof(drm_gamma_private_t) ); + + list_for_each(list, &dev->maplist->head) { + #warning list_entry() is needed here + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea = r_list->map; + break; + } + } + + DRM_FIND_MAP( dev_priv->mmio0, init->mmio0 ); + DRM_FIND_MAP( dev_priv->mmio1, init->mmio1 ); + DRM_FIND_MAP( dev_priv->mmio2, init->mmio2 ); + DRM_FIND_MAP( dev_priv->mmio3, init->mmio3 ); + + dev_priv->sarea_priv = (drm_gamma_sarea_t *) + ((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + if (init->pcimode) { + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + pgt = buf->address; + + for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) { + buf = dma->buflist[i]; + *pgt = virt_to_phys((void*)buf->address) | 0x07; + pgt++; + } + + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + } else { + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + + DRM_IOREMAP( dev_priv->buffers ); + + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + pgt = buf->address; + + for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) { + buf = dma->buflist[i]; + *pgt = (unsigned int)buf->address + 0x07; + pgt++; + } + + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1) cpu_relax(); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0xe) ; + } + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); cpu_relax(); + GAMMA_WRITE( GAMMA_PAGETABLEADDR, virt_to_phys((void*)buf->address) ); + GAMMA_WRITE( GAMMA_PAGETABLELENGTH, 2 ); + + return 0; +} + +int gamma_do_cleanup_dma( drm_device_t *dev ) +{ + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( dev->dev_private ) { + drm_gamma_private_t *dev_priv = dev->dev_private; + + DRM_IOREMAPFREE( dev_priv->buffers ); + + DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int gamma_dma_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_gamma_init_t init; + + if ( copy_from_user( &init, (drm_gamma_init_t *)arg, sizeof(init) ) ) + return -EFAULT; + + switch ( init.func ) { + case GAMMA_INIT_DMA: + return gamma_do_init_dma( dev, &init ); + case GAMMA_CLEANUP_DMA: + return gamma_do_cleanup_dma( dev ); + } + + return -EINVAL; +} + +static int gamma_do_copy_dma( drm_device_t *dev, drm_gamma_copy_t *copy ) +{ + drm_device_dma_t *dma = dev->dma; + unsigned int *screenbuf; + + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + /* We've DRM_RESTRICTED this DMA buffer */ + + screenbuf = dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ]->address; + +#if 0 + *buffer++ = 0x180; /* Tag (FilterMode) */ + *buffer++ = 0x200; /* Allow FBColor through */ + *buffer++ = 0x53B; /* Tag */ + *buffer++ = copy->Pitch; + *buffer++ = 0x53A; /* Tag */ + *buffer++ = copy->SrcAddress; + *buffer++ = 0x539; /* Tag */ + *buffer++ = copy->WidthHeight; /* Initiates transfer */ + *buffer++ = 0x53C; /* Tag - DMAOutputAddress */ + *buffer++ = virt_to_phys((void*)screenbuf); + *buffer++ = 0x53D; /* Tag - DMAOutputCount */ + *buffer++ = copy->Count; /* Reads HostOutFifo BLOCKS until ..*/ + + /* Data now sitting in dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ] */ + /* Now put it back to the screen */ + + *buffer++ = 0x180; /* Tag (FilterMode) */ + *buffer++ = 0x400; /* Allow Sync through */ + *buffer++ = 0x538; /* Tag - DMARectangleReadTarget */ + *buffer++ = 0x155; /* FBSourceData | count */ + *buffer++ = 0x537; /* Tag */ + *buffer++ = copy->Pitch; + *buffer++ = 0x536; /* Tag */ + *buffer++ = copy->DstAddress; + *buffer++ = 0x535; /* Tag */ + *buffer++ = copy->WidthHeight; /* Initiates transfer */ + *buffer++ = 0x530; /* Tag - DMAAddr */ + *buffer++ = virt_to_phys((void*)screenbuf); + *buffer++ = 0x531; + *buffer++ = copy->Count; /* initiates DMA transfer of color data */ +#endif + + /* need to dispatch it now */ + + return 0; +} + +int gamma_dma_copy( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_gamma_copy_t copy; + + if ( copy_from_user( ©, (drm_gamma_copy_t *)arg, sizeof(copy) ) ) + return -EFAULT; + + return gamma_do_copy_dma( dev, © ); +} + +/* ============================================================= + * Per Context SAREA Support + */ + +int gamma_getsareactx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_priv_map_t request; + drm_map_t *map; + + if (copy_from_user(&request, + (drm_ctx_priv_map_t *)arg, + sizeof(request))) + return -EFAULT; + + down(&dev->struct_sem); + if ((int)request.ctx_id >= dev->max_context) { + up(&dev->struct_sem); + return -EINVAL; + } + + map = dev->context_sareas[request.ctx_id]; + up(&dev->struct_sem); + + request.handle = map->handle; + if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request))) + return -EFAULT; + return 0; +} + +int gamma_setsareactx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_priv_map_t request; + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; + + if (copy_from_user(&request, + (drm_ctx_priv_map_t *)arg, + sizeof(request))) + return -EFAULT; + + down(&dev->struct_sem); + r_list = NULL; + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + if(r_list->map && + r_list->map->handle == request.handle) break; + } + if (list == &(dev->maplist->head)) { + up(&dev->struct_sem); + return -EINVAL; + } + map = r_list->map; + up(&dev->struct_sem); + + if (!map) return -EINVAL; + + down(&dev->struct_sem); + if ((int)request.ctx_id >= dev->max_context) { + up(&dev->struct_sem); + return -EINVAL; + } + dev->context_sareas[request.ctx_id] = map; + up(&dev->struct_sem); + return 0; +} + +/* drm_dma.h hooks +*/ +void DRM(driver_irq_preinstall)( drm_device_t *dev ) { +} + +void DRM(driver_irq_postinstall)( drm_device_t *dev ) { +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/gamma_drm.h linux.21pre4-ac6/drivers/char/drm/gamma_drm.h --- linux.21pre4/drivers/char/drm/gamma_drm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/drm/gamma_drm.h 2003-01-06 17:25:49.000000000 +0000 @@ -0,0 +1,89 @@ +#ifndef _GAMMA_DRM_H_ +#define _GAMMA_DRM_H_ + +typedef struct _drm_gamma_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} drm_gamma_tex_region_t; + +typedef struct { + unsigned int GDeltaMode; + unsigned int GDepthMode; + unsigned int GGeometryMode; + unsigned int GTransformMode; +} drm_gamma_context_regs_t; + +typedef struct _drm_gamma_sarea { + drm_gamma_context_regs_t context_state; + + unsigned int dirty; + + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + +#define GAMMA_NR_TEX_REGIONS 64 + drm_gamma_tex_region_t texList[GAMMA_NR_TEX_REGIONS+1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + int ctxOwner; /* last context to upload state */ + + int vertex_prim; +} drm_gamma_sarea_t; + +/* WARNING: If you change any of these defines, make sure to wear a bullet + * proof vest because these are part of the stable kernel<->userspace ABI + */ + +/* Gamma specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t) +#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t) + +typedef struct drm_gamma_copy { + unsigned int DMAOutputAddress; + unsigned int DMAOutputCount; + unsigned int DMAReadGLINTSource; + unsigned int DMARectangleWriteAddress; + unsigned int DMARectangleWriteLinePitch; + unsigned int DMARectangleWrite; + unsigned int DMARectangleReadAddress; + unsigned int DMARectangleReadLinePitch; + unsigned int DMARectangleRead; + unsigned int DMARectangleReadTarget; +} drm_gamma_copy_t; + +typedef struct drm_gamma_init { + enum { + GAMMA_INIT_DMA = 0x01, + GAMMA_CLEANUP_DMA = 0x02 + } func; + + int sarea_priv_offset; + int pcimode; + unsigned int mmio0; + unsigned int mmio1; + unsigned int mmio2; + unsigned int mmio3; + unsigned int buffers_offset; +} drm_gamma_init_t; + +#endif /* _GAMMA_DRM_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/gamma_drv.c linux.21pre4-ac6/drivers/char/drm/gamma_drv.c --- linux.21pre4/drivers/char/drm/gamma_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/gamma_drv.c 2003-01-06 17:25:49.000000000 +0000 @@ -32,57 +32,18 @@ #include #include "gamma.h" #include "drmP.h" +#include "drm.h" +#include "gamma_drm.h" #include "gamma_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "gamma" -#define DRIVER_DESC "3DLabs gamma" -#define DRIVER_DATE "20010216" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 } - - -#define __HAVE_COUNTERS 5 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_DMA -#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL -#define __HAVE_COUNTER10 _DRM_STAT_MISSED - - #include "drm_auth.h" +#include "drm_agpsupport.h" #include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init gamma_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", gamma_options ); -#endif - - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/gamma_drv.h linux.21pre4-ac6/drivers/char/drm/gamma_drv.h --- linux.21pre4/drivers/char/drm/gamma_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/gamma_drv.h 2003-01-06 17:25:58.000000000 +0000 @@ -32,8 +32,9 @@ #ifndef _GAMMA_DRV_H_ #define _GAMMA_DRV_H_ - typedef struct drm_gamma_private { + drm_gamma_sarea_t *sarea_priv; + drm_map_t *sarea; drm_map_t *buffers; drm_map_t *mmio0; drm_map_t *mmio1; @@ -51,6 +52,11 @@ } \ } while (0) + /* gamma_dma.c */ +extern int gamma_dma_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int gamma_dma_copy( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); extern void gamma_dma_ready(drm_device_t *dev); extern void gamma_dma_quiescent_single(drm_device_t *dev); @@ -63,6 +69,7 @@ extern int gamma_find_devices(void); extern int gamma_found(void); +#define GLINT_DRI_BUF_COUNT 256 #define GAMMA_OFF(reg) \ ((reg < 0x1000) \ @@ -78,7 +85,6 @@ ((reg < 0x10000) ? dev_priv->mmio1->handle : \ ((reg < 0x11000) ? dev_priv->mmio2->handle : \ dev_priv->mmio3->handle)))) - #define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) #define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) #define GAMMA_READ(reg) GAMMA_DEREF(reg) @@ -91,9 +97,11 @@ #define GAMMA_FILTERMODE 0x8c00 #define GAMMA_GCOMMANDINTFLAGS 0x0c50 #define GAMMA_GCOMMANDMODE 0x0c40 +#define GAMMA_QUEUED_DMA_MODE 1<<1 #define GAMMA_GCOMMANDSTATUS 0x0c60 #define GAMMA_GDELAYTIMER 0x0c38 #define GAMMA_GDMACONTROL 0x0060 +#define GAMMA_USE_AGP 1<<1 #define GAMMA_GINTENABLE 0x0808 #define GAMMA_GINTFLAGS 0x0810 #define GAMMA_INFIFOSPACE 0x0018 @@ -101,5 +109,12 @@ #define GAMMA_OUTPUTFIFO 0x2000 #define GAMMA_SYNC 0x8c40 #define GAMMA_SYNC_TAG 0x0188 +#define GAMMA_PAGETABLEADDR 0x0C00 +#define GAMMA_PAGETABLELENGTH 0x0C08 + +#define GAMMA_PASSTHROUGH 0x1FE +#define GAMMA_DMAADDRTAG 0x530 +#define GAMMA_DMACOUNTTAG 0x531 +#define GAMMA_COMMANDINTTAG 0x532 #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/gamma.h linux.21pre4-ac6/drivers/char/drm/gamma.h --- linux.21pre4/drivers/char/drm/gamma.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/gamma.h 2003-01-06 17:25:58.000000000 +0000 @@ -38,9 +38,36 @@ */ #define __HAVE_MTRR 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "gamma" +#define DRIVER_DESC "3DLabs gamma" +#define DRIVER_DATE "20010624" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 } + +#define IOCTL_TABLE_NAME DRM(ioctls) +#define IOCTL_FUNC_NAME DRM(ioctl) + +#define __HAVE_COUNTERS 5 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_DMA +#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL +#define __HAVE_COUNTER10 _DRM_STAT_MISSED + /* DMA customization: */ #define __HAVE_DMA 1 +#define __HAVE_AGP 1 +#define __MUST_HAVE_AGP 0 #define __HAVE_OLD_DMA 1 #define __HAVE_PCI_DMA 1 @@ -61,33 +88,61 @@ #define __HAVE_DMA_QUIESCENT 1 #define DRIVER_DMA_QUIESCENT() do { \ /* FIXME ! */ \ - gamma_dma_quiescent_dual(dev); \ + gamma_dma_quiescent_single(dev); \ return 0; \ } while (0) #define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_IRQ_BH 1 + +#if 1 #define DRIVER_PREINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); \ GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ } while (0) - #define DRIVER_POSTINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); \ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ } while (0) +#else +#define DRIVER_POSTINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); \ +} while (0) + +#define DRIVER_PREINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );\ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );\ +} while (0) +#endif #define DRIVER_UNINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); \ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ } while (0) +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_gamma_private_t *)((dev)->dev_private))->buffers + #endif /* __GAMMA_H__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i810_dma.c linux.21pre4-ac6/drivers/char/drm/i810_dma.c --- linux.21pre4/drivers/char/drm/i810_dma.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i810_dma.c 2003-01-06 17:26:33.000000000 +0000 @@ -26,21 +26,20 @@ * * Authors: Rickard E. (Rik) Faith * Jeff Hartmann - * Keith Whitwell + * Keith Whitwell * */ #include #include "i810.h" #include "drmP.h" +#include "drm.h" +#include "i810_drm.h" #include "i810_drv.h" #include /* For task queue support */ -#include +#include -/* in case we don't have a 2.3.99-pre6 kernel or later: */ -#ifndef VM_DONTCOPY -#define VM_DONTCOPY 0 -#endif +#define DO_MUNMAP(m, a, l) do_munmap(m, a, l, 1) #define I810_BUF_FREE 2 #define I810_BUF_CLIENT 1 @@ -51,29 +50,27 @@ #define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ - n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ +#define BEGIN_LP_RING(n) do { \ + if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ } while (0) -#define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ +#define ADVANCE_LP_RING() do { \ + if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -#define OUT_RING(n) do { \ - if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ +#define OUT_RING(n) do { \ + if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ } while (0) static inline void i810_print_status_page(drm_device_t *dev) @@ -135,14 +132,14 @@ } static struct file_operations i810_buffer_fops = { - open: DRM(open), - flush: DRM(flush), - release: DRM(release), - ioctl: DRM(ioctl), - mmap: i810_mmap_buffers, - read: DRM(read), - fasync: DRM(fasync), - poll: DRM(poll), + .open = DRM(open), + .flush = DRM(flush), + .release = DRM(release), + .ioctl = DRM(ioctl), + .mmap = i810_mmap_buffers, + .read = DRM(read), + .fasync = DRM(fasync), + .poll = DRM(poll), }; int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -165,7 +162,7 @@ buf_priv->currently_mapped = I810_BUF_MAPPED; unlock_kernel(); - if (remap_page_range(vma->vm_start, + if (remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma), vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; @@ -183,28 +180,31 @@ if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; - if(VM_DONTCOPY != 0) { - down_write( ¤t->mm->mmap_sem ); - old_fops = filp->f_op; - filp->f_op = &i810_buffer_fops; - dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, - PROT_READ|PROT_WRITE, - MAP_SHARED, - buf->bus_address); - dev_priv->mmap_buffer = NULL; - filp->f_op = old_fops; - if ((unsigned long)buf_priv->virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed int)buf_priv->virtual; - buf_priv->virtual = 0; - } - up_write( ¤t->mm->mmap_sem ); - } else { - buf_priv->virtual = buf_priv->kernel_virtual; - buf_priv->currently_mapped = I810_BUF_MAPPED; + + + + down_write( ¤t->mm->mmap_sem ); + + old_fops = filp->f_op; + filp->f_op = &i810_buffer_fops; + dev_priv->mmap_buffer = buf; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("mmap error\n"); + retcode = (signed int)buf_priv->virtual; + buf_priv->virtual = 0; } + + + + up_write( ¤t->mm->mmap_sem ); + return retcode; } @@ -213,15 +213,21 @@ drm_i810_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; - if(VM_DONTCOPY != 0) { - if(buf_priv->currently_mapped != I810_BUF_MAPPED) - return -EINVAL; - down_write( ¤t->mm->mmap_sem ); - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, - (size_t) buf->total); - up_write( ¤t->mm->mmap_sem ); - } + if(buf_priv->currently_mapped != I810_BUF_MAPPED) + return -EINVAL; + + + + down_write( ¤t->mm->mmap_sem ); + + retcode = DO_MUNMAP(current->mm, + (unsigned long)buf_priv->virtual, + (size_t) buf->total); + + + + up_write( ¤t->mm->mmap_sem ); + buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = 0; @@ -273,8 +279,9 @@ dev_priv->ring.Size); } if(dev_priv->hw_status_page != 0UL) { - pci_free_consistent(dev->pdev, PAGE_SIZE, (void *)dev_priv->hw_status_page, - dev_priv->dma_status_page); + pci_free_consistent(dev->pdev, PAGE_SIZE, + (void *)dev_priv->hw_status_page, + dev_priv->dma_status_page); /* Need to rewrite hardware status page */ I810_WRITE(0x02080, 0x1ffff000); } @@ -301,8 +308,6 @@ end = jiffies + (HZ*3); while (ring->space < n) { - int i; - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; @@ -317,7 +322,7 @@ goto out_wait_ring; } - for (i = 0 ; i < 2000 ; i++) ; + udelay(1); } out_wait_ring: @@ -405,9 +410,6 @@ ((u8 *)dev_priv->sarea_map->handle + init->sarea_priv_offset); - atomic_set(&dev_priv->flush_done, 0); - init_waitqueue_head(&dev_priv->flush_queue); - dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; @@ -440,8 +442,9 @@ dev_priv->zi1 = init->depth_offset | init->pitch_bits; /* Program Hardware Status Page */ - dev_priv->hw_status_page = (unsigned long)pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); + dev_priv->hw_status_page = + (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE, + &dev_priv->dma_status_page); if(dev_priv->hw_status_page == 0UL) { dev->dev_private = (void *)dev_priv; i810_dma_cleanup(dev); @@ -451,7 +454,7 @@ memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - I810_WRITE(0x02080, dev_priv->dma_status_page); + I810_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ @@ -532,16 +535,12 @@ /* Most efficient way to verify state for the i810 is as it is * emitted. Non-conformant state is silently dropped. - * - * Use 'volatile' & local var tmp to force the emitted values to be - * identical to the verified ones. */ static void i810EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) + unsigned int *code ) { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; - unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); @@ -553,14 +552,13 @@ OUT_RING( code[I810_CTXREG_ST1] ); for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - - if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + if ((code[i] & (7<<29)) == (3<<29) && + (code[i] & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( code[i] ); j++; } + else printk("constext state dropped!!!\n"); } if (j & 1) @@ -574,7 +572,6 @@ { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; - unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); @@ -585,14 +582,14 @@ OUT_RING( code[I810_TEXREG_MI3] ); for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + if ((code[i] & (7<<29)) == (3<<29) && + (code[i] & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( code[i] ); j++; } + else printk("texture state dropped!!!\n"); } if (j & 1) @@ -617,9 +614,9 @@ if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( tmp ); - } else - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", - tmp, dev_priv->front_di1, dev_priv->back_di1); + } + else + printk("buffer state dropped\n"); /* invarient: */ @@ -704,7 +701,6 @@ continue; if ( flags & I810_FRONT ) { - DRM_DEBUG("clear front\n"); BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); @@ -717,7 +713,6 @@ } if ( flags & I810_BACK ) { - DRM_DEBUG("clear back\n"); BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); @@ -730,7 +725,6 @@ } if ( flags & I810_DEPTH ) { - DRM_DEBUG("clear depth\n"); BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); @@ -756,8 +750,6 @@ int i; RING_LOCALS; - DRM_DEBUG("swapbuffers\n"); - i810_kernel_lost_context(dev); if (nbox > I810_NR_SAREA_CLIPRECTS) @@ -776,10 +768,6 @@ pbox->y2 > dev_priv->h) continue; - DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", - pbox[i].x1, pbox[i].y1, - pbox[i].x2, pbox[i].y2); - BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); OUT_RING( pitch | (0xCC << 16)); @@ -804,7 +792,7 @@ int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - int i = 0, u; + int i = 0; RING_LOCALS; i810_kernel_lost_context(dev); @@ -812,33 +800,16 @@ if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - if (discard) { - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_HARDWARE); - if(u != I810_BUF_CLIENT) { - DRM_DEBUG("xxxx 2\n"); - } - } - if (used > 4*1024) used = 0; if (sarea_priv->dirty) i810EmitState( dev ); - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", - address, used, nbox); - - dev_priv->counter++; - DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG( "i810_dma_dispatch\n"); - DRM_DEBUG( "start : %lx\n", start); - DRM_DEBUG( "used : %d\n", used); - DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); - if (buf_priv->currently_mapped == I810_BUF_MAPPED) { - *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | - sarea_priv->vertex_prim | + unsigned int prim = (sarea_priv->vertex_prim & PR_MASK); + + *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | prim | ((used/4)-2)); if (used & 4) { @@ -871,154 +842,62 @@ } while (++i < nbox); } - BEGIN_LP_RING(10); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( 0 ); - if (discard) { + dev_priv->counter++; + + (void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE); + + BEGIN_LP_RING(8); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); OUT_RING( CMD_STORE_DWORD_IDX ); OUT_RING( buf_priv->my_use_idx ); OUT_RING( I810_BUF_FREE ); + OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); + ADVANCE_LP_RING(); } - - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); -} - - -/* Interrupts are only for flushing */ -void i810_dma_service(int irq, void *device, struct pt_regs *regs) -{ - drm_device_t *dev = (drm_device_t *)device; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u16 temp; - - atomic_inc(&dev->counts[_DRM_STAT_IRQ]); - temp = I810_READ16(I810REG_INT_IDENTITY_R); - temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, - temp); /* Clear all interrupts */ - else - return; - - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); } -void i810_dma_immediate_bh(void *device) -{ - drm_device_t *dev = (drm_device_t *) device; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); -} - -static inline void i810_dma_emit_flush(drm_device_t *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( GFX_OP_USER_INTERRUPT ); - ADVANCE_LP_RING(); - -/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */ -/* atomic_set(&dev_priv->flush_done, 1); */ -/* wake_up_interruptible(&dev_priv->flush_queue); */ -} - -static inline void i810_dma_quiescent_emit(drm_device_t *dev) +void i810_dma_quiescent(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; RING_LOCALS; +/* printk("%s\n", __FUNCTION__); */ + i810_kernel_lost_context(dev); BEGIN_LP_RING(4); OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); - OUT_RING( GFX_OP_USER_INTERRUPT ); + OUT_RING( 0 ); ADVANCE_LP_RING(); -/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */ -/* atomic_set(&dev_priv->flush_done, 1); */ -/* wake_up_interruptible(&dev_priv->flush_queue); */ -} - -void i810_dma_quiescent(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - unsigned long end; - - if(dev_priv == NULL) { - return; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i810_dma_quiescent_emit(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - break; - } - } - - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); - - return; + i810_wait_ring( dev, dev_priv->ring.Size - 8 ); } static int i810_flush_queue(drm_device_t *dev) { - DECLARE_WAITQUEUE(entry, current); - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - unsigned long end; int i, ret = 0; + RING_LOCALS; + +/* printk("%s\n", __FUNCTION__); */ - if(dev_priv == NULL) { - return 0; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i810_dma_emit_flush(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } + i810_kernel_lost_context(dev); - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + i810_wait_ring( dev, dev_priv->ring.Size - 8 ); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; @@ -1030,7 +909,7 @@ if (used == I810_BUF_HARDWARE) DRM_DEBUG("reclaimed from HARDWARE\n"); if (used == I810_BUF_CLIENT) - DRM_DEBUG("still on client HARDWARE\n"); + DRM_DEBUG("still on client\n"); } return ret; @@ -1070,7 +949,6 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("i810_flush_ioctl\n"); if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_flush_ioctl called without lock held\n"); return -EINVAL; @@ -1101,9 +979,6 @@ return -EINVAL; } - DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", - vertex.idx, vertex.used, vertex.discard); - if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; i810_dma_dispatch_vertex( dev, @@ -1152,8 +1027,6 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("i810_swap_bufs\n"); - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_swap_buf called without lock held\n"); return -EINVAL; @@ -1189,7 +1062,6 @@ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) dev_priv->sarea_priv; - DRM_DEBUG("getbuf\n"); if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d))) return -EFAULT; @@ -1202,9 +1074,6 @@ retcode = i810_dma_get_buffer(dev, &d, filp); - DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", - current->pid, retcode, d.granted); - if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) return -EFAULT; sarea_priv->last_dispatch = (int) hw_status[5]; @@ -1212,47 +1081,19 @@ return retcode; } -int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int i810_copybuf(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_i810_copy_t d; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - drm_buf_t *buf; - drm_i810_buf_priv_t *buf_priv; - drm_device_dma_t *dma = dev->dma; - - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i810_dma called without lock held\n"); - return -EINVAL; - } - - if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d))) - return -EFAULT; - - if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL; - buf = dma->buflist[ d.idx ]; - buf_priv = buf->dev_private; - if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM; - - if(d.used < 0 || d.used > buf->total) return -EINVAL; - - if (copy_from_user(buf_priv->virtual, d.address, d.used)) - return -EFAULT; - - sarea_priv->last_dispatch = (int) hw_status[5]; - + /* Never copy - 2.4.x doesn't need it */ return 0; } int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - if(VM_DONTCOPY == 0) return 1; + /* Never copy - 2.4.x doesn't need it */ return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i810_drm.h linux.21pre4-ac6/drivers/char/drm/i810_drm.h --- linux.21pre4/drivers/char/drm/i810_drm.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i810_drm.h 2003-01-06 17:27:11.000000000 +0000 @@ -88,6 +88,8 @@ #define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */ #define I810_TEX_SETUP_SIZE 8 +/* Flags for clear ioctl + */ #define I810_FRONT 0x1 #define I810_BACK 0x2 #define I810_DEPTH 0x4 @@ -166,14 +168,34 @@ } drm_i810_sarea_t; +/* WARNING: If you change any of these defines, make sure to wear a bullet + * proof vest since these are part of the stable kernel<->userspace ABI + */ + +/* i810 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44) +#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) +#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) +#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) +#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t) +#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a) +#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b) +#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t) +#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d ) + typedef struct _drm_i810_clear { int clear_color; int clear_depth; int flags; } drm_i810_clear_t; - - /* These may be placeholders if we have more cliprects than * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to * false, indicating that the buffer will be dispatched again with a @@ -191,6 +213,17 @@ void *address; /* Address to copy from */ } drm_i810_copy_t; +#define PR_TRIANGLES (0x0<<18) +#define PR_TRISTRIP_0 (0x1<<18) +#define PR_TRISTRIP_1 (0x2<<18) +#define PR_TRIFAN (0x3<<18) +#define PR_POLYGON (0x4<<18) +#define PR_LINES (0x5<<18) +#define PR_LINESTRIP (0x6<<18) +#define PR_RECTS (0x7<<18) +#define PR_MASK (0x7<<18) + + typedef struct drm_i810_dma { void *virtual; int request_idx; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i810_drv.c linux.21pre4-ac6/drivers/char/drm/i810_drv.c --- linux.21pre4/drivers/char/drm/i810_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i810_drv.c 2003-01-06 17:27:11.000000000 +0000 @@ -33,42 +33,10 @@ #include #include "i810.h" #include "drmP.h" +#include "drm.h" +#include "i810_drm.h" #include "i810_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i810" -#define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20010920" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } - - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -77,25 +45,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i810_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i810_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i810_drv.h linux.21pre4-ac6/drivers/char/drm/i810_drv.h --- linux.21pre4/drivers/char/drm/i810_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i810_drv.h 2003-01-06 17:27:11.000000000 +0000 @@ -63,10 +63,9 @@ unsigned long hw_status_page; unsigned long counter; - dma_addr_t dma_status_page; - atomic_t flush_done; - wait_queue_head_t flush_queue; /* Processes waiting until flush */ + dma_addr_t dma_status_page; + drm_buf_t *mmap_buffer; @@ -78,6 +77,7 @@ int overlay_physical; int w, h; int pitch; + } drm_i810_private_t; /* i810_dma.c */ @@ -92,8 +92,13 @@ extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma); + +/* Obsolete: + */ extern int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +/* Obsolete: + */ extern int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -111,9 +116,6 @@ extern void i810_dma_quiescent(drm_device_t *dev); -#define I810_VERBOSE 0 - - int i810_dma_vertex(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i810.h linux.21pre4-ac6/drivers/char/drm/i810.h --- linux.21pre4/drivers/char/drm/i810.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i810.h 2003-01-06 17:27:11.000000000 +0000 @@ -41,6 +41,47 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i810" +#define DRIVER_DESC "Intel i810" +#define DRIVER_DATE "20020211" + +/* Interface history + * + * 1.1 - XFree86 4.1 + * 1.2 - XvMC interfaces + * - XFree86 4.2 + * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) + * - Remove requirement for interrupt (leave stubs again) + */ +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 1 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } + + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + /* Driver customization: */ #define __HAVE_RELEASE 1 @@ -60,50 +101,10 @@ i810_dma_quiescent( dev ); \ } while (0) -#define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 -#define __HAVE_SHARED_IRQ 1 -#define DRIVER_PREINSTALL() do { \ - drm_i810_private_t *dev_priv = \ - (drm_i810_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I810_READ16( I810REG_HWSTAM ); \ - tmp = tmp & 0x6000; \ - I810_WRITE16( I810REG_HWSTAM, tmp ); \ - \ - tmp = I810_READ16( I810REG_INT_MASK_R ); \ - tmp = tmp & 0x6000; /* Unmask interrupts */ \ - I810_WRITE16( I810REG_INT_MASK_R, tmp ); \ - tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ -} while (0) - -#define DRIVER_POSTINSTALL() do { \ - drm_i810_private_t *dev_priv = \ - (drm_i810_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; \ - tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ - I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ -} while (0) - -#define DRIVER_UNINSTALL() do { \ - drm_i810_private_t *dev_priv = \ - (drm_i810_private_t *)dev->dev_private; \ - u16 tmp; \ - if ( dev_priv ) { \ - tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \ - tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ - if ( tmp != 0 ) \ - I810_WRITE16( I810REG_INT_IDENTITY_R, tmp ); \ - \ - tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ - } \ -} while (0) +/* Don't need an irq any more. The template code will make sure that + * a noop stub is generated for compatibility. + */ +#define __HAVE_DMA_IRQ 0 /* Buffer customization: */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i830_dma.c linux.21pre4-ac6/drivers/char/drm/i830_dma.c --- linux.21pre4/drivers/char/drm/i830_dma.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i830_dma.c 2003-01-31 11:54:14.000000000 +0000 @@ -26,20 +26,22 @@ * * Authors: Rickard E. (Rik) Faith * Jeff Hartmann - * Keith Whitwell - * Abraham vd Merwe + * Keith Whitwell + * Abraham vd Merwe * */ + #include "i830.h" #include "drmP.h" +#include "drm.h" +#include "i830_drm.h" #include "i830_drv.h" #include /* For task queue support */ +#include /* For FASTCALL on unlock_page() */ #include -/* in case we don't have a 2.3.99-pre6 kernel or later: */ -#ifndef VM_DONTCOPY -#define VM_DONTCOPY 0 -#endif + +#define DO_MUNMAP(m, a, l) do_munmap(m, a, l, 1) #define I830_BUF_FREE 2 #define I830_BUF_CLIENT 1 @@ -48,54 +50,24 @@ #define I830_BUF_UNMAPPED 0 #define I830_BUF_MAPPED 1 -#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define DO_IDLE_WORKAROUND() \ -do { \ - int _head; \ - int _tail; \ - do { \ - _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \ - _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \ - udelay(1); \ - } while(_head != _tail); \ -} while(0) - -#define I830_SYNC_WORKAROUND 0 - -#define BEGIN_LP_RING(n) do { \ - if (I830_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ - n, __FUNCTION__); \ - if (I830_SYNC_WORKAROUND) \ - DO_IDLE_WORKAROUND(); \ - if (dev_priv->ring.space < n*4) \ - i830_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I830_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I830_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (I830_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0); + + + + + + + + + + static inline void i830_print_status_page(drm_device_t *dev) { drm_device_dma_t *dma = dev->dma; drm_i830_private_t *dev_priv = dev->dev_private; - u8 *temp = dev_priv->hw_status_page; + u32 *temp = (u32 *)dev_priv->hw_status_page; int i; DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]); @@ -149,14 +121,14 @@ } static struct file_operations i830_buffer_fops = { - open: DRM(open), - flush: DRM(flush), - release: DRM(release), - ioctl: DRM(ioctl), - mmap: i830_mmap_buffers, - read: DRM(read), - fasync: DRM(fasync), - poll: DRM(poll), + .open = DRM(open), + .flush = DRM(flush), + .release = DRM(release), + .ioctl = DRM(ioctl), + .mmap = i830_mmap_buffers, + .read = DRM(read), + .fasync = DRM(fasync), + .poll = DRM(poll), }; int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -179,7 +151,7 @@ buf_priv->currently_mapped = I830_BUF_MAPPED; unlock_kernel(); - if (remap_page_range(vma->vm_start, + if (remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma), vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; @@ -197,28 +169,24 @@ if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL; - if(VM_DONTCOPY != 0) { - down_write( ¤t->mm->mmap_sem ); - old_fops = filp->f_op; - filp->f_op = &i830_buffer_fops; - dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, - PROT_READ|PROT_WRITE, - MAP_SHARED, - buf->bus_address); - dev_priv->mmap_buffer = NULL; - filp->f_op = old_fops; - if ((unsigned long)buf_priv->virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed int)buf_priv->virtual; - buf_priv->virtual = 0; - } - up_write( ¤t->mm->mmap_sem ); - } else { - buf_priv->virtual = buf_priv->kernel_virtual; - buf_priv->currently_mapped = I830_BUF_MAPPED; + down_write( ¤t->mm->mmap_sem ); + old_fops = filp->f_op; + filp->f_op = &i830_buffer_fops; + dev_priv->mmap_buffer = buf; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_ERROR("mmap error\n"); + retcode = (signed int)buf_priv->virtual; + buf_priv->virtual = 0; } + up_write( ¤t->mm->mmap_sem ); + return retcode; } @@ -227,15 +195,15 @@ drm_i830_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; - if(VM_DONTCOPY != 0) { - if(buf_priv->currently_mapped != I830_BUF_MAPPED) - return -EINVAL; - down_write( ¤t->mm->mmap_sem ); - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, - (size_t) buf->total); - up_write( ¤t->mm->mmap_sem ); - } + if(buf_priv->currently_mapped != I830_BUF_MAPPED) + return -EINVAL; + + down_write(¤t->mm->mmap_sem); + retcode = DO_MUNMAP(current->mm, + (unsigned long)buf_priv->virtual, + (size_t) buf->total); + up_write(¤t->mm->mmap_sem); + buf_priv->currently_mapped = I830_BUF_UNMAPPED; buf_priv->virtual = 0; @@ -260,7 +228,7 @@ retcode = i830_map_buffer(buf, filp); if(retcode) { i830_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } buf->pid = priv->pid; @@ -286,12 +254,22 @@ DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, dev_priv->ring.Size); } - if(dev_priv->hw_status_page != NULL) { - pci_free_consistent(dev->pdev, PAGE_SIZE, - dev_priv->hw_status_page, dev_priv->dma_status_page); + if(dev_priv->hw_status_page != 0UL) { + pci_free_consistent(dev->pdev, PAGE_SIZE, + (void *)dev_priv->hw_status_page, + dev_priv->dma_status_page); /* Need to rewrite hardware status page */ I830_WRITE(0x02080, 0x1ffff000); } + + /* Disable interrupts here because after dev_private + * is freed, it's too late. + */ + if (dev->irq) { + I830_WRITE16( I830REG_INT_MASK_R, 0xffff ); + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); + } + DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -305,7 +283,7 @@ return 0; } -static int i830_wait_ring(drm_device_t *dev, int n) +int i830_wait_ring(drm_device_t *dev, int n, const char *caller) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -314,7 +292,7 @@ unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; end = jiffies + (HZ*3); - while (ring->space < n) { + while (ring->space < n) { ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; @@ -325,13 +303,13 @@ } iters++; - if(time_before(end,jiffies)) { + if(time_before(end, jiffies)) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; } - - udelay(1); + udelay(1); + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } out_wait_ring: @@ -344,9 +322,12 @@ drm_i830_ring_buffer_t *ring = &(dev_priv->ring); ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I830_READ(LP_RING + RING_TAIL); + ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; + + if (ring->head == ring->tail) + dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) @@ -420,9 +401,6 @@ ((u8 *)dev_priv->sarea_map->handle + init->sarea_priv_offset); - atomic_set(&dev_priv->flush_done, 0); - init_waitqueue_head(&dev_priv->flush_queue); - dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; @@ -446,11 +424,17 @@ dev_priv->pitch = init->pitch; dev_priv->back_offset = init->back_offset; dev_priv->depth_offset = init->depth_offset; + dev_priv->front_offset = init->front_offset; dev_priv->front_di1 = init->front_offset | init->pitch_bits; dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; + DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1); + DRM_DEBUG("back_offset %x\n", dev_priv->back_offset); + DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1); + DRM_DEBUG("pitch_bits %x\n", init->pitch_bits); + dev_priv->cpp = init->cpp; /* We are using seperate values as placeholders for mechanisms for * private backbuffer/depthbuffer usage. @@ -458,20 +442,23 @@ dev_priv->back_pitch = init->back_pitch; dev_priv->depth_pitch = init->depth_pitch; + dev_priv->do_boxes = 0; + dev_priv->use_mi_batchbuffer_start = 0; /* Program Hardware Status Page */ - dev_priv->hw_status_page = pci_alloc_consistent(dev->pdev, PAGE_SIZE, + dev_priv->hw_status_page = + (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE, &dev_priv->dma_status_page); - if(dev_priv->hw_status_page == NULL) { + if(dev_priv->hw_status_page == 0UL) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); + memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); + DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - I830_WRITE(0x02080, dev_priv->dma_status_page); + I830_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ @@ -517,83 +504,107 @@ return retcode; } +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + /* Most efficient way to verify state for the i830 is as it is * emitted. Non-conformant state is silently dropped. - * - * Use 'volatile' & local var tmp to force the emitted values to be - * identical to the verified ones. */ -static void i830EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i830EmitContextVerified( drm_device_t *dev, + unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_CTX_SETUP_SIZE ); - for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) { + BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 ); + + for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { tmp = code[i]; + if ((tmp & (7<<29)) == CMD_3D && + (tmp & (0x1f<<24)) < (0x1d<<24)) { + OUT_RING( tmp ); + j++; + } else { + DRM_ERROR("Skipping %d\n", i); + } + } -#if 0 - if ((tmp & (7<<29)) == (3<<29) && + OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); + OUT_RING( code[I830_CTXREG_BLENDCOLR] ); + j += 2; + + for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) { + tmp = code[i]; + if ((tmp & (7<<29)) == CMD_3D && (tmp & (0x1f<<24)) < (0x1d<<24)) { OUT_RING( tmp ); j++; } else { - printk("Skipping %d\n", i); + DRM_ERROR("Skipping %d\n", i); } -#else - OUT_RING( tmp ); - j++; -#endif } + OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); + OUT_RING( code[I830_CTXREG_MCSB1] ); + j += 2; + if (j & 1) OUT_RING( 0 ); ADVANCE_LP_RING(); } -static void i830EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); - - OUT_RING( GFX_OP_MAP_INFO ); - OUT_RING( code[I830_TEXREG_MI1] ); - OUT_RING( code[I830_TEXREG_MI2] ); - OUT_RING( code[I830_TEXREG_MI3] ); - OUT_RING( code[I830_TEXREG_MI4] ); - OUT_RING( code[I830_TEXREG_MI5] ); - - for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - OUT_RING( tmp ); - j++; - } + if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || + (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == + (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) { + + BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); + + OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */ + OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */ + OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */ + OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */ + OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */ + OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */ + + for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING( 0 ); - ADVANCE_LP_RING(); + ADVANCE_LP_RING(); + } + else + printk("rejected packet %x\n", code[0]); } static void i830EmitTexBlendVerified( drm_device_t *dev, - volatile unsigned int *code, - volatile unsigned int num) + unsigned int *code, + unsigned int num) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( num ); + if (!num) + return; + + BEGIN_LP_RING( num + 1 ); for ( i = 0 ; i < num ; i++ ) { tmp = code[i]; @@ -616,6 +627,8 @@ int i; RING_LOCALS; + return; /* Is this right ? -- Arjan */ + BEGIN_LP_RING( 258 ); if(is_shared == 1) { @@ -629,44 +642,43 @@ OUT_RING(palette[i]); } OUT_RING(0); + /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! + */ } /* Need to do some additional checking when setting the dest buffer. */ static void i830EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) + unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); + BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 ); + tmp = code[I830_DESTREG_CBUFADDR]; - if (tmp == dev_priv->front_di1) { - /* Don't use fence when front buffer rendering */ - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); - OUT_RING( tmp ); + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + if (((int)outring) & 8) { + OUT_RING(0); + OUT_RING(0); + } OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_DEPTH | - BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); - OUT_RING( dev_priv->zi1 ); - } else if(tmp == dev_priv->back_di1) { - OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_USE_FENCE); OUT_RING( tmp ); + OUT_RING( 0 ); OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); OUT_RING( dev_priv->zi1 ); + OUT_RING( 0 ); } else { - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + DRM_ERROR("bad di1 %x (allow %x or %x)\n", tmp, dev_priv->front_di1, dev_priv->back_di1); } @@ -688,25 +700,39 @@ if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { OUT_RING( tmp ); } else { - DRM_DEBUG("bad scissor enable\n"); + DRM_ERROR("bad scissor enable\n"); OUT_RING( 0 ); } - OUT_RING( code[I830_DESTREG_SENABLE] ); - OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR2] ); + OUT_RING( 0 ); ADVANCE_LP_RING(); } +static void i830EmitStippleVerified( drm_device_t *dev, + unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + BEGIN_LP_RING( 2 ); + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[1] ); + ADVANCE_LP_RING(); +} + + static void i830EmitState( drm_device_t *dev ) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; + DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); + if (dirty & I830_UPLOAD_BUFFERS) { i830EmitDestVerified( dev, sarea_priv->BufferState ); sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; @@ -740,17 +766,154 @@ } if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + } else { + if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); + } + + /* 1.3: + */ +#if 0 + if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } +#endif + } + + /* 1.3: + */ + if (dirty & I830_UPLOAD_STIPPLE) { + i830EmitStippleVerified( dev, + sarea_priv->StippleState); + sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; + } + + if (dirty & I830_UPLOAD_TEX2) { + i830EmitTexVerified( dev, sarea_priv->TexState2 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX2; + } + + if (dirty & I830_UPLOAD_TEX3) { + i830EmitTexVerified( dev, sarea_priv->TexState3 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX3; + } + + + if (dirty & I830_UPLOAD_TEXBLEND2) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState2, + sarea_priv->TexBlendStateWordsUsed2); + + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; + } + + if (dirty & I830_UPLOAD_TEXBLEND3) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState3, + sarea_priv->TexBlendStateWordsUsed3); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; + } +} + +/* ================================================================ + * Performance monitoring functions + */ + +static void i830_fill_box( drm_device_t *dev, + int x, int y, int w, int h, + int r, int g, int b ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + u32 color; + unsigned int BR13, CMD; + RING_LOCALS; + + BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24); + CMD = XY_COLOR_BLT_CMD; + x += dev_priv->sarea_priv->boxes[0].x1; + y += dev_priv->sarea_priv->boxes[0].y1; + + if (dev_priv->cpp == 4) { + BR13 |= (1<<25); + CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); } else { - if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); - } - if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { - i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); - } + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + } + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (y << 16) | x ); + OUT_RING( ((y+h) << 16) | (x+w) ); + + if ( dev_priv->current_page == 1 ) { + OUT_RING( dev_priv->front_offset ); + } else { + OUT_RING( dev_priv->back_offset ); + } + + OUT_RING( color ); + ADVANCE_LP_RING(); +} + +static void i830_cp_performance_boxes( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + /* Purple box for page flipping + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) + i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 ); + + /* Red box if we have to wait for idle at any point + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) + i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 ); + + /* Blue box: lost context? + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) + i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 ); + + /* Yellow box for texture swaps + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) + i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 ); + + /* Green box if hardware never idles (as far as we can tell) + */ + if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) + i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 ); + + + /* Draw bars indicating number of buffers allocated + * (not a great measure, easily confused) + */ + if (dev_priv->dma_used) { + int bar = dev_priv->dma_used / 10240; + if (bar > 100) bar = 100; + if (bar < 1) bar = 1; + i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 ); + dev_priv->dma_used = 0; } + + dev_priv->sarea_priv->perf_boxes = 0; } static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, @@ -768,6 +931,15 @@ unsigned int BR13, CMD, D_CMD; RING_LOCALS; + + if ( dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(I830_FRONT | I830_BACK); + if ( tmp & I830_FRONT ) flags |= I830_BACK; + if ( tmp & I830_BACK ) flags |= I830_FRONT; + } + i830_kernel_lost_context(dev); switch(cpp) { @@ -808,7 +980,7 @@ OUT_RING( BR13 ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( 0 ); + OUT_RING( dev_priv->front_offset ); OUT_RING( clear_color ); ADVANCE_LP_RING(); } @@ -847,13 +1019,17 @@ drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; int cpp = dev_priv->cpp; - int ofs = dev_priv->back_offset; int i; unsigned int CMD, BR13; RING_LOCALS; DRM_DEBUG("swapbuffers\n"); + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) + i830_cp_performance_boxes( dev ); + switch(cpp) { case 2: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); @@ -870,7 +1046,6 @@ break; } - i830_kernel_lost_context(dev); if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; @@ -890,23 +1065,72 @@ BEGIN_LP_RING( 8 ); OUT_RING( CMD ); OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | - pbox->x2 ); - - OUT_RING( 0 /* front ofs always zero */ ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->front_offset ); + else + OUT_RING( dev_priv->back_offset ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( BR13 & 0xffff ); - OUT_RING( ofs ); + + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->back_offset ); + else + OUT_RING( dev_priv->front_offset ); ADVANCE_LP_RING(); } } +static void i830_dma_dispatch_flip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); + + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) { + dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; + i830_cp_performance_boxes( dev ); + } + + + BEGIN_LP_RING( 2 ); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP ); + OUT_RING( 0 ); + if ( dev_priv->current_page == 0 ) { + OUT_RING( dev_priv->back_offset ); + dev_priv->current_page = 1; + } else { + OUT_RING( dev_priv->front_offset ); + dev_priv->current_page = 0; + } + OUT_RING(0); + ADVANCE_LP_RING(); + + + BEGIN_LP_RING( 2 ); + OUT_RING( MI_WAIT_FOR_EVENT | + MI_WAIT_FOR_PLANE_A_FLIP ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} static void i830_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, @@ -936,7 +1160,7 @@ } } - if (used > 4*1024) + if (used > 4*1023) used = 0; if (sarea_priv->dirty) @@ -953,12 +1177,19 @@ DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); if (buf_priv->currently_mapped == I830_BUF_MAPPED) { - *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | - sarea_priv->vertex_prim | - ((used/4)-2)); + u32 *vp = buf_priv->virtual; + + vp[0] = (GFX_OP_PRIMITIVE | + sarea_priv->vertex_prim | + ((used/4)-2)); + + if (dev_priv->use_mi_batchbuffer_start) { + vp[used/4] = MI_BATCH_BUFFER_END; + used += 4; + } if (used & 4) { - *(u32 *)((u32)buf_priv->virtual + used) = 0; + vp[used/4] = 0; used += 4; } @@ -978,80 +1209,45 @@ ADVANCE_LP_RING(); } - BEGIN_LP_RING(4); + if (dev_priv->use_mi_batchbuffer_start) { + BEGIN_LP_RING(2); + OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + ADVANCE_LP_RING(); + } + else { + BEGIN_LP_RING(4); + OUT_RING( MI_BATCH_BUFFER ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } - OUT_RING( MI_BATCH_BUFFER ); - OUT_RING( start | MI_BATCH_NON_SECURE ); - OUT_RING( start + used - 4 ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); - } while (++i < nbox); } - BEGIN_LP_RING(10); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( 0 ); - if (discard) { + dev_priv->counter++; + + (void) cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_HARDWARE); + + BEGIN_LP_RING(8); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); OUT_RING( CMD_STORE_DWORD_IDX ); OUT_RING( buf_priv->my_use_idx ); OUT_RING( I830_BUF_FREE ); + OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); + ADVANCE_LP_RING(); } - - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); -} - -/* Interrupts are only for flushing */ -void i830_dma_service(int irq, void *device, struct pt_regs *regs) -{ - drm_device_t *dev = (drm_device_t *)device; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u16 temp; - - temp = I830_READ16(I830REG_INT_IDENTITY_R); - temp = temp & ~(0x6000); - if(temp != 0) I830_WRITE16(I830REG_INT_IDENTITY_R, - temp); /* Clear all interrupts */ - else - return; - - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); -} - -void DRM(dma_immediate_bh)(void *device) -{ - drm_device_t *dev = (drm_device_t *) device; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); } -static inline void i830_dma_emit_flush(drm_device_t *dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i830_kernel_lost_context(dev); - BEGIN_LP_RING(2); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( GFX_OP_USER_INTERRUPT ); - ADVANCE_LP_RING(); - - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); -} - -static inline void i830_dma_quiescent_emit(drm_device_t *dev) +void i830_dma_quiescent(drm_device_t *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1062,79 +1258,27 @@ OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); - OUT_RING( GFX_OP_USER_INTERRUPT ); + OUT_RING( 0 ); ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); -} - -void i830_dma_quiescent(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - unsigned long end; - - if(dev_priv == NULL) { - return; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i830_dma_quiescent_emit(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if(time_before(end, jiffies)) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - break; - } - } - - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); - - return; + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); } static int i830_flush_queue(drm_device_t *dev) { - DECLARE_WAITQUEUE(entry, current); - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - unsigned long end; - int i, ret = 0; + int i, ret = 0; + RING_LOCALS; + + i830_kernel_lost_context(dev); - if(dev_priv == NULL) { - return 0; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i830_dma_emit_flush(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if(time_before(end, jiffies)) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } - - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; @@ -1146,7 +1290,7 @@ if (used == I830_BUF_HARDWARE) DRM_DEBUG("reclaimed from HARDWARE\n"); if (used == I830_BUF_CLIENT) - DRM_DEBUG("still on client HARDWARE\n"); + DRM_DEBUG("still on client\n"); } return ret; @@ -1185,8 +1329,7 @@ { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - - DRM_DEBUG("i830_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i830_flush_ioctl called without lock held\n"); return -EINVAL; @@ -1275,6 +1418,53 @@ return 0; } + + +/* Not sure why this isn't set all the time: + */ +static void i830_do_init_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} + +int i830_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + if (dev_priv->current_page != 0) + i830_dma_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_flip_buf called without lock held\n"); + return -EINVAL; + } + + if (!dev_priv->page_flipping) + i830_do_init_pageflip( dev ); + + i830_dma_dispatch_flip( dev ); + return 0; +} + int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1324,46 +1514,80 @@ return retcode; } -int i830_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, +int i830_copybuf(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + /* Never copy - 2.4.x doesn't need it */ + return 0; +} + +int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { + return 0; +} + + + +int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_i830_copy_t d; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; - drm_buf_t *buf; - drm_i830_buf_priv_t *buf_priv; - drm_device_dma_t *dma = dev->dma; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_getparam_t param; + int value; - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i830_dma called without lock held\n"); + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); return -EINVAL; } - - if (copy_from_user(&d, (drm_i830_copy_t *)arg, sizeof(d))) - return -EFAULT; - - if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL; - buf = dma->buflist[ d.idx ]; - buf_priv = buf->dev_private; - if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EPERM; - - if(d.used < 0 || d.used > buf->total) return -EINVAL; - if (copy_from_user(buf_priv->virtual, d.address, d.used)) + if (copy_from_user(¶m, (drm_i830_getparam_t *)arg, sizeof(param) )) return -EFAULT; - sarea_priv->last_dispatch = (int) hw_status[5]; + switch( param.param ) { + case I830_PARAM_IRQ_ACTIVE: + value = dev->irq ? 1 : 0; + break; + default: + return -EINVAL; + } + if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + return 0; } -int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + +int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) { - if(VM_DONTCOPY == 0) return 1; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_setparam_t param; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user(¶m, (drm_i830_setparam_t *)arg, sizeof(param) )) + return -EFAULT; + + switch( param.param ) { + case I830_SETPARAM_USE_MI_BATCHBUFFER_START: + dev_priv->use_mi_batchbuffer_start = param.value; + break; + default: + return -EINVAL; + } + return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i830_drm.h linux.21pre4-ac6/drivers/char/drm/i830_drm.h --- linux.21pre4/drivers/char/drm/i830_drm.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i830_drm.h 2003-01-31 11:54:14.000000000 +0000 @@ -3,6 +3,9 @@ /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. + * + * KW: Actually, you can't ever change them because doing so would + * break backwards compatibility. */ #ifndef _I830_DEFINES_ @@ -18,14 +21,12 @@ #define I830_NR_TEX_REGIONS 64 #define I830_LOG_MIN_TEX_REGION_SIZE 16 -/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ -#if !defined(I830_ENABLE_4_TEXTURES) +/* KW: These aren't correct but someone set them to two and then + * released the module. Now we can't change them as doing so would + * break backwards compatibility. + */ #define I830_TEXTURE_COUNT 2 -#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ -#else /* defined(I830_ENABLE_4_TEXTURES) */ -#define I830_TEXTURE_COUNT 4 -#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */ -#endif /* I830_ENABLE_4_TEXTURES */ +#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ @@ -57,6 +58,7 @@ #define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 +#define I830_UPLOAD_STIPPLE 0x8000000 /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, @@ -73,7 +75,6 @@ */ #define I830_DESTREG_CBUFADDR 0 -/* Invarient */ #define I830_DESTREG_DBUFADDR 1 #define I830_DESTREG_DV0 2 #define I830_DESTREG_DV1 3 @@ -109,6 +110,13 @@ #define I830_CTXREG_MCSB1 16 #define I830_CTX_SETUP_SIZE 17 +/* 1.3: Stipple state + */ +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + + /* Texture state (per tex unit) */ @@ -124,6 +132,18 @@ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEX_SETUP_SIZE 10 +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S0 1 +#define I830_TEXREG_TM0S1 2 +#define I830_TEXREG_TM0S2 3 +#define I830_TEXREG_TM0S3 4 +#define I830_TEXREG_TM0S4 5 +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define __I830_TEX_SETUP_SIZE 10 + #define I830_FRONT 0x1 #define I830_BACK 0x2 #define I830_DEPTH 0x4 @@ -199,8 +219,53 @@ int ctxOwner; /* last context to upload state */ int vertex_prim; + + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: + */ + unsigned int TexState2[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed2; + + unsigned int TexState3[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState3[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed3; + + unsigned int StippleState[I830_STP_SETUP_SIZE]; } drm_i830_sarea_t; +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +/* I830 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t) +#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t) +#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t) +#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44) +#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t) +#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) +#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) +#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49) +#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t) +#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t) +#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t) +#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t) + typedef struct _drm_i830_clear { int clear_color; int clear_depth; @@ -235,4 +300,36 @@ int granted; } drm_i830_dma_t; + +/* 1.3: Userspace can request & wait on irq's: + */ +typedef struct drm_i830_irq_emit { + int *irq_seq; +} drm_i830_irq_emit_t; + +typedef struct drm_i830_irq_wait { + int irq_seq; +} drm_i830_irq_wait_t; + + +/* 1.3: New ioctl to query kernel params: + */ +#define I830_PARAM_IRQ_ACTIVE 1 + +typedef struct drm_i830_getparam { + int param; + int *value; +} drm_i830_getparam_t; + + +/* 1.3: New ioctl to set kernel params: + */ +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 + +typedef struct drm_i830_setparam { + int param; + int value; +} drm_i830_setparam_t; + + #endif /* _I830_DRM_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i830_drv.c linux.21pre4-ac6/drivers/char/drm/i830_drv.c --- linux.21pre4/drivers/char/drm/i830_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i830_drv.c 2003-01-06 17:28:08.000000000 +0000 @@ -29,41 +29,16 @@ * Jeff Hartmann * Gareth Hughes * Abraham vd Merwe + * Keith Whitwell */ #include #include "i830.h" #include "drmP.h" +#include "drm.h" +#include "i830_drm.h" #include "i830_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i830" -#define DRIVER_DESC "Intel 830M" -#define DRIVER_DATE "20011004" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -72,25 +47,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i830_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i830_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i830_drv.h linux.21pre4-ac6/drivers/char/drm/i830_drv.h --- linux.21pre4/drivers/char/drm/i830_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i830_drv.h 2003-01-31 11:54:14.000000000 +0000 @@ -61,24 +61,36 @@ drm_i830_sarea_t *sarea_priv; drm_i830_ring_buffer_t ring; - u8 *hw_status_page; + unsigned long hw_status_page; unsigned long counter; - - dma_addr_t dma_status_page; - atomic_t flush_done; - wait_queue_head_t flush_queue; /* Processes waiting until flush */ + dma_addr_t dma_status_page; + drm_buf_t *mmap_buffer; u32 front_di1, back_di1, zi1; int back_offset; int depth_offset; + int front_offset; int w, h; int pitch; int back_pitch; int depth_pitch; unsigned int cpp; + + int do_boxes; + int dma_used; + + int current_page; + int page_flipping; + + wait_queue_head_t irq_queue; + atomic_t irq_received; + atomic_t irq_emitted; + + int use_mi_batchbuffer_start; + } drm_i830_private_t; /* i830_dma.c */ @@ -109,24 +121,81 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#define I830_VERBOSE 0 +extern int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i830_getparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int i830_setparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +/* i830_irq.c */ +extern int i830_irq_emit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_irq_wait( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_wait_irq(drm_device_t *dev, int irq_nr); +extern int i830_emit_irq(drm_device_t *dev); + #define I830_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) #define I830_ADDR(reg) (I830_BASE(reg) + reg) -#define I830_DEREF(reg) *(__volatile__ int *)I830_ADDR(reg) -#define I830_READ(reg) I830_DEREF(reg) -#define I830_WRITE(reg,val) do { I830_DEREF(reg) = val; } while (0) +#define I830_DEREF(reg) *(__volatile__ unsigned int *)I830_ADDR(reg) +#define I830_READ(reg) readl((volatile u32 *)I830_ADDR(reg)) +#define I830_WRITE(reg,val) writel(val, (volatile u32 *)I830_ADDR(reg)) #define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg) #define I830_READ16(reg) I830_DEREF16(reg) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) + + +#define I830_VERBOSE 0 + +#define RING_LOCALS unsigned int outring, ringmask, outcount; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I830_VERBOSE) \ + printk("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i830_wait_ring(dev, n*4, __FUNCTION__); \ + outcount = 0; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + + +#define OUT_RING(n) do { \ + if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outcount++; \ + outring += 4; \ + outring &= ringmask; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ + dev_priv->ring.tail = outring; \ + dev_priv->ring.space -= outcount * 4; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); + + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) +#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) + #define INST_PARSER_CLIENT 0x00000000 #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 @@ -142,18 +211,21 @@ #define I830REG_INT_MASK_R 0x020a8 #define I830REG_INT_ENABLE_R 0x020a0 +#define I830_IRQ_RESERVED ((1<<13)|(3<<2)) + + #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 +#define TAIL_ADDR 0x001FFFF8 #define RING_HEAD 0x04 #define HEAD_WRAP_COUNT 0xFFE00000 #define HEAD_WRAP_ONE 0x00200000 #define HEAD_ADDR 0x001FFFFC #define RING_START 0x08 -#define START_ADDR 0x00FFFFF8 +#define START_ADDR 0x0xFFFFF000 #define RING_LEN 0x0C -#define RING_NR_PAGES 0x000FF000 +#define RING_NR_PAGES 0x001FF000 #define RING_REPORT_MASK 0x00000006 #define RING_REPORT_64K 0x00000002 #define RING_REPORT_128K 0x00000004 @@ -184,6 +256,12 @@ #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) + +#define CMD_3D (0x3<<29) +#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) +#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 @@ -208,8 +286,15 @@ #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) #define MI_BATCH_BUFFER ((0x30<<23)|1) +#define MI_BATCH_BUFFER_START (0x31<<23) +#define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) + +#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i830.h linux.21pre4-ac6/drivers/char/drm/i830.h --- linux.21pre4/drivers/char/drm/i830.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/i830.h 2003-01-31 11:54:14.000000000 +0000 @@ -41,6 +41,48 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i830" +#define DRIVER_DESC "Intel 830M" +#define DRIVER_DATE "20021108" + +/* Interface history: + * + * 1.1: Original. + * 1.2: ? + * 1.3: New irq emit/wait ioctls. + * New pageflip ioctl. + * New getparam ioctl. + * State for texunits 3&4 in sarea. + * New (alternative) layout for texture state. + */ +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 3 +#define DRIVER_PATCHLEVEL 2 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 } + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + /* Driver customization: */ #define __HAVE_RELEASE 1 @@ -60,51 +102,50 @@ i830_dma_quiescent( dev ); \ } while (0) + +/* Driver will work either way: IRQ's save cpu time when waiting for + * the card, but are subject to subtle interactions between bios, + * hardware and the driver. + */ +#define USE_IRQS 0 + + +#if USE_IRQS #define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 -#define __HAVE_SHARED_IRQ 1 -#define DRIVER_PREINSTALL() do { \ - drm_i830_private_t *dev_priv = \ - (drm_i830_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I830_READ16( I830REG_HWSTAM ); \ - tmp = tmp & 0x6000; \ - I830_WRITE16( I830REG_HWSTAM, tmp ); \ - \ - tmp = I830_READ16( I830REG_INT_MASK_R ); \ - tmp = tmp & 0x6000; /* Unmask interrupts */ \ - I830_WRITE16( I830REG_INT_MASK_R, tmp ); \ - tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ -} while (0) +#define __HAVE_SHARED_IRQ 1 -#define DRIVER_POSTINSTALL() do { \ - drm_i830_private_t *dev_priv = \ +#define DRIVER_PREINSTALL() do { \ + drm_i830_private_t *dev_priv = \ (drm_i830_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; \ - tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ - I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ + \ + I830_WRITE16( I830REG_HWSTAM, 0xffff ); \ + I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); \ + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); \ } while (0) -#define DRIVER_UNINSTALL() do { \ - drm_i830_private_t *dev_priv = \ - (drm_i830_private_t *)dev->dev_private; \ - u16 tmp; \ - if ( dev_priv ) { \ - tmp = I830_READ16( I830REG_INT_IDENTITY_R ); \ - tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ - if ( tmp != 0 ) \ - I830_WRITE16( I830REG_INT_IDENTITY_R, tmp ); \ - \ - tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ - } \ + +#define DRIVER_POSTINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); \ + atomic_set(&dev_priv->irq_received, 0); \ + atomic_set(&dev_priv->irq_emitted, 0); \ + init_waitqueue_head(&dev_priv->irq_queue); \ } while (0) + +/* This gets called too late to be useful: dev_priv has already been + * freed. + */ +#define DRIVER_UNINSTALL() do { \ +} while (0) + +#else +#define __HAVE_DMA_IRQ 0 +#endif + + + /* Buffer customization: */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/i830_irq.c linux.21pre4-ac6/drivers/char/drm/i830_irq.c --- linux.21pre4/drivers/char/drm/i830_irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/drm/i830_irq.c 2003-01-31 11:54:14.000000000 +0000 @@ -0,0 +1,178 @@ +/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- + * + * Copyright 2002 Tungsten Graphics, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Keith Whitwell + * + */ + + +#include "i830.h" +#include "drmP.h" +#include "drm.h" +#include "i830_drm.h" +#include "i830_drv.h" +#include /* For task queue support */ +#include + + +void DRM(dma_service)(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u16 temp; + + temp = I830_READ16(I830REG_INT_IDENTITY_R); + printk("%s: %x\n", __FUNCTION__, temp); + + if(temp == 0) + return; + + I830_WRITE16(I830REG_INT_IDENTITY_R, temp); + + if (temp & 2) { + atomic_inc(&dev_priv->irq_received); + wake_up_interruptible(&dev_priv->irq_queue); + } +} + + +int i830_emit_irq(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG("%s\n", __FUNCTION__); + + atomic_inc(&dev_priv->irq_emitted); + + BEGIN_LP_RING(2); + OUT_RING( 0 ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + return atomic_read(&dev_priv->irq_emitted); +} + + +int i830_wait_irq(drm_device_t *dev, int irq_nr) +{ + drm_i830_private_t *dev_priv = + (drm_i830_private_t *)dev->dev_private; + DECLARE_WAITQUEUE(entry, current); + unsigned long end = jiffies + HZ*3; + int ret = 0; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + return 0; + + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; + + add_wait_queue(&dev_priv->irq_queue, &entry); + + for (;;) { + current->state = TASK_INTERRUPTIBLE; + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + break; + if (time_after(jiffies, end)) { + DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n", + I830_READ16( I830REG_INT_IDENTITY_R ), + I830_READ16( I830REG_INT_MASK_R ), + I830_READ16( I830REG_INT_ENABLE_R ), + I830_READ16( I830REG_HWSTAM )); + + ret = -EBUSY; /* Lockup? Missed irq? */ + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->irq_queue, &entry); + return ret; +} + + +/* Needs the lock as it touches the ring. + */ +int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_irq_emit_t emit; + int result; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_irq_emit called without lock held\n"); + return -EINVAL; + } + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) )) + return -EFAULT; + + result = i830_emit_irq( dev ); + + if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + +/* Doesn't need the hardware lock. + */ +int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_irq_wait_t irqwait; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg, + sizeof(irqwait) )) + return -EFAULT; + + return i830_wait_irq( dev, irqwait.irq_seq ); +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/Makefile linux.21pre4-ac6/drivers/char/drm/Makefile --- linux.21pre4/drivers/char/drm/Makefile 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/Makefile 2003-01-31 11:54:14.000000000 +0000 @@ -10,9 +10,9 @@ r128-objs := r128_drv.o r128_cce.o r128_state.o mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o i810-objs := i810_drv.o i810_dma.o -i830-objs := i830_drv.o i830_dma.o +i830-objs := i830_drv.o i830_dma.o i830_irq.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o ffb-objs := ffb_drv.o ffb_context.o sis-objs := sis_drv.o sis_ds.o sis_mm.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga_dma.c linux.21pre4-ac6/drivers/char/drm/mga_dma.c --- linux.21pre4/drivers/char/drm/mga_dma.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga_dma.c 2003-01-06 17:28:08.000000000 +0000 @@ -35,10 +35,11 @@ #include "mga.h" #include "drmP.h" +#include "drm.h" +#include "mga_drm.h" #include "mga_drv.h" - -#include /* For task queue support */ -#include +#include +#include "drm_os_linux.h" #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 @@ -52,7 +53,7 @@ { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; @@ -74,7 +75,7 @@ { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK; @@ -93,7 +94,7 @@ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_primary_buffer_t *primary = &dev_priv->prim; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The primary DMA stream should look like new right about now. */ @@ -114,7 +115,7 @@ int mga_do_engine_reset( drm_mga_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* Okay, so we've completely screwed up and locked the engine. * How about we clean up after ourselves? @@ -160,8 +161,8 @@ u32 head, tail; u32 status = 0; int i; - DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DMA_LOCALS; + DRM_DEBUG( "\n" ); /* We need to wait so that we can do an safe flush */ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { @@ -207,7 +208,7 @@ mga_flush_write_combine(); MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) @@ -215,7 +216,7 @@ drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_DMA_WRAP(); @@ -250,7 +251,7 @@ MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); set_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) @@ -258,7 +259,7 @@ drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 head = dev_priv->primary->offset; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); sarea_priv->last_wrap++; DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); @@ -267,7 +268,7 @@ MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); clear_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } @@ -307,8 +308,7 @@ drm_mga_buf_priv_t *buf_priv; drm_mga_freelist_t *entry; int i; - DRM_DEBUG( "%s: count=%d\n", - __FUNCTION__, dma->buf_count ); + DRM_DEBUG( "count=%d\n", dma->buf_count ); dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); @@ -354,7 +354,7 @@ drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; drm_mga_freelist_t *next; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); entry = dev_priv->head; while ( entry ) { @@ -392,7 +392,7 @@ drm_mga_freelist_t *prev; drm_mga_freelist_t *tail = dev_priv->tail; u32 head, wrap; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); head = MGA_READ( MGA_PRIMADDRESS ); wrap = dev_priv->sarea_priv->last_wrap; @@ -424,8 +424,7 @@ drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_freelist_t *head, *entry, *prev; - DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n", - __FUNCTION__, + DRM_DEBUG( "age=0x%06lx wrap=%d\n", buf_priv->list_entry->age.head - dev_priv->primary->offset, buf_priv->list_entry->age.wrap ); @@ -458,9 +457,8 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) { drm_mga_private_t *dev_priv; - struct list_head *list; int ret; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER ); if ( !dev_priv ) @@ -494,15 +492,8 @@ dev_priv->texture_offset = init->texture_offset[0]; dev_priv->texture_size = init->texture_size[0]; - list_for_each( list, &dev->maplist->head ) { - drm_map_list_t *entry = (drm_map_list_t *)list; - if ( entry->map && - entry->map->type == _DRM_SHM && - (entry->map->flags & _DRM_CONTAINS_LOCK) ) { - dev_priv->sarea = entry->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR( "failed to find sarea!\n" ); /* Assign dev_private so we can do cleanup. */ @@ -626,8 +617,6 @@ dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; - spin_lock_init( &dev_priv->prim.list_lock ); - dev_priv->prim.status[0] = dev_priv->primary->offset; dev_priv->prim.status[1] = 0; @@ -650,7 +639,7 @@ int mga_do_cleanup_dma( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -725,7 +714,7 @@ #if MGA_DMA_DEBUG int ret = mga_do_wait_for_idle( dev_priv ); if ( ret < 0 ) - DRM_INFO( __FUNCTION__": -EBUSY\n" ); + DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ ); return ret; #else return mga_do_wait_for_idle( dev_priv ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga_drm.h linux.21pre4-ac6/drivers/char/drm/mga_drm.h --- linux.21pre4/drivers/char/drm/mga_drm.h 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga_drm.h 2003-01-06 17:28:08.000000000 +0000 @@ -225,6 +225,20 @@ /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmMga.h) */ + +/* MGA specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) +#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42) +#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) +#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) + typedef struct _drm_mga_warp_index { int installed; unsigned long phys_addr; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga_drv.c linux.21pre4-ac6/drivers/char/drm/mga_drv.c --- linux.21pre4/drivers/char/drm/mga_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga_drv.c 2003-01-06 17:28:08.000000000 +0000 @@ -32,37 +32,9 @@ #include #include "mga.h" #include "drmP.h" +#include "drm.h" +#include "mga_drm.h" #include "mga_drv.h" - -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "mga" -#define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010321" - -#define DRIVER_MAJOR 3 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 2 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, - - -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -70,27 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init mga_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", mga_options ); -#endif - - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga_drv.h linux.21pre4-ac6/drivers/char/drm/mga_drv.h --- linux.21pre4/drivers/char/drm/mga_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga_drv.h 2003-01-06 17:28:08.000000000 +0000 @@ -46,8 +46,6 @@ u32 last_wrap; u32 high_mark; - - spinlock_t list_lock; } drm_mga_primary_buffer_t; typedef struct drm_mga_freelist { @@ -257,7 +255,7 @@ #define BEGIN_DMA_WRAP() \ do { \ if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \ + DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \ DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ } \ prim = dev_priv->prim.start; \ @@ -276,7 +274,7 @@ #define FLUSH_DMA() \ do { \ if ( 0 ) { \ - DRM_INFO( "%s:\n" , __FUNCTION__); \ + DRM_INFO( "%s:\n", __FUNCTION__ ); \ DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ dev_priv->prim.tail, \ MGA_READ( MGA_PRIMADDRESS ) - \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga.h linux.21pre4-ac6/drivers/char/drm/mga.h --- linux.21pre4/drivers/char/drm/mga.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga.h 2003-01-06 17:28:08.000000000 +0000 @@ -41,6 +41,33 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "mga" +#define DRIVER_DESC "Matrox G200/G400" +#define DRIVER_DATE "20010321" + +#define DRIVER_MAJOR 3 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 2 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, + +#define __HAVE_COUNTERS 3 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY + /* Driver customization: */ #define DRIVER_PRETAKEDOWN() do { \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga_state.c linux.21pre4-ac6/drivers/char/drm/mga_state.c --- linux.21pre4/drivers/char/drm/mga_state.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga_state.c 2003-01-06 17:28:08.000000000 +0000 @@ -34,8 +34,9 @@ #include "mga.h" #include "drmP.h" -#include "mga_drv.h" #include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" /* ================================================================ @@ -512,7 +513,7 @@ int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG("%s:\n" , __FUNCTION__); + DRM_DEBUG( "\n" ); BEGIN_DMA( 1 ); @@ -606,7 +607,7 @@ int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); sarea_priv->last_frame.head = dev_priv->prim.tail; sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; @@ -760,8 +761,7 @@ u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; u32 y2; DMA_LOCALS; - DRM_DEBUG( "%s: buf=%d used=%d\n", - __FUNCTION__, buf->idx, buf->used ); + DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); y2 = length / 64; @@ -815,7 +815,7 @@ int nbox = sarea_priv->nbox; u32 scandir = 0, i; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_DMA( 4 + nbox ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/mga_warp.c linux.21pre4-ac6/drivers/char/drm/mga_warp.c --- linux.21pre4/drivers/char/drm/mga_warp.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/mga_warp.c 2003-01-06 17:28:08.000000000 +0000 @@ -27,8 +27,11 @@ * Gareth Hughes */ + #include "mga.h" #include "drmP.h" +#include "drm.h" +#include "mga_drm.h" #include "mga_drv.h" #include "mga_ucode.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/r128_cce.c linux.21pre4-ac6/drivers/char/drm/r128_cce.c --- linux.21pre4/drivers/char/drm/r128_cce.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/r128_cce.c 2003-01-06 17:28:08.000000000 +0000 @@ -30,14 +30,14 @@ #include "r128.h" #include "drmP.h" +#include "drm.h" +#include "r128_drm.h" #include "r128_drv.h" - -#include /* For task queue support */ -#include +#include "drm_os_linux.h" +#include #define R128_FIFO_DEBUG 0 - /* CCE microcode (from ATI) */ static u32 r128_cce_microcode[] = { 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, @@ -83,6 +83,7 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ); int R128_READ_PLL(drm_device_t *dev, int addr) { @@ -131,7 +132,7 @@ } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif return -EBUSY; } @@ -147,7 +148,7 @@ } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif return -EBUSY; } @@ -157,7 +158,7 @@ int i, ret; ret = r128_do_wait_for_fifo( dev_priv, 64 ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { @@ -168,7 +169,7 @@ } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif return -EBUSY; } @@ -183,7 +184,7 @@ { int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); r128_do_wait_for_idle( dev_priv ); @@ -319,7 +320,7 @@ u32 ring_start; u32 tmp; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The manual (p. 2) says this address is in "VM space". This * means it's an offset from the start of AGP space. @@ -351,8 +352,8 @@ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08llx handle=0x%08lx\n", - (u64)entry->busaddr[page_ofs], + DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", + entry->busaddr[page_ofs], entry->handle + tmp_ofs ); } @@ -374,9 +375,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) { drm_r128_private_t *dev_priv; - struct list_head *list; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) @@ -481,15 +481,8 @@ dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | (dev_priv->span_offset >> 5)); - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; @@ -622,16 +615,20 @@ if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; +#if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { +#endif DRM_IOREMAPFREE( dev_priv->cce_ring ); DRM_IOREMAPFREE( dev_priv->ring_rptr ); DRM_IOREMAPFREE( dev_priv->buffers ); +#if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, dev_priv->phys_pci_gart, dev_priv->bus_pci_gart )) DRM_ERROR( "failed to cleanup PCI GART!\n" ); } +#endif DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); @@ -713,7 +710,7 @@ */ if ( stop.idle ) { ret = r128_do_cce_idle( dev_priv ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; } /* Finally, we can turn off the CCE. If the engine isn't idle, @@ -790,7 +787,7 @@ static int r128_do_init_pageflip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); @@ -808,7 +805,7 @@ int r128_do_cleanup_pageflip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/r128_drm.h linux.21pre4-ac6/drivers/char/drm/r128_drm.h --- linux.21pre4/drivers/char/drm/r128_drm.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/r128_drm.h 2003-01-06 17:28:08.000000000 +0000 @@ -170,6 +170,27 @@ /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmR128.h) */ + +/* Rage 128 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) +#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) +#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) +#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) +#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) +#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t) + typedef struct drm_r128_init { enum { R128_INIT_CCE = 0x01, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/r128_drv.c linux.21pre4-ac6/drivers/char/drm/r128_drv.c --- linux.21pre4/drivers/char/drm/r128_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/r128_drv.c 2003-01-06 17:28:08.000000000 +0000 @@ -32,48 +32,11 @@ #include #include "r128.h" #include "drmP.h" +#include "drm.h" +#include "r128_drm.h" #include "r128_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "r128" -#define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010917" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, - - -#if 0 -/* GH: Count data sent to card via ring or vertex/indirect buffers. - */ -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#endif - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -81,26 +44,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init r128_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", r128_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/r128_drv.h linux.21pre4-ac6/drivers/char/drm/r128_drv.h --- linux.21pre4/drivers/char/drm/r128_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/r128_drv.h 2003-02-05 17:42:16.000000000 +0000 @@ -33,9 +33,10 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ +#include -#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head ) -#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val ) +#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) typedef struct drm_r128_freelist { unsigned int age; @@ -384,44 +385,11 @@ #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE( reg ) + reg) -#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg))) -static inline u32 _R128_READ(u32 *addr) -{ - mb(); - return *(volatile u32 *)addr; -} -#define R128_WRITE(reg,val) \ -do { \ - wmb(); \ - R128_DEREF(reg) = val; \ -} while (0) -#else -#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) ) -#define R128_WRITE(reg,val) \ -do { \ - R128_DEREF( reg ) = cpu_to_le32( val ); \ -} while (0) -#endif +#define R128_READ(reg) readl( (volatile u32 *) R128_ADDR(reg) ) +#define R128_WRITE(reg,val) writel( (val) , (volatile u32 *) R128_ADDR(reg)) -#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg)) -static inline u8 _R128_READ8(u8 *addr) -{ - mb(); - return *(volatile u8 *)addr; -} -#define R128_WRITE8(reg,val) \ -do { \ - wmb(); \ - R128_DEREF8(reg) = val; \ -} while (0) -#else -#define R128_READ8(reg) R128_DEREF8( reg ) -#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0) -#endif +#define R128_READ8(reg) readb( (volatile u8 *) R128_ADDR(reg) ) +#define R128_WRITE8(reg,val) writeb( (val), (volatile u8 *) R128_ADDR(reg) ) #define R128_WRITE_PLL(addr,val) \ do { \ @@ -470,6 +438,7 @@ return -EBUSY; \ } \ __ring_space_done: ; \ + break; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -493,7 +462,11 @@ * Ring control */ +#if defined(__powerpc__) +#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else #define r128_flush_write_combine() mb() +#endif #define R128_VERBOSE 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/r128.h linux.21pre4-ac6/drivers/char/drm/r128.h --- linux.21pre4/drivers/char/drm/r128.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/r128.h 2003-01-06 17:28:08.000000000 +0000 @@ -43,6 +43,35 @@ #define __HAVE_SG 1 #define __HAVE_PCI_DMA 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "r128" +#define DRIVER_DESC "ATI Rage 128" +#define DRIVER_DATE "20010917" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, + /* Driver customization: */ #define DRIVER_PRERELEASE() do { \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/r128_state.c linux.21pre4-ac6/drivers/char/drm/r128_state.c --- linux.21pre4/drivers/char/drm/r128_state.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/r128_state.c 2003-01-06 17:28:08.000000000 +0000 @@ -29,9 +29,9 @@ #include "r128.h" #include "drmP.h" -#include "r128_drv.h" #include "drm.h" -#include +#include "r128_drm.h" +#include "r128_drv.h" /* ================================================================ @@ -528,7 +528,7 @@ { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + DRM_DEBUG( "page=%d\n", dev_priv->current_page ); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -577,8 +577,7 @@ int prim = buf_priv->prim; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s: buf=%d nbox=%d\n", - __FUNCTION__, buf->idx, sarea_priv->nbox ); + DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox ); if ( 0 ) r128_print_dirty( "dispatch_vertex", sarea_priv->dirty ); @@ -789,7 +788,7 @@ u32 *data; int dword_shift, dwords; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_cp.c linux.21pre4-ac6/drivers/char/drm/radeon_cp.c --- linux.21pre4/drivers/char/drm/radeon_cp.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/radeon_cp.c 2003-02-21 16:23:48.000000000 +0000 @@ -30,21 +30,278 @@ #include "radeon.h" #include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" #include "radeon_drv.h" +#include "drm_os_linux.h" #include /* For task queue support */ #include - #define RADEON_FIFO_DEBUG 0 -#if defined(__alpha__) -# define PCIGART_ENABLED -#else -# undef PCIGART_ENABLED -#endif /* CP microcode (from ATI) */ +static u32 R200_cp_microcode[][2] = { + { 0x21007000, 0000000000 }, + { 0x20007000, 0000000000 }, + { 0x000000ab, 0x00000004 }, + { 0x000000af, 0x00000004 }, + { 0x66544a49, 0000000000 }, + { 0x49494174, 0000000000 }, + { 0x54517d83, 0000000000 }, + { 0x498d8b64, 0000000000 }, + { 0x49494949, 0000000000 }, + { 0x49da493c, 0000000000 }, + { 0x49989898, 0000000000 }, + { 0xd34949d5, 0000000000 }, + { 0x9dc90e11, 0000000000 }, + { 0xce9b9b9b, 0000000000 }, + { 0x000f0000, 0x00000016 }, + { 0x352e232c, 0000000000 }, + { 0x00000013, 0x00000004 }, + { 0x000f0000, 0x00000016 }, + { 0x352e272c, 0000000000 }, + { 0x000f0001, 0x00000016 }, + { 0x3239362f, 0000000000 }, + { 0x000077ef, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000020, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000020, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000020, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00000016, 0x00000004 }, + { 0x0003802a, 0x00000002 }, + { 0x040067e0, 0x00000002 }, + { 0x00000016, 0x00000004 }, + { 0x000077e0, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x000037e1, 0x00000002 }, + { 0x040067e1, 0x00000006 }, + { 0x000077e0, 0x00000002 }, + { 0x000077e1, 0x00000002 }, + { 0x000077e1, 0x00000006 }, + { 0xffffffff, 0000000000 }, + { 0x10000000, 0000000000 }, + { 0x0003802a, 0x00000002 }, + { 0x040067e0, 0x00000006 }, + { 0x00007675, 0x00000002 }, + { 0x00007676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0003802b, 0x00000002 }, + { 0x04002676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0000002e, 0x00000018 }, + { 0x0000002e, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x0000002f, 0x00000018 }, + { 0x0000002f, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x01605000, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00098000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x64c0603d, 0x00000004 }, + { 0x00080000, 0x00000016 }, + { 0000000000, 0000000000 }, + { 0x0400251d, 0x00000002 }, + { 0x00007580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x04002580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x00000046, 0x00000004 }, + { 0x00005000, 0000000000 }, + { 0x00061000, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x00019000, 0x00000002 }, + { 0x00011055, 0x00000014 }, + { 0x00000055, 0x00000012 }, + { 0x0400250f, 0x00000002 }, + { 0x0000504a, 0x00000004 }, + { 0x00007565, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x00000051, 0x00000004 }, + { 0x01e655b4, 0x00000002 }, + { 0x4401b0dc, 0x00000002 }, + { 0x01c110dc, 0x00000002 }, + { 0x2666705d, 0x00000018 }, + { 0x040c2565, 0x00000002 }, + { 0x0000005d, 0x00000018 }, + { 0x04002564, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x00000054, 0x00000004 }, + { 0x00401060, 0x00000008 }, + { 0x00101000, 0x00000002 }, + { 0x000d80ff, 0x00000002 }, + { 0x00800063, 0x00000008 }, + { 0x000f9000, 0x00000002 }, + { 0x000e00ff, 0x00000002 }, + { 0000000000, 0x00000006 }, + { 0x00000080, 0x00000018 }, + { 0x00000054, 0x00000004 }, + { 0x00007576, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00009000, 0x00000002 }, + { 0x00041000, 0x00000002 }, + { 0x0c00350e, 0x00000002 }, + { 0x00049000, 0x00000002 }, + { 0x00051000, 0x00000002 }, + { 0x01e785f8, 0x00000002 }, + { 0x00200000, 0x00000002 }, + { 0x00600073, 0x0000000c }, + { 0x00007563, 0x00000002 }, + { 0x006075f0, 0x00000021 }, + { 0x20007068, 0x00000004 }, + { 0x00005068, 0x00000004 }, + { 0x00007576, 0x00000002 }, + { 0x00007577, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x0000750f, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00600076, 0x0000000c }, + { 0x006075f0, 0x00000021 }, + { 0x000075f8, 0x00000002 }, + { 0x00000076, 0x00000004 }, + { 0x000a750e, 0x00000002 }, + { 0x0020750f, 0x00000002 }, + { 0x00600079, 0x00000004 }, + { 0x00007570, 0x00000002 }, + { 0x00007571, 0x00000002 }, + { 0x00007572, 0x00000006 }, + { 0x00005000, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00007568, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000084, 0x0000000c }, + { 0x00058000, 0x00000002 }, + { 0x0c607562, 0x00000002 }, + { 0x00000086, 0x00000004 }, + { 0x00600085, 0x00000004 }, + { 0x400070dd, 0000000000 }, + { 0x000380dd, 0x00000002 }, + { 0x00000093, 0x0000001c }, + { 0x00065095, 0x00000018 }, + { 0x040025bb, 0x00000002 }, + { 0x00061096, 0x00000018 }, + { 0x040075bc, 0000000000 }, + { 0x000075bb, 0x00000002 }, + { 0x000075bc, 0000000000 }, + { 0x00090000, 0x00000006 }, + { 0x00090000, 0x00000002 }, + { 0x000d8002, 0x00000006 }, + { 0x00005000, 0x00000002 }, + { 0x00007821, 0x00000002 }, + { 0x00007800, 0000000000 }, + { 0x00007821, 0x00000002 }, + { 0x00007800, 0000000000 }, + { 0x01665000, 0x00000002 }, + { 0x000a0000, 0x00000002 }, + { 0x000671cc, 0x00000002 }, + { 0x0286f1cd, 0x00000002 }, + { 0x000000a3, 0x00000010 }, + { 0x21007000, 0000000000 }, + { 0x000000aa, 0x0000001c }, + { 0x00065000, 0x00000002 }, + { 0x000a0000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x000b0000, 0x00000002 }, + { 0x38067000, 0x00000002 }, + { 0x000a00a6, 0x00000004 }, + { 0x20007000, 0000000000 }, + { 0x01200000, 0x00000002 }, + { 0x20077000, 0x00000002 }, + { 0x01200000, 0x00000002 }, + { 0x20007000, 0000000000 }, + { 0x00061000, 0x00000002 }, + { 0x0120751b, 0x00000002 }, + { 0x8040750a, 0x00000002 }, + { 0x8040750b, 0x00000002 }, + { 0x00110000, 0x00000002 }, + { 0x000380dd, 0x00000002 }, + { 0x000000bd, 0x0000001c }, + { 0x00061096, 0x00000018 }, + { 0x844075bd, 0x00000002 }, + { 0x00061095, 0x00000018 }, + { 0x840075bb, 0x00000002 }, + { 0x00061096, 0x00000018 }, + { 0x844075bc, 0x00000002 }, + { 0x000000c0, 0x00000004 }, + { 0x804075bd, 0x00000002 }, + { 0x800075bb, 0x00000002 }, + { 0x804075bc, 0x00000002 }, + { 0x00108000, 0x00000002 }, + { 0x01400000, 0x00000002 }, + { 0x006000c4, 0x0000000c }, + { 0x20c07000, 0x00000020 }, + { 0x000000c6, 0x00000012 }, + { 0x00800000, 0x00000006 }, + { 0x0080751d, 0x00000006 }, + { 0x000025bb, 0x00000002 }, + { 0x000040c0, 0x00000004 }, + { 0x0000775c, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00661000, 0x00000002 }, + { 0x0460275d, 0x00000020 }, + { 0x00004000, 0000000000 }, + { 0x00007999, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00661000, 0x00000002 }, + { 0x0460299b, 0x00000020 }, + { 0x00004000, 0000000000 }, + { 0x01e00830, 0x00000002 }, + { 0x21007000, 0000000000 }, + { 0x00005000, 0x00000002 }, + { 0x00038042, 0x00000002 }, + { 0x040025e0, 0x00000002 }, + { 0x000075e1, 0000000000 }, + { 0x00000001, 0000000000 }, + { 0x000380d9, 0x00000002 }, + { 0x04007394, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, +}; + + static u32 radeon_cp_microcode[][2] = { { 0x21007000, 0000000000 }, { 0x20007000, 0000000000 }, @@ -346,6 +603,8 @@ u32 tmp; int i; + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); tmp |= RADEON_RB2D_DC_FLUSH_ALL; RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); @@ -370,6 +629,8 @@ { int i; + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) & RADEON_RBBM_FIFOCNT_MASK ); @@ -388,8 +649,10 @@ { int i, ret; + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + ret = radeon_do_wait_for_fifo( dev_priv, 64 ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(RADEON_READ( RADEON_RBBM_STATUS ) @@ -416,16 +679,31 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) { int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_wait_for_idle( dev_priv ); RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); - for ( i = 0 ; i < 256 ; i++ ) { - RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, - radeon_cp_microcode[i][1] ); - RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, - radeon_cp_microcode[i][0] ); + + if (dev_priv->is_r200) + { + DRM_INFO("Loading R200 Microcode\n"); + for ( i = 0 ; i < 256 ; i++ ) + { + RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, + R200_cp_microcode[i][1] ); + RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, + R200_cp_microcode[i][0] ); + } + } + else + { + for ( i = 0 ; i < 256 ; i++ ) { + RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, + radeon_cp_microcode[i][1] ); + RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, + radeon_cp_microcode[i][0] ); + } } } @@ -435,7 +713,7 @@ */ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); #if 0 u32 tmp; @@ -449,7 +727,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) { RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_RING( 6 ); @@ -458,6 +736,7 @@ RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); + COMMIT_RING(); return radeon_do_wait_for_idle( dev_priv ); } @@ -467,7 +746,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) { RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_wait_for_idle( dev_priv ); @@ -482,6 +761,7 @@ RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); + COMMIT_RING(); } /* Reset the Command Processor. This will not flush any pending @@ -491,7 +771,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) { u32 cur_read_ptr; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); @@ -505,7 +785,7 @@ */ static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); @@ -518,7 +798,7 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_pixcache_flush( dev_priv ); @@ -603,6 +883,7 @@ /* Set the write pointer delay */ RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); + RADEON_READ( RADEON_CP_RB_WPTR_DELAY ); /* read back to propagate */ /* Initialize the ring buffer's read and write pointers */ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); @@ -622,13 +903,63 @@ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08llx handle=0x%08lx\n", - (u64)entry->busaddr[page_ofs], + DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", + entry->busaddr[page_ofs], entry->handle + tmp_ofs ); } + /* Initialize the scratch register pointer. This will cause + * the scratch register values to be written out to memory + * whenever they are updated. + * + * We simply put this behind the ring read pointer, this works + * with PCI GART as well as (whatever kind of) AGP GART + */ + RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR ) + + RADEON_SCRATCH_REG_OFFSET ); + + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring.head + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + + RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); + + /* Writeback doesn't seem to work everywhere, test it first */ + writel(0, &dev_priv->scratch[1]); + RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); + + for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { + if ( readl( &dev_priv->scratch[1] ) == 0xdeadbeef ) + break; + udelay(1); + } + + if ( tmp < dev_priv->usec_timeout ) { + dev_priv->writeback_works = 1; + DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp ); + } else { + dev_priv->writeback_works = 0; + DRM_DEBUG( "writeback test failed\n" ); + } + + dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; + RADEON_WRITE( RADEON_LAST_FRAME_REG, + dev_priv->sarea_priv->last_frame ); + + dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; + RADEON_WRITE( RADEON_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch ); + + dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; + RADEON_WRITE( RADEON_LAST_CLEAR_REG, + dev_priv->sarea_priv->last_clear ); + /* Set ring buffer size */ +#ifdef __BIG_ENDIAN + RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); +#else RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); +#endif radeon_do_wait_for_idle( dev_priv ); @@ -647,9 +978,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) { drm_radeon_private_t *dev_priv; - struct list_head *list; u32 tmp; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) @@ -659,17 +989,6 @@ dev_priv->is_pci = init->is_pci; -#if !defined(PCIGART_ENABLED) - /* PCI support is not 100% working, so we disable it here. - */ - if ( dev_priv->is_pci ) { - DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); - dev->dev_private = (void *)dev_priv; - radeon_do_cleanup_cp(dev); - return -EINVAL; - } -#endif - if ( dev_priv->is_pci && !dev->sg ) { DRM_ERROR( "PCI GART memory not allocated!\n" ); dev->dev_private = (void *)dev_priv; @@ -686,12 +1005,10 @@ return -EINVAL; } + dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP); + dev_priv->do_boxes = 0; dev_priv->cp_mode = init->cp_mode; - /* Simple idle check. - */ - atomic_set( &dev_priv->idle_count, 0 ); - /* We don't support anything other than bus-mastering ring mode, * but the ring can be in either AGP or PCI space for the ring * read pointer. @@ -743,17 +1060,17 @@ * and screwing with the clear operation. */ dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | - RADEON_Z_ENABLE | (dev_priv->color_fmt << 10) | - RADEON_ZBLOCK16); + (1<<15)); - dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | - RADEON_Z_TEST_ALWAYS | - RADEON_STENCIL_TEST_ALWAYS | - RADEON_STENCIL_S_FAIL_KEEP | - RADEON_STENCIL_ZPASS_KEEP | - RADEON_STENCIL_ZFAIL_KEEP | - RADEON_Z_WRITE_ENABLE); + dev_priv->depth_clear.rb3d_zstencilcntl = + (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_REPLACE | + RADEON_STENCIL_ZPASS_REPLACE | + RADEON_STENCIL_ZFAIL_REPLACE | + RADEON_Z_WRITE_ENABLE); dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | RADEON_BFACE_SOLID | @@ -767,15 +1084,8 @@ RADEON_ROUND_MODE_TRUNC | RADEON_ROUND_PREC_8TH_PIX); - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; @@ -896,34 +1206,7 @@ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; -#if 0 - /* Initialize the scratch register pointer. This will cause - * the scratch register values to be written out to memory - * whenever they are updated. - * FIXME: This doesn't quite work yet, so we're disabling it - * for the release. - */ - RADEON_WRITE( RADEON_SCRATCH_ADDR, (dev_priv->ring_rptr->offset + - RADEON_SCRATCH_REG_OFFSET) ); - RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); -#endif - - dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle + - (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - - dev_priv->sarea_priv->last_frame = 0; - RADEON_WRITE( RADEON_LAST_FRAME_REG, - dev_priv->sarea_priv->last_frame ); - - dev_priv->sarea_priv->last_dispatch = 0; - RADEON_WRITE( RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch ); - - dev_priv->sarea_priv->last_clear = 0; - RADEON_WRITE( RADEON_LAST_CLEAR_REG, - dev_priv->sarea_priv->last_clear ); - +#if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart)) { @@ -953,19 +1236,20 @@ RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ } else { +#endif /* __REALLY_HAVE_SG */ /* Turn off PCI GART */ tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN; RADEON_WRITE( RADEON_AIC_CNTL, tmp ); +#if __REALLY_HAVE_SG } +#endif /* __REALLY_HAVE_SG */ radeon_cp_load_microcode( dev_priv ); radeon_cp_init_ring_buffer( dev, dev_priv ); -#if ROTATE_BUFS dev_priv->last_buf = 0; -#endif dev->dev_private = (void *)dev_priv; @@ -976,7 +1260,7 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -986,10 +1270,12 @@ DRM_IOREMAPFREE( dev_priv->ring_rptr ); DRM_IOREMAPFREE( dev_priv->buffers ); } else { +#if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, dev_priv->phys_pci_gart, dev_priv->bus_pci_gart )) DRM_ERROR( "failed to cleanup PCI GART!\n" ); +#endif /* __REALLY_HAVE_SG */ } DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), @@ -1012,6 +1298,7 @@ switch ( init.func ) { case RADEON_INIT_CP: + case RADEON_INIT_R200_CP: return radeon_do_init_cp( dev, &init ); case RADEON_CLEANUP_CP: return radeon_do_cleanup_cp( dev ); @@ -1075,7 +1362,7 @@ */ if ( stop.idle ) { ret = radeon_do_cp_idle( dev_priv ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; } /* Finally, we can turn off the CP. If the engine isn't idle, @@ -1145,117 +1432,74 @@ * Fullscreen mode */ -static int radeon_do_init_pageflip( drm_device_t *dev ) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET ); - dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL ); - - RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset ); - RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, - dev_priv->crtc_offset_cntl | - RADEON_CRTC_OFFSET_FLIP_CNTL ); - - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - - return 0; -} - -int radeon_do_cleanup_pageflip( drm_device_t *dev ) +/* KW: Deprecated to say the least: + */ +int radeon_fullscreen(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) { - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset ); - RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); - - dev_priv->page_flipping = 0; - dev_priv->current_page = 0; - return 0; } -int radeon_fullscreen( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_radeon_fullscreen_t fs; - - LOCK_TEST_WITH_RETURN( dev ); - - if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg, - sizeof(fs) ) ) - return -EFAULT; - - switch ( fs.func ) { - case RADEON_INIT_FULLSCREEN: - return radeon_do_init_pageflip( dev ); - case RADEON_CLEANUP_FULLSCREEN: - return radeon_do_cleanup_pageflip( dev ); - } - - return -EINVAL; -} - /* ================================================================ * Freelist management */ -#define RADEON_BUFFER_USED 0xffffffff -#define RADEON_BUFFER_FREE 0 -#if 0 -static int radeon_freelist_init( drm_device_t *dev ) +/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through + * bufs until freelist code is used. Note this hides a problem with + * the scratch register * (used to keep track of last buffer + * completed) being written to before * the last buffer has actually + * completed rendering. + * + * KW: It's also a good way to find free buffers quickly. + * + * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't + * sleep. However, bugs in older versions of radeon_accel.c mean that + * we essentially have to do this, else old clients will break. + * + * However, it does leave open a potential deadlock where all the + * buffers are held by other clients, which can't release them because + * they can't get the lock. + */ + +drm_buf_t *radeon_freelist_get( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_buf_t *buf; drm_radeon_buf_priv_t *buf_priv; - drm_radeon_freelist_t *entry; - int i; - - dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t), - DRM_MEM_DRIVER ); - if ( dev_priv->head == NULL ) - return -ENOMEM; - - memset( dev_priv->head, 0, sizeof(drm_radeon_freelist_t) ); - dev_priv->head->age = RADEON_BUFFER_USED; + drm_buf_t *buf; + int i, t; + int start; - for ( i = 0 ; i < dma->buf_count ; i++ ) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; + if ( ++dev_priv->last_buf >= dma->buf_count ) + dev_priv->last_buf = 0; - entry = DRM(alloc)( sizeof(drm_radeon_freelist_t), - DRM_MEM_DRIVER ); - if ( !entry ) return -ENOMEM; - - entry->age = RADEON_BUFFER_FREE; - entry->buf = buf; - entry->prev = dev_priv->head; - entry->next = dev_priv->head->next; - if ( !entry->next ) - dev_priv->tail = entry; - - buf_priv->discard = 0; - buf_priv->dispatched = 0; - buf_priv->list_entry = entry; + start = dev_priv->last_buf; - dev_priv->head->next = entry; + for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { + u32 done_age = GET_SCRATCH( 1 ); + DRM_DEBUG("done_age = %d\n",done_age); + for ( i = start ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pid == 0 || (buf->pending && + buf_priv->age <= done_age) ) { + dev_priv->stats.requested_bufs++; + buf->pending = 0; + return buf; + } + start = 0; + } - if ( dev_priv->head->next ) - dev_priv->head->next->prev = entry; + if (t) { + udelay(1); + dev_priv->stats.freelist_loops++; + } } - return 0; - + DRM_DEBUG( "returning NULL!\n" ); + return NULL; } -#endif - +#if 0 drm_buf_t *radeon_freelist_get( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; @@ -1263,76 +1507,40 @@ drm_radeon_buf_priv_t *buf_priv; drm_buf_t *buf; int i, t; -#if ROTATE_BUFS int start; -#endif - - /* FIXME: Optimize -- use freelist code */ + u32 done_age = readl(&dev_priv->scratch[1]); - for ( i = 0 ; i < dma->buf_count ; i++ ) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if ( buf->pid == 0 ) { - DRM_DEBUG( " ret buf=%d last=%d pid=0\n", - buf->idx, dev_priv->last_buf ); - return buf; - } - DRM_DEBUG( " skipping buf=%d pid=%d\n", - buf->idx, buf->pid ); - } - -#if ROTATE_BUFS if ( ++dev_priv->last_buf >= dma->buf_count ) dev_priv->last_buf = 0; + start = dev_priv->last_buf; -#endif - for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { -#if 0 - /* FIXME: Disable this for now */ - u32 done_age = dev_priv->scratch[RADEON_LAST_DISPATCH]; -#else - u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG ); -#endif -#if ROTATE_BUFS + dev_priv->stats.freelist_loops++; + + for ( t = 0 ; t < 2 ; t++ ) { for ( i = start ; i < dma->buf_count ; i++ ) { -#else - for ( i = 0 ; i < dma->buf_count ; i++ ) { -#endif buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pending && buf_priv->age <= done_age ) { - /* The buffer has been processed, so it - * can now be used. - */ + if ( buf->pid == 0 || (buf->pending && + buf_priv->age <= done_age) ) { + dev_priv->stats.requested_bufs++; buf->pending = 0; - DRM_DEBUG( " ret buf=%d last=%d age=%d done=%d\n", buf->idx, dev_priv->last_buf, buf_priv->age, done_age ); return buf; } - DRM_DEBUG( " skipping buf=%d age=%d done=%d\n", - buf->idx, buf_priv->age, - done_age ); -#if ROTATE_BUFS - start = 0; -#endif } - udelay( 1 ); + start = 0; } - DRM_ERROR( "returning NULL!\n" ); return NULL; } +#endif void radeon_freelist_reset( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; -#if ROTATE_BUFS drm_radeon_private_t *dev_priv = dev->dev_private; -#endif int i; -#if ROTATE_BUFS dev_priv->last_buf = 0; -#endif for ( i = 0 ; i < dma->buf_count ; i++ ) { drm_buf_t *buf = dma->buflist[i]; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; @@ -1349,11 +1557,23 @@ { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; + u32 last_head = GET_RING_HEAD(ring); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - radeon_update_ring_snapshot( ring ); + u32 head = GET_RING_HEAD(ring); + + ring->space = (head - ring->tail) * sizeof(u32); + if ( ring->space <= 0 ) + ring->space += ring->size; if ( ring->space > n ) return 0; + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + if (head != last_head) + i = 0; + last_head = head; + udelay( 1 ); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_drm.h linux.21pre4-ac6/drivers/char/drm/radeon_drm.h --- linux.21pre4/drivers/char/drm/radeon_drm.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/radeon_drm.h 2003-02-21 16:20:52.000000000 +0000 @@ -2,6 +2,7 @@ * * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +27,7 @@ * Authors: * Kevin E. Martin * Gareth Hughes + * Keith Whitwell */ #ifndef __RADEON_DRM_H__ @@ -37,7 +39,8 @@ #ifndef __RADEON_SAREA_DEFINES__ #define __RADEON_SAREA_DEFINES__ -/* What needs to be changed for the current vertex buffer? +/* Old style state flags, required for sarea interface (1.1 and 1.2 + * clears) and 1.2 drm_vertex2 ioctl. */ #define RADEON_UPLOAD_CONTEXT 0x00000001 #define RADEON_UPLOAD_VERTFMT 0x00000002 @@ -56,11 +59,136 @@ #define RADEON_UPLOAD_TEX2IMAGES 0x00004000 #define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ #define RADEON_REQUIRE_QUIESCENCE 0x00010000 -#define RADEON_UPLOAD_ALL 0x0001ffff +#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */ +#define RADEON_UPLOAD_ALL 0x003effff +#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff + + +/* New style per-packet identifiers for use in cmd_buffer ioctl with + * the RADEON_EMIT_PACKET command. Comments relate new packets to old + * state bits and the packet size: + */ +#define RADEON_EMIT_PP_MISC 0 /* context/7 */ +#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ +#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ +#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ +#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ +#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ +#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ +#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ +#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ +#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ +#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ +#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ +#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ +#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ +#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ +#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ +#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ +#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ +#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */ +#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */ +#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */ +#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */ +#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */ +#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */ +#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */ +#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */ +#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */ +#define R200_EMIT_TFACTOR_0 30 /* tf/7 */ +#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */ +#define R200_EMIT_VAP_CTL 32 /* vap/1 */ +#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */ +#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */ +#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */ +#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */ +#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */ +#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */ +#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */ +#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */ +#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */ +#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */ +#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */ +#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */ +#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */ +#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */ +#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */ +#define R200_EMIT_VTE_CNTL 48 /* vte/1 */ +#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */ +#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */ +#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */ +#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */ +#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */ +#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */ +#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */ +#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */ +#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */ +#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */ +#define R200_EMIT_PP_CUBIC_FACES_0 61 +#define R200_EMIT_PP_CUBIC_OFFSETS_0 62 +#define R200_EMIT_PP_CUBIC_FACES_1 63 +#define R200_EMIT_PP_CUBIC_OFFSETS_1 64 +#define R200_EMIT_PP_CUBIC_FACES_2 65 +#define R200_EMIT_PP_CUBIC_OFFSETS_2 66 +#define R200_EMIT_PP_CUBIC_FACES_3 67 +#define R200_EMIT_PP_CUBIC_OFFSETS_3 68 +#define R200_EMIT_PP_CUBIC_FACES_4 69 +#define R200_EMIT_PP_CUBIC_OFFSETS_4 70 +#define R200_EMIT_PP_CUBIC_FACES_5 71 +#define R200_EMIT_PP_CUBIC_OFFSETS_5 72 +#define RADEON_MAX_STATE_PACKETS 73 + + +/* Commands understood by cmd_buffer ioctl. More can be added but + * obviously these can't be removed or changed: + */ +#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ +#define RADEON_CMD_SCALARS 2 /* emit scalar data */ +#define RADEON_CMD_VECTORS 3 /* emit vector data */ +#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ +#define RADEON_CMD_PACKET3 5 /* emit hw packet */ +#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ +#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */ +#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: + * doesn't make the cpu wait, just + * the graphics hardware */ + + +typedef union { + int i; + struct { + unsigned char cmd_type, pad0, pad1, pad2; + } header; + struct { + unsigned char cmd_type, packet_id, pad0, pad1; + } packet; + struct { + unsigned char cmd_type, offset, stride, count; + } scalars; + struct { + unsigned char cmd_type, offset, stride, count; + } vectors; + struct { + unsigned char cmd_type, buf_idx, pad0, pad1; + } dma; + struct { + unsigned char cmd_type, flags, pad0, pad1; + } wait; +} drm_radeon_cmd_header_t; + +#define RADEON_WAIT_2D 0x1 +#define RADEON_WAIT_3D 0x2 + #define RADEON_FRONT 0x1 #define RADEON_BACK 0x2 #define RADEON_DEPTH 0x4 +#define RADEON_STENCIL 0x8 /* Primitive types */ @@ -78,12 +206,9 @@ /* Byte offsets for indirect buffer data */ #define RADEON_INDEX_PRIM_OFFSET 20 -#define RADEON_HOSTDATA_BLIT_OFFSET 32 #define RADEON_SCRATCH_REG_OFFSET 32 -/* Keep these small for testing - */ #define RADEON_NR_SAREA_CLIPRECTS 12 /* There are 2 heaps (local/AGP). Each region within a heap is a @@ -95,7 +220,7 @@ #define RADEON_NR_TEX_REGIONS 64 #define RADEON_LOG_TEX_GRANULARITY 16 -#define RADEON_MAX_TEXTURE_LEVELS 11 +#define RADEON_MAX_TEXTURE_LEVELS 12 #define RADEON_MAX_TEXTURE_UNITS 3 #endif /* __RADEON_SAREA_DEFINES__ */ @@ -155,28 +280,18 @@ /* Setup state */ unsigned int se_cntl_status; /* 0x2140 */ -#ifdef TCL_ENABLE - /* TCL state */ - radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */ - radeon_color_regs_t se_tcl_material_ambient; - radeon_color_regs_t se_tcl_material_diffuse; - radeon_color_regs_t se_tcl_material_specular; - unsigned int se_tcl_shininess; - unsigned int se_tcl_output_vtx_fmt; - unsigned int se_tcl_output_vtx_sel; - unsigned int se_tcl_matrix_select_0; - unsigned int se_tcl_matrix_select_1; - unsigned int se_tcl_ucp_vert_blend_ctl; - unsigned int se_tcl_texture_proc_ctl; - unsigned int se_tcl_light_model_ctl; - unsigned int se_tcl_per_light_ctl[4]; -#endif - /* Misc state */ unsigned int re_top_left; /* 0x26c0 */ unsigned int re_misc; } drm_radeon_context_regs_t; +typedef struct { + /* Zbias state */ + unsigned int se_zbias_factor; /* 0x1dac */ + unsigned int se_zbias_constant; +} drm_radeon_context2_regs_t; + + /* Setup registers for each texture unit */ typedef struct { @@ -186,24 +301,37 @@ unsigned int pp_txcblend; unsigned int pp_txablend; unsigned int pp_tfactor; - unsigned int pp_border_color; - -#ifdef CUBIC_ENABLE - unsigned int pp_cubic_faces; - unsigned int pp_cubic_offset[5]; -#endif } drm_radeon_texture_regs_t; typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim:8; + unsigned int stateidx:8; + unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ + unsigned int vc_format; /* vertex format */ +} drm_radeon_prim_t; + + +typedef struct { + drm_radeon_context_regs_t context; + drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS]; + drm_radeon_context2_regs_t context2; + unsigned int dirty; +} drm_radeon_state_t; + + +typedef struct { unsigned char next, prev; unsigned char in_use; int age; } drm_radeon_tex_region_t; typedef struct { - /* The channel for communication of state information to the kernel - * on firing a vertex buffer. + /* The channel for communication of state information to the + * kernel on firing a vertex buffer with either of the + * obsoleted vertex/index ioctls. */ drm_radeon_context_regs_t context_state; drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS]; @@ -225,16 +353,50 @@ drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1]; int tex_age[RADEON_NR_TEX_HEAPS]; int ctx_owner; + int pfState; /* number of 3d windows (0,1,2ormore) */ + int pfCurrentPage; /* which buffer is being displayed? */ + int crtc2_base; /* CRTC2 frame offset */ } drm_radeon_sarea_t; /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmRadeon.h) + * + * KW: actually it's illegal to change any of this (backwards compatibility). */ + +/* Radeon specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) +#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) +#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) +#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) +#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) +#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) +#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) +#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) +#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) +#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) +#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) +#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex2_t) +#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t) +#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t) +#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52) +#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR( 0x53, drm_radeon_mem_alloc_t) +#define DRM_IOCTL_RADEON_FREE DRM_IOW( 0x54, drm_radeon_mem_free_t) +#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( 0x55, drm_radeon_mem_init_heap_t) +#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR( 0x56, drm_radeon_irq_emit_t) +#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( 0x57, drm_radeon_irq_wait_t) + typedef struct drm_radeon_init { enum { RADEON_INIT_CP = 0x01, - RADEON_CLEANUP_CP = 0x02 + RADEON_CLEANUP_CP = 0x02, + RADEON_INIT_R200_CP = 0x03, } func; unsigned long sarea_priv_offset; int is_pci; @@ -285,7 +447,7 @@ unsigned int clear_color; unsigned int clear_depth; unsigned int color_mask; - unsigned int depth_mask; + unsigned int depth_mask; /* misnamed field: should be stencil */ drm_radeon_clear_rect_t *depth_boxes; } drm_radeon_clear_t; @@ -304,6 +466,36 @@ int discard; /* Client finished with buffer? */ } drm_radeon_indices_t; +/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices + * - allows multiple primitives and state changes in a single ioctl + * - supports driver change to emit native primitives + */ +typedef struct drm_radeon_vertex2 { + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ + int nr_states; + drm_radeon_state_t *state; + int nr_prims; + drm_radeon_prim_t *prim; +} drm_radeon_vertex2_t; + +/* v1.3 - obsoletes drm_radeon_vertex2 + * - allows arbitarily large cliprect list + * - allows updating of tcl packet, vector and scalar state + * - allows memory-efficient description of state updates + * - allows state to be emitted without a primitive + * (for clears, ctx switches) + * - allows more than one dma buffer to be referenced per ioctl + * - supports tcl driver + * - may be extended in future versions with new cmd types, packets + */ +typedef struct drm_radeon_cmd_buffer { + int bufsz; + char *buf; + int nbox; + drm_clip_rect_t *boxes; +} drm_radeon_cmd_buffer_t; + typedef struct drm_radeon_tex_image { unsigned int x, y; /* Blit coordinates */ unsigned int width, height; @@ -330,4 +522,55 @@ int discard; } drm_radeon_indirect_t; + +/* 1.3: An ioctl to get parameters that aren't available to the 3d + * client any other way. + */ +#define RADEON_PARAM_AGP_BUFFER_OFFSET 1 /* card offset of 1st agp buffer */ +#define RADEON_PARAM_LAST_FRAME 2 +#define RADEON_PARAM_LAST_DISPATCH 3 +#define RADEON_PARAM_LAST_CLEAR 4 +#define RADEON_PARAM_IRQ_NR 5 +#define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */ + +typedef struct drm_radeon_getparam { + int param; + int *value; +} drm_radeon_getparam_t; + +/* 1.6: Set up a memory manager for regions of shared memory: + */ +#define RADEON_MEM_REGION_AGP 1 +#define RADEON_MEM_REGION_FB 2 + +typedef struct drm_radeon_mem_alloc { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drm_radeon_mem_alloc_t; + +typedef struct drm_radeon_mem_free { + int region; + int region_offset; +} drm_radeon_mem_free_t; + +typedef struct drm_radeon_mem_init_heap { + int region; + int size; + int start; +} drm_radeon_mem_init_heap_t; + + +/* 1.6: Userspace can request & wait on irq's: + */ +typedef struct drm_radeon_irq_emit { + int *irq_seq; +} drm_radeon_irq_emit_t; + +typedef struct drm_radeon_irq_wait { + int irq_seq; +} drm_radeon_irq_wait_t; + + #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_drv.c linux.21pre4-ac6/drivers/char/drm/radeon_drv.c --- linux.21pre4/drivers/char/drm/radeon_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/radeon_drv.c 2003-01-06 17:28:08.000000000 +0000 @@ -30,47 +30,11 @@ #include #include "radeon.h" #include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" #include "radeon_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "radeon" -#define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20010405" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 1 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, - - -#if 0 -/* GH: Count data sent to card via ring or vertex/indirect buffers. - */ -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#endif - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -78,26 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init radeon_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", radeon_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_drv.h linux.21pre4-ac6/drivers/char/drm/radeon_drv.h --- linux.21pre4/drivers/char/drm/radeon_drv.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/radeon_drv.h 2003-02-21 17:01:35.000000000 +0000 @@ -31,6 +31,9 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ +#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) + typedef struct drm_radeon_freelist { unsigned int age; drm_buf_t *buf; @@ -58,6 +61,15 @@ u32 se_cntl; } drm_radeon_depth_clear_t; + +struct mem_block { + struct mem_block *next; + struct mem_block *prev; + int start; + int size; + int pid; /* 0: free, -1: heap, other: real pids */ +}; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; drm_radeon_sarea_t *sarea_priv; @@ -71,27 +83,32 @@ drm_radeon_freelist_t *head; drm_radeon_freelist_t *tail; -/* FIXME: ROTATE_BUFS is a hask to cycle through bufs until freelist - code is used. Note this hides a problem with the scratch register - (used to keep track of last buffer completed) being written to before - the last buffer has actually completed rendering. */ -#define ROTATE_BUFS 1 -#if ROTATE_BUFS int last_buf; -#endif volatile u32 *scratch; + int writeback_works; int usec_timeout; + + int is_r200; + int is_pci; unsigned long phys_pci_gart; dma_addr_t bus_pci_gart; - atomic_t idle_count; + struct { + u32 boxes; + int freelist_timeouts; + int freelist_loops; + int requested_bufs; + int last_frame_reads; + int last_clear_reads; + int clears; + int texture_uploads; + } stats; + int do_boxes; int page_flipping; int current_page; - u32 crtc_offset; - u32 crtc_offset_cntl; u32 color_fmt; unsigned int front_offset; @@ -116,14 +133,18 @@ drm_map_t *ring_rptr; drm_map_t *buffers; drm_map_t *agp_textures; + + struct mem_block *agp_heap; + struct mem_block *fb_heap; + + /* SW interrupt */ + wait_queue_head_t swi_queue; + atomic_t swi_emitted; + } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { u32 age; - int prim; - int discard; - int dispatched; - drm_radeon_freelist_t *list_entry; } drm_radeon_buf_priv_t; /* radeon_cp.c */ @@ -149,14 +170,6 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); -static inline void -radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring ) -{ - ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32); - if ( ring->space <= 0 ) - ring->space += ring->size; -} - extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); extern int radeon_do_cleanup_cp( drm_device_t *dev ); extern int radeon_do_cleanup_pageflip( drm_device_t *dev ); @@ -176,6 +189,34 @@ unsigned int cmd, unsigned long arg ); extern int radeon_cp_indirect( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +extern int radeon_cp_vertex2(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_cp_cmdbuf(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_cp_getparam(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_cp_flip(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); + +extern int radeon_mem_alloc(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_mem_free(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_mem_init_heap(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern void radeon_mem_takedown( struct mem_block **heap ); +extern void radeon_mem_release( struct mem_block *heap ); + + /* radeon_irq.c */ +extern int radeon_irq_emit(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_irq_wait(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); + +extern int radeon_emit_and_wait_irq(drm_device_t *dev); +extern int radeon_wait_irq(drm_device_t *dev, int swi_nr); +extern int radeon_emit_irq(drm_device_t *dev); + + +/* Flags for stats.boxes + */ +#define RADEON_BOX_DMA_IDLE 0x1 +#define RADEON_BOX_RING_FULL 0x2 +#define RADEON_BOX_FLIP 0x4 +#define RADEON_BOX_WAIT_IDLE 0x8 +#define RADEON_BOX_TEXTURE_LOAD 0x10 + /* Register definitions, register access macros and drmAddMap constants @@ -202,10 +243,10 @@ #define RADEON_CRTC_OFFSET_CNTL 0x0228 # define RADEON_CRTC_TILE_EN (1 << 15) # define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) +#define RADEON_CRTC2_OFFSET 0x0324 +#define RADEON_CRTC2_OFFSET_CNTL 0x0328 #define RADEON_RB3D_COLORPITCH 0x1c48 -#define RADEON_RB3D_DEPTHCLEARVALUE 0x1c30 -#define RADEON_RB3D_DEPTHXY_OFFSET 0x1c60 #define RADEON_DP_GUI_MASTER_CNTL 0x146c # define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) @@ -240,6 +281,24 @@ #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 +#define GET_SCRATCH( x ) (dev_priv->writeback_works \ + ? readl( &dev_priv->scratch[(x)] ) \ + : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) + + +#define RADEON_GEN_INT_CNTL 0x0040 +# define RADEON_CRTC_VBLANK_MASK (1 << 0) +# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) +# define RADEON_SW_INT_ENABLE (1 << 25) + +#define RADEON_GEN_INT_STATUS 0x0044 +# define RADEON_CRTC_VBLANK_STAT (1 << 0) +# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) +# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) +# define RADEON_SW_INT_TEST (1 << 25) +# define RADEON_SW_INT_TEST_ACK (1 << 25) +# define RADEON_SW_INT_FIRE (1 << 26) + #define RADEON_HOST_PATH_CNTL 0x0130 # define RADEON_HDP_SOFT_RESET (1 << 26) # define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) @@ -253,6 +312,12 @@ # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) +#define RADEON_RBBM_GUICNTL 0x172c +# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) +# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) +# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) +# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) + #define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_MCLK_CNTL 0x0012 @@ -290,10 +355,8 @@ # define RADEON_ROP_ENABLE (1 << 6) # define RADEON_STENCIL_ENABLE (1 << 7) # define RADEON_Z_ENABLE (1 << 8) -# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) -# define RADEON_ZBLOCK8 (0 << 15) -# define RADEON_ZBLOCK16 (1 << 15) #define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_DEPTHPITCH 0x1c28 #define RADEON_RB3D_PLANEMASK 0x1d84 #define RADEON_RB3D_STENCILREFMASK 0x1d7c #define RADEON_RB3D_ZCACHE_MODE 0x3250 @@ -306,9 +369,9 @@ # define RADEON_Z_TEST_MASK (7 << 4) # define RADEON_Z_TEST_ALWAYS (7 << 4) # define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) -# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) -# define RADEON_STENCIL_ZFAIL_KEEP (0 << 20) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) # define RADEON_Z_WRITE_ENABLE (1 << 30) #define RADEON_RBBM_SOFT_RESET 0x00f0 # define RADEON_SOFT_RESET_CP (1 << 0) @@ -357,6 +420,16 @@ #define RADEON_SE_CNTL_STATUS 0x2140 #define RADEON_SE_LINE_WIDTH 0x1db8 #define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SE_ZBIAS_FACTOR 0x1db0 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 +#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200 +# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16 +# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28 +#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204 +#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208 +# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16 +#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C #define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8 #define RADEON_SURFACE_ACCESS_CLR 0x0bfc #define RADEON_SURFACE_CNTL 0x0b00 @@ -421,6 +494,7 @@ #define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_CNTL 0x0704 +# define RADEON_BUF_SWAP_32BIT (2 << 16) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -457,11 +531,14 @@ #define RADEON_CP_PACKET3 0xC0000000 # define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 # define RADEON_WAIT_FOR_IDLE 0x00002600 +# define RADEON_3D_DRAW_VBUF 0x00002800 # define RADEON_3D_DRAW_IMMD 0x00002900 -# define RADEON_3D_CLEAR_ZMASK 0x00003200 +# define RADEON_3D_DRAW_INDX 0x00002A00 +# define RADEON_3D_LOAD_VBPNTR 0x00002F00 # define RADEON_CNTL_HOSTDATA_BLT 0x00009400 # define RADEON_CNTL_PAINT_MULTI 0x00009A00 # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 +# define RADEON_CNTL_SET_SCISSORS 0xC0001E00 #define RADEON_CP_PACKET_MASK 0xC0000000 #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 @@ -470,6 +547,7 @@ #define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 #define RADEON_VTX_Z_PRESENT (1 << 31) +#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3) #define RADEON_PRIM_TYPE_NONE (0 << 0) #define RADEON_PRIM_TYPE_POINT (1 << 0) @@ -482,6 +560,7 @@ #define RADEON_PRIM_TYPE_RECT_LIST (8 << 0) #define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) #define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) +#define RADEON_PRIM_TYPE_MASK 0xf #define RADEON_PRIM_WALK_IND (1 << 4) #define RADEON_PRIM_WALK_LIST (2 << 4) #define RADEON_PRIM_WALK_RING (3 << 4) @@ -508,6 +587,105 @@ #define RADEON_TXFORMAT_ARGB4444 5 #define RADEON_TXFORMAT_ARGB8888 6 #define RADEON_TXFORMAT_RGBA8888 7 +#define RADEON_TXFORMAT_VYUY422 10 +#define RADEON_TXFORMAT_YVYU422 11 +#define RADEON_TXFORMAT_DXT1 12 +#define RADEON_TXFORMAT_DXT23 14 +#define RADEON_TXFORMAT_DXT45 15 + +#define R200_PP_TXCBLEND_0 0x2f00 +#define R200_PP_TXCBLEND_1 0x2f10 +#define R200_PP_TXCBLEND_2 0x2f20 +#define R200_PP_TXCBLEND_3 0x2f30 +#define R200_PP_TXCBLEND_4 0x2f40 +#define R200_PP_TXCBLEND_5 0x2f50 +#define R200_PP_TXCBLEND_6 0x2f60 +#define R200_PP_TXCBLEND_7 0x2f70 +#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 +#define R200_PP_TFACTOR_0 0x2ee0 +#define R200_SE_VTX_FMT_0 0x2088 +#define R200_SE_VAP_CNTL 0x2080 +#define R200_SE_TCL_MATRIX_SEL_0 0x2230 +#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 +#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 +#define R200_PP_TXFILTER_5 0x2ca0 +#define R200_PP_TXFILTER_4 0x2c80 +#define R200_PP_TXFILTER_3 0x2c60 +#define R200_PP_TXFILTER_2 0x2c40 +#define R200_PP_TXFILTER_1 0x2c20 +#define R200_PP_TXFILTER_0 0x2c00 +#define R200_PP_TXOFFSET_5 0x2d78 +#define R200_PP_TXOFFSET_4 0x2d60 +#define R200_PP_TXOFFSET_3 0x2d48 +#define R200_PP_TXOFFSET_2 0x2d30 +#define R200_PP_TXOFFSET_1 0x2d18 +#define R200_PP_TXOFFSET_0 0x2d00 + +#define R200_PP_CUBIC_FACES_0 0x2c18 +#define R200_PP_CUBIC_FACES_1 0x2c38 +#define R200_PP_CUBIC_FACES_2 0x2c58 +#define R200_PP_CUBIC_FACES_3 0x2c78 +#define R200_PP_CUBIC_FACES_4 0x2c98 +#define R200_PP_CUBIC_FACES_5 0x2cb8 +#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 +#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 +#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c +#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 +#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 +#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c +#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 +#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 +#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 +#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c +#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 +#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 +#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c +#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 +#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 +#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c +#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 +#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 +#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 +#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c +#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 +#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 +#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c +#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 +#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 +#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c +#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 +#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 +#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 +#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c + +#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 +#define R200_SE_VTE_CNTL 0x20b0 +#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 +#define R200_PP_TAM_DEBUG3 0x2d9c +#define R200_PP_CNTL_X 0x2cc4 +#define R200_SE_VAP_CNTL_STATUS 0x2140 +#define R200_RE_SCISSOR_TL_0 0x1cd8 +#define R200_RE_SCISSOR_TL_1 0x1ce0 +#define R200_RE_SCISSOR_TL_2 0x1ce8 +#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 +#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 +#define R200_SE_VTX_STATE_CNTL 0x2180 +#define R200_RE_POINTSIZE 0x2648 +#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 + + +#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 +#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 +#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012 +#define SE_VTE_CNTL__VTX_XY_FMT_MASK 0x00000100 +#define SE_VTE_CNTL__VTX_Z_FMT_MASK 0x00000200 +#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK 0x00000001 +#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK 0x00000002 +#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b +#define R200_3D_DRAW_IMMD_2 0xC0003500 +#define R200_SE_VTX_FMT_1 0x208c +#define R200_RE_CNTL 0x1c50 + /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -515,6 +693,7 @@ #define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0 #define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1 #define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2 +#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 #define RADEON_LAST_DISPATCH 1 #define RADEON_MAX_VB_AGE 0x7fffffff @@ -526,41 +705,11 @@ #define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) -#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) -#ifdef __alpha__ -#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg ))) -static inline u32 _RADEON_READ(u32 *addr) -{ - mb(); - return *(volatile u32 *)addr; -} -#define RADEON_WRITE(reg,val) \ -do { \ - wmb(); \ - RADEON_DEREF(reg) = val; \ -} while (0) -#else -#define RADEON_READ(reg) RADEON_DEREF( reg ) -#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0) -#endif +#define RADEON_READ(reg) readl( (volatile u32 *) RADEON_ADDR(reg) ) +#define RADEON_WRITE(reg,val) writel( (val), (volatile u32 *) RADEON_ADDR(reg)) -#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) -#ifdef __alpha__ -#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg )) -static inline u8 _RADEON_READ8(u8 *addr) -{ - mb(); - return *(volatile u8 *)addr; -} -#define RADEON_WRITE8(reg,val) \ -do { \ - wmb(); \ - RADEON_DEREF8( reg ) = val; \ -} while (0) -#else -#define RADEON_READ8(reg) RADEON_DEREF8( reg ) -#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0) -#endif +#define RADEON_READ8(reg) readb( (volatile u8 *) RADEON_ADDR(reg) ) +#define RADEON_WRITE8(reg,val) writeb( (val), (volatile u8 *) RADEON_ADDR(reg)) #define RADEON_WRITE_PLL( addr, val ) \ do { \ @@ -647,20 +796,16 @@ } \ } while (0) + +/* Perfbox functionality only. + */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ - drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \ - if ( ring->space < ring->high_mark ) { \ - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ - radeon_update_ring_snapshot( ring ); \ - if ( ring->space >= ring->high_mark ) \ - goto __ring_space_done; \ - udelay( 1 ); \ - } \ - DRM_ERROR( "ring space check failed!\n" ); \ - return -EBUSY; \ + if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \ + u32 head = GET_RING_HEAD(&dev_priv->ring); \ + if (head == dev_priv->ring.tail) \ + dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \ } \ - __ring_space_done: ; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -668,7 +813,7 @@ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ int __ret = radeon_do_cp_idle( dev_priv ); \ - if ( __ret < 0 ) return __ret; \ + if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ radeon_freelist_reset( dev ); \ } \ @@ -694,22 +839,53 @@ * Ring control */ -#define radeon_flush_write_combine() mb() +#define RADEON_VERBOSE 0 +#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; -#define RADEON_VERBOSE 0 +#if defined(__alpha__) +# define RADEON_PAD_RING 16 /* pad ring requests to 16 lw boundaries */ +#else +# define RADEON_PAD_RING 0 +#endif -#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; +#if RADEON_PAD_RING +# define radeon_pad_size(n) \ + (((RADEON_PAD_RING) - ((n) % (RADEON_PAD_RING))) % (RADEON_PAD_RING)) +# define radeon_pad_ring() do { \ + if (RADEON_VERBOSE) { \ + DRM_INFO("Padding ring from %d (%x) with %d words\n", \ + write, write, radeon_pad_size(write)); \ + } \ + switch (radeon_pad_size(write)) { \ + case 0: /* aligned */ \ + break; \ + case 1: /* 1 word */ \ + OUT_RING(CP_PACKET2()); \ + break; \ + default: /* >= 2 words */ \ + OUT_RING(CP_PACKET3(0x1000, radeon_pad_size(write) - 1));\ + write = (write + radeon_pad_size(write)) & mask; \ + write &= mask; \ + break; \ + } \ +} while(0) +#else +# define radeon_pad_size(n) 0 +# define radeon_pad_ring() +#endif -#define BEGIN_RING( n ) do { \ +#define BEGIN_RING( req_n ) do { \ + int n = req_n + radeon_pad_size(req_n); \ if ( RADEON_VERBOSE ) { \ - DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ - n, __FUNCTION__ ); \ + DRM_INFO( "BEGIN_RING( %d (%d) ) in %s\n", \ + n, req_n, __FUNCTION__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + COMMIT_RING(); \ radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ - dev_priv->ring.space -= (n) * sizeof(u32); \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ mask = dev_priv->ring.tail_mask; \ @@ -720,9 +896,23 @@ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ write, dev_priv->ring.tail ); \ } \ - radeon_flush_write_combine(); \ - dev_priv->ring.tail = write; \ - RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \ + radeon_pad_ring(); \ + if (((dev_priv->ring.tail + _nr) & mask) != write) { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ + ((dev_priv->ring.tail + _nr) & mask), \ + write, __LINE__); \ + } else \ + dev_priv->ring.tail = write; \ +} while (0) + +#define COMMIT_RING() do { \ + /* Flush writes to ring */ \ + mb(); \ + GET_RING_HEAD( &dev_priv->ring ); \ + RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ + /* read from PCI bus to ensure correct posting */ \ + RADEON_READ( RADEON_CP_RB_RPTR ); \ } while (0) #define OUT_RING( x ) do { \ @@ -734,6 +924,33 @@ write &= mask; \ } while (0) -#define RADEON_PERFORMANCE_BOXES 0 +#define OUT_RING_REG( reg, val ) do { \ + OUT_RING( CP_PACKET0( reg, 0 ) ); \ + OUT_RING( val ); \ +} while (0) + + +#define OUT_RING_USER_TABLE( tab, sz ) do { \ + int _size = (sz); \ + int *_tab = (tab); \ + \ + if (write + _size > mask) { \ + int i = (mask+1) - write; \ + if (__copy_from_user( (int *)(ring+write), \ + _tab, i*4 )) \ + return -EFAULT; \ + write = 0; \ + _size -= i; \ + _tab += i; \ + } \ + \ + if (_size && __copy_from_user( (int *)(ring+write), \ + _tab, _size*4 )) \ + return -EFAULT; \ + \ + write += _size; \ + write &= mask; \ +} while (0) + #endif /* __RADEON_DRV_H__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon.h linux.21pre4-ac6/drivers/char/drm/radeon.h --- linux.21pre4/drivers/char/drm/radeon.h 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/radeon.h 2003-01-06 17:28:08.000000000 +0000 @@ -44,7 +44,78 @@ #define __HAVE_SG 1 #define __HAVE_PCI_DMA 1 -/* Driver customization: +#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others." + +#define DRIVER_NAME "radeon" +#define DRIVER_DESC "ATI Radeon" +#define DRIVER_DATE "20020828" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 7 +#define DRIVER_PATCHLEVEL 0 + +/* Interface history: + * + * 1.1 - ?? + * 1.2 - Add vertex2 ioctl (keith) + * - Add stencil capability to clear ioctl (gareth, keith) + * - Increase MAX_TEXTURE_LEVELS (brian) + * 1.3 - Add cmdbuf ioctl (keith) + * - Add support for new radeon packets (keith) + * - Add getparam ioctl (keith) + * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). + * 1.4 - Add scratch registers to get_param ioctl. + * 1.5 - Add r200 packets to cmdbuf ioctl + * - Add r200 function to init ioctl + * - Add 'scalar2' instruction to cmdbuf + * 1.6 - Add static agp memory manager + * Add irq handler (won't be turned on unless X server knows to) + * Add irq ioctls and irq_active getparam. + * Add wait command for cmdbuf ioctl + * Add agp offset query for getparam + * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5] + * and R200_PP_CUBIC_OFFSET_F1_[0..5]. + * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and + * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian) + */ +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)] = { radeon_mem_init_heap, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, + + +#define USE_IRQS 1 +#if USE_IRQS +#define __HAVE_DMA_IRQ 1 +#define __HAVE_VBL_IRQ 1 +#define __HAVE_SHARED_IRQ 1 + +/* When a client dies: + * - Check for and clean up flipped page state + * - Free any alloced agp memory. + * + * DRM infrastructure takes care of reclaiming dma buffers. */ #define DRIVER_PRERELEASE() do { \ if ( dev->dev_private ) { \ @@ -52,31 +123,36 @@ if ( dev_priv->page_flipping ) { \ radeon_do_cleanup_pageflip( dev ); \ } \ + radeon_mem_release( dev_priv->agp_heap ); \ } \ } while (0) +/* On unloading the module: + * - Free memory heap structure + * - Remove mappings made at startup and free dev_private. + */ #define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ + if ( dev->dev_private ) { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + radeon_mem_takedown( &(dev_priv->agp_heap) ); \ + radeon_do_cleanup_cp( dev ); \ + } \ } while (0) +#else +#define __HAVE_DMA_IRQ 0 +#endif + /* DMA customization: */ #define __HAVE_DMA 1 -#if 0 -/* GH: Remove this for now... */ -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - return radeon_do_cp_idle( dev_priv ); \ -} while (0) -#endif /* Buffer customization: */ #define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ ((drm_radeon_private_t *)((dev)->dev_private))->buffers #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_irq.c linux.21pre4-ac6/drivers/char/drm/radeon_irq.c --- linux.21pre4/drivers/char/drm/radeon_irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/drm/radeon_irq.c 2003-01-31 11:54:14.000000000 +0000 @@ -0,0 +1,256 @@ +/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- + * + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "radeon.h" +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "drm_os_linux.h" + +/* Interrupts - Used for device synchronization and flushing in the + * following circumstances: + * + * - Exclusive FB access with hw idle: + * - Wait for GUI Idle (?) interrupt, then do normal flush. + * + * - Frame throttling, NV_fence: + * - Drop marker irq's into command stream ahead of time. + * - Wait on irq's with lock *not held* + * - Check each for termination condition + * + * - Internally in cp_getbuffer, etc: + * - as above, but wait with lock held??? + * + * NOTE: These functions are misleadingly named -- the irq's aren't + * tied to dma at all, this is just a hangover from dri prehistory. + */ + +void DRM(dma_service)(int irq, void *arg, struct pt_regs *reg) +{ + drm_device_t *dev = (drm_device_t *) arg; + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + u32 stat; + + stat = RADEON_READ(RADEON_GEN_INT_STATUS); + if (!stat) + return; + + /* SW interrupt */ + if (stat & RADEON_SW_INT_TEST) { + wake_up_interruptible( &dev_priv->swi_queue ); + } + + /* VBLANK interrupt */ + if (stat & RADEON_CRTC_VBLANK_STAT) { + atomic_inc(&dev->vbl_received); + wake_up_interruptible(&dev->vbl_queue); + DRM(vbl_send_signals)(dev); + } + + /* Acknowledge all the bits in GEN_INT_STATUS -- seem to get + * more than we asked for... + */ + RADEON_WRITE(RADEON_GEN_INT_STATUS, stat); +} + +static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv) +{ + u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS ); + if (tmp) + RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp ); +} + +int radeon_emit_irq(drm_device_t *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + unsigned int ret; + RING_LOCALS; + + atomic_inc(&dev_priv->swi_emitted); + ret = atomic_read(&dev_priv->swi_emitted); + + BEGIN_RING( 4 ); + OUT_RING_REG( RADEON_LAST_SWI_REG, ret ); + OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE ); + ADVANCE_RING(); + COMMIT_RING(); + + return ret; +} + + +int radeon_wait_irq(drm_device_t *dev, int swi_nr) +{ + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + int ret = 0; + + if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr) + return 0; + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + /* This is a hack to work around mysterious freezes on certain + * systems: + */ + radeon_acknowledge_irqs( dev_priv ); + + DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * HZ, + RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); + + return ret; +} + +int radeon_emit_and_wait_irq(drm_device_t *dev) +{ + return radeon_wait_irq( dev, radeon_emit_irq(dev) ); +} + + +int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence) +{ + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + radeon_acknowledge_irqs( dev_priv ); + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON( ret, dev->vbl_queue, 3*HZ, + ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) + - ~*sequence + 1 ) <= (1<<23) ) ); + + *sequence = cur_vblank; + + return ret; +} + + +/* Needs the lock as it touches the ring. + */ +int radeon_irq_emit(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_irq_emit_t emit; + int result; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t *)data, + sizeof(emit) ); + + result = radeon_emit_irq( dev ); + + if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + +/* Doesn't need the hardware lock. + */ +int radeon_irq_wait(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_irq_wait_t irqwait; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t *)data, + sizeof(irqwait) ); + + return radeon_wait_irq( dev, irqwait.irq_seq ); +} + + +/* drm_dma.h hooks +*/ +void DRM(driver_irq_preinstall)( drm_device_t *dev ) { + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + + /* Disable *all* interrupts */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + + /* Clear bits if they're already high */ + radeon_acknowledge_irqs( dev_priv ); +} + +void DRM(driver_irq_postinstall)( drm_device_t *dev ) { + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + + atomic_set(&dev_priv->swi_emitted, 0); + init_waitqueue_head( &dev_priv->swi_queue ); + + /* Turn on SW and VBL ints */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, + RADEON_CRTC_VBLANK_MASK | + RADEON_SW_INT_ENABLE ); +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + if ( dev_priv ) { + /* Disable *all* interrupts */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_mem.c linux.21pre4-ac6/drivers/char/drm/radeon_mem.c --- linux.21pre4/drivers/char/drm/radeon_mem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/drm/radeon_mem.c 2003-01-06 17:28:08.000000000 +0000 @@ -0,0 +1,338 @@ +/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*- + * + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#include "radeon.h" +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "drm_os_linux.h" + +/* Very simple allocator for agp memory, working on a static range + * already mapped into each client's address space. + */ + +static struct mem_block *split_block(struct mem_block *p, int start, int size, + int pid ) +{ + /* Maybe cut off the start of an existing block */ + if (start > p->start) { + struct mem_block *newblock = kmalloc(sizeof(*newblock), GFP_KERNEL); + if (!newblock) + goto out; + newblock->start = start; + newblock->size = p->size - (start - p->start); + newblock->pid = 0; + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + p->size -= newblock->size; + p = newblock; + } + + /* Maybe cut off the end of an existing block */ + if (size < p->size) { + struct mem_block *newblock = kmalloc(sizeof(*newblock), GFP_KERNEL); + if (!newblock) + goto out; + newblock->start = start + size; + newblock->size = p->size - size; + newblock->pid = 0; + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + p->size = size; + } + + out: + /* Our block is in the middle */ + p->pid = pid; + return p; +} + +static struct mem_block *alloc_block( struct mem_block *heap, int size, + int align2, int pid ) +{ + struct mem_block *p; + int mask = (1 << align2)-1; + + for (p = heap->next ; p != heap ; p = p->next) { + int start = (p->start + mask) & ~mask; + if (p->pid == 0 && start + size <= p->start + p->size) + return split_block( p, start, size, pid ); + } + + return NULL; +} + +static struct mem_block *find_block( struct mem_block *heap, int start ) +{ + struct mem_block *p; + + for (p = heap->next ; p != heap ; p = p->next) + if (p->start == start) + return p; + + return NULL; +} + + +static void free_block( struct mem_block *p ) +{ + p->pid = 0; + + /* Assumes a single contiguous range. Needs a special pid in + * 'heap' to stop it being subsumed. + */ + if (p->next->pid == 0) { + struct mem_block *q = p->next; + p->size += q->size; + p->next = q->next; + p->next->prev = p; + kfree(q); + } + + if (p->prev->pid == 0) { + struct mem_block *q = p->prev; + q->size += p->size; + q->next = p->next; + q->next->prev = q; + kfree(p); + } +} + +static void print_heap( struct mem_block *heap ) +{ + struct mem_block *p; + + for (p = heap->next ; p != heap ; p = p->next) + DRM_DEBUG("0x%x..0x%x (0x%x) -- owner %d\n", + p->start, p->start + p->size, + p->size, p->pid); +} + +/* Initialize. How to check for an uninitialized heap? + */ +static int init_heap(struct mem_block **heap, int start, int size) +{ + struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); + + if (!blocks) + return -ENOMEM; + + *heap = kmalloc(sizeof(**heap), GFP_KERNEL); + if (!*heap) { + kfree( blocks ); + return -ENOMEM; + } + + blocks->start = start; + blocks->size = size; + blocks->pid = 0; + blocks->next = blocks->prev = *heap; + + memset( *heap, 0, sizeof(**heap) ); + (*heap)->pid = -1; + (*heap)->next = (*heap)->prev = blocks; + return 0; +} + + +/* Free all blocks associated with the releasing pid. + */ +void radeon_mem_release( struct mem_block *heap ) +{ + int pid = current->pid; + struct mem_block *p; + + if (!heap || !heap->next) + return; + + for (p = heap->next ; p != heap ; p = p->next) { + if (p->pid == pid) + p->pid = 0; + } + + /* Assumes a single contiguous range. Needs a special pid in + * 'heap' to stop it being subsumed. + */ + for (p = heap->next ; p != heap ; p = p->next) { + while (p->pid == 0 && p->next->pid == 0) { + struct mem_block *q = p->next; + p->size += q->size; + p->next = q->next; + p->next->prev = p; + kfree(q); + } + } +} + +/* Shutdown. + */ +void radeon_mem_takedown( struct mem_block **heap ) +{ + struct mem_block *p; + + if (!*heap) + return; + + for (p = (*heap)->next ; p != *heap ; ) { + struct mem_block *q = p; + p = p->next; + kfree(q); + } + + kfree( *heap ); + *heap = 0; +} + + + +/* IOCTL HANDLERS */ + +static struct mem_block **get_heap( drm_radeon_private_t *dev_priv, + int region ) +{ + switch( region ) { + case RADEON_MEM_REGION_AGP: + return &dev_priv->agp_heap; + case RADEON_MEM_REGION_FB: + return &dev_priv->fb_heap; + default: + return 0; + } +} + +int radeon_mem_alloc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_mem_alloc_t alloc; + struct mem_block *block, **heap; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t *)data, + sizeof(alloc) ); + + heap = get_heap( dev_priv, alloc.region ); + if (!heap || !*heap) + return -EFAULT; + + /* Make things easier on ourselves: all allocations at least + * 4k aligned. + */ + if (alloc.alignment < 12) + alloc.alignment = 12; + + block = alloc_block( *heap, alloc.size, alloc.alignment, + current->pid ); + + if (!block) + return -ENOMEM; + + if ( copy_to_user( alloc.region_offset, &block->start, + sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + + +int radeon_mem_free(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_mem_free_t memfree; + struct mem_block *block, **heap; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t *)data, + sizeof(memfree) ); + + heap = get_heap( dev_priv, memfree.region ); + if (!heap || !*heap) + return -EFAULT; + + block = find_block( *heap, memfree.region_offset ); + if (!block) + return -EFAULT; + + if (block->pid != current->pid) + return -EPERM; + + free_block( block ); + return 0; +} + +int radeon_mem_init_heap(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_mem_init_heap_t initheap; + struct mem_block **heap; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t *)data, + sizeof(initheap) ); + + heap = get_heap( dev_priv, initheap.region ); + if (!heap) + return -EFAULT; + + if (*heap) { + DRM_ERROR("heap already initialized?"); + return -EFAULT; + } + + return init_heap( heap, initheap.start, initheap.size ); +} + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/radeon_state.c linux.21pre4-ac6/drivers/char/drm/radeon_state.c --- linux.21pre4/drivers/char/drm/radeon_state.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/radeon_state.c 2003-02-21 17:41:58.000000000 +0000 @@ -29,10 +29,11 @@ #include "radeon.h" #include "drmP.h" -#include "radeon_drv.h" #include "drm.h" -#include - +#include "drm_sarea.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "drm_os_linux.h" /* ================================================================ * CP hardware state programming functions @@ -47,360 +48,254 @@ box->x1, box->y1, box->x2, box->y2 ); BEGIN_RING( 4 ); - OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); OUT_RING( (box->y1 << 16) | box->x1 ); - OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_context( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 14 ); - - OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); - OUT_RING( ctx->pp_misc ); - OUT_RING( ctx->pp_fog_color ); - OUT_RING( ctx->re_solid_color ); - OUT_RING( ctx->rb3d_blendcntl ); - OUT_RING( ctx->rb3d_depthoffset ); - OUT_RING( ctx->rb3d_depthpitch ); - OUT_RING( ctx->rb3d_zstencilcntl ); - - OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); - OUT_RING( ctx->pp_cntl ); - OUT_RING( ctx->rb3d_cntl ); - OUT_RING( ctx->rb3d_coloroffset ); - - OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); - OUT_RING( ctx->rb3d_colorpitch ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 2 ); - - OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); - OUT_RING( ctx->se_coord_fmt ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_line( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 5 ); - - OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); - OUT_RING( ctx->re_line_pattern ); - OUT_RING( ctx->re_line_state ); - - OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); - OUT_RING( ctx->se_line_width ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 5 ); - - OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); - OUT_RING( ctx->pp_lum_matrix ); - - OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); - OUT_RING( ctx->pp_rot_matrix_0 ); - OUT_RING( ctx->pp_rot_matrix_1 ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 4 ); - - OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); - OUT_RING( ctx->rb3d_stencilrefmask ); - OUT_RING( ctx->rb3d_ropcntl ); - OUT_RING( ctx->rb3d_planemask ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 7 ); - - OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); - OUT_RING( ctx->se_vport_xscale ); - OUT_RING( ctx->se_vport_xoffset ); - OUT_RING( ctx->se_vport_yscale ); - OUT_RING( ctx->se_vport_yoffset ); - OUT_RING( ctx->se_vport_zscale ); - OUT_RING( ctx->se_vport_zoffset ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 4 ); - - OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); - OUT_RING( ctx->se_cntl ); - OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); - OUT_RING( ctx->se_cntl_status ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv ) -{ -#ifdef TCL_ENABLE - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 29 ); - - OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) ); - OUT_RING( ctx->se_tcl_material_emmissive.red ); - OUT_RING( ctx->se_tcl_material_emmissive.green ); - OUT_RING( ctx->se_tcl_material_emmissive.blue ); - OUT_RING( ctx->se_tcl_material_emmissive.alpha ); - OUT_RING( ctx->se_tcl_material_ambient.red ); - OUT_RING( ctx->se_tcl_material_ambient.green ); - OUT_RING( ctx->se_tcl_material_ambient.blue ); - OUT_RING( ctx->se_tcl_material_ambient.alpha ); - OUT_RING( ctx->se_tcl_material_diffuse.red ); - OUT_RING( ctx->se_tcl_material_diffuse.green ); - OUT_RING( ctx->se_tcl_material_diffuse.blue ); - OUT_RING( ctx->se_tcl_material_diffuse.alpha ); - OUT_RING( ctx->se_tcl_material_specular.red ); - OUT_RING( ctx->se_tcl_material_specular.green ); - OUT_RING( ctx->se_tcl_material_specular.blue ); - OUT_RING( ctx->se_tcl_material_specular.alpha ); - OUT_RING( ctx->se_tcl_shininess ); - OUT_RING( ctx->se_tcl_output_vtx_fmt ); - OUT_RING( ctx->se_tcl_output_vtx_sel ); - OUT_RING( ctx->se_tcl_matrix_select_0 ); - OUT_RING( ctx->se_tcl_matrix_select_1 ); - OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl ); - OUT_RING( ctx->se_tcl_texture_proc_ctl ); - OUT_RING( ctx->se_tcl_light_model_ctl ); - for ( i = 0 ; i < 4 ; i++ ) { - OUT_RING( ctx->se_tcl_per_light_ctl[i] ); - } - - ADVANCE_RING(); -#else - DRM_ERROR( "TCL not enabled!\n" ); -#endif -} - -static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 2 ); - - OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); - OUT_RING( ctx->re_misc ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0]; - RING_LOCALS; - DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); - - BEGIN_RING( 9 ); - - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); - OUT_RING( tex->pp_txfilter ); - OUT_RING( tex->pp_txformat ); - OUT_RING( tex->pp_txoffset ); - OUT_RING( tex->pp_txcblend ); - OUT_RING( tex->pp_txablend ); - OUT_RING( tex->pp_tfactor ); - - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); - OUT_RING( tex->pp_border_color ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1]; - RING_LOCALS; - DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); - - BEGIN_RING( 9 ); - - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); - OUT_RING( tex->pp_txfilter ); - OUT_RING( tex->pp_txformat ); - OUT_RING( tex->pp_txoffset ); - OUT_RING( tex->pp_txcblend ); - OUT_RING( tex->pp_txablend ); - OUT_RING( tex->pp_tfactor ); - - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); - OUT_RING( tex->pp_border_color ); - ADVANCE_RING(); } -static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv ) +/* Emit 1.1 state + */ +static void radeon_emit_state( drm_radeon_private_t *dev_priv, + drm_radeon_context_regs_t *ctx, + drm_radeon_texture_regs_t *tex, + unsigned int dirty ) { - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2]; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 9 ); - - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); - OUT_RING( tex->pp_txfilter ); - OUT_RING( tex->pp_txformat ); - OUT_RING( tex->pp_txoffset ); - OUT_RING( tex->pp_txcblend ); - OUT_RING( tex->pp_txablend ); - OUT_RING( tex->pp_tfactor ); - - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); - OUT_RING( tex->pp_border_color ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); + DRM_DEBUG( "dirty=0x%08x\n", dirty ); if ( dirty & RADEON_UPLOAD_CONTEXT ) { - radeon_emit_context( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT; + BEGIN_RING( 14 ); + OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); + OUT_RING( ctx->pp_misc ); + OUT_RING( ctx->pp_fog_color ); + OUT_RING( ctx->re_solid_color ); + OUT_RING( ctx->rb3d_blendcntl ); + OUT_RING( ctx->rb3d_depthoffset ); + OUT_RING( ctx->rb3d_depthpitch ); + OUT_RING( ctx->rb3d_zstencilcntl ); + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); + OUT_RING( ctx->pp_cntl ); + OUT_RING( ctx->rb3d_cntl ); + OUT_RING( ctx->rb3d_coloroffset ); + OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); + OUT_RING( ctx->rb3d_colorpitch ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_VERTFMT ) { - radeon_emit_vertfmt( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT; + BEGIN_RING( 2 ); + OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); + OUT_RING( ctx->se_coord_fmt ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_LINE ) { - radeon_emit_line( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_LINE; + BEGIN_RING( 5 ); + OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); + OUT_RING( ctx->re_line_pattern ); + OUT_RING( ctx->re_line_state ); + OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); + OUT_RING( ctx->se_line_width ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_BUMPMAP ) { - radeon_emit_bumpmap( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP; + BEGIN_RING( 5 ); + OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); + OUT_RING( ctx->pp_lum_matrix ); + OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); + OUT_RING( ctx->pp_rot_matrix_0 ); + OUT_RING( ctx->pp_rot_matrix_1 ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_MASKS ) { - radeon_emit_masks( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS; + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); + OUT_RING( ctx->rb3d_stencilrefmask ); + OUT_RING( ctx->rb3d_ropcntl ); + OUT_RING( ctx->rb3d_planemask ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_VIEWPORT ) { - radeon_emit_viewport( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT; + BEGIN_RING( 7 ); + OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); + OUT_RING( ctx->se_vport_xscale ); + OUT_RING( ctx->se_vport_xoffset ); + OUT_RING( ctx->se_vport_yscale ); + OUT_RING( ctx->se_vport_yoffset ); + OUT_RING( ctx->se_vport_zscale ); + OUT_RING( ctx->se_vport_zoffset ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_SETUP ) { - radeon_emit_setup( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP; - } - - if ( dirty & RADEON_UPLOAD_TCL ) { -#ifdef TCL_ENABLE - radeon_emit_tcl( dev_priv ); -#endif - sarea_priv->dirty &= ~RADEON_UPLOAD_TCL; + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( ctx->se_cntl ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); + OUT_RING( ctx->se_cntl_status ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_MISC ) { - radeon_emit_misc( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_MISC; + BEGIN_RING( 2 ); + OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); + OUT_RING( ctx->re_misc ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_TEX0 ) { - radeon_emit_tex0( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0; + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); + OUT_RING( tex[0].pp_txfilter ); + OUT_RING( tex[0].pp_txformat ); + OUT_RING( tex[0].pp_txoffset ); + OUT_RING( tex[0].pp_txcblend ); + OUT_RING( tex[0].pp_txablend ); + OUT_RING( tex[0].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); + OUT_RING( tex[0].pp_border_color ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_TEX1 ) { - radeon_emit_tex1( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1; + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); + OUT_RING( tex[1].pp_txfilter ); + OUT_RING( tex[1].pp_txformat ); + OUT_RING( tex[1].pp_txoffset ); + OUT_RING( tex[1].pp_txcblend ); + OUT_RING( tex[1].pp_txablend ); + OUT_RING( tex[1].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); + OUT_RING( tex[1].pp_border_color ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_TEX2 ) { -#if 0 - radeon_emit_tex2( dev_priv ); -#endif - sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2; + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); + OUT_RING( tex[2].pp_txfilter ); + OUT_RING( tex[2].pp_txformat ); + OUT_RING( tex[2].pp_txoffset ); + OUT_RING( tex[2].pp_txcblend ); + OUT_RING( tex[2].pp_txablend ); + OUT_RING( tex[2].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); + OUT_RING( tex[2].pp_border_color ); + ADVANCE_RING(); } +} + +/* Emit 1.2 state + */ +static void radeon_emit_state2( drm_radeon_private_t *dev_priv, + drm_radeon_state_t *state ) +{ + RING_LOCALS; - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); + if (state->dirty & RADEON_UPLOAD_ZBIAS) { + BEGIN_RING( 3 ); + OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) ); + OUT_RING( state->context2.se_zbias_factor ); + OUT_RING( state->context2.se_zbias_constant ); + ADVANCE_RING(); + } + + radeon_emit_state( dev_priv, &state->context, + state->tex, state->dirty ); } +/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in + * 1.3 cmdbuffers allow all previous state to be updated as well as + * the tcl scalar and vector areas. + */ +static struct { + int start; + int len; + const char *name; +} packet[RADEON_MAX_STATE_PACKETS] = { + { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, + { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, + { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, + { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, + { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, + { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, + { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, + { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, + { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, + { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, + { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, + { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, + { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, + { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, + { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" }, + { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, + { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, + { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, + { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, + { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, + { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, + { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, + { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, + { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, + { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, + { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, + { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, + { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, + { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, + { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, + { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, + { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, + { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, + { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, + { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, + { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, + { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, + { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, + { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, + { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, + { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, + { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, + { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, + { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, + { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, + { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, + { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, + { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, + { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, + { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, + { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, + { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, + { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, + { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ + { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ + { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" }, + { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, + { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" }, + { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, + { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" }, + { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, + { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" }, + { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, + { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" }, + { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, +}; + + -#if RADEON_PERFORMANCE_BOXES /* ================================================================ * Performance monitoring functions */ @@ -409,10 +304,12 @@ int x, int y, int w, int h, int r, int g, int b ) { - u32 pitch, offset; u32 color; RING_LOCALS; + x += dev_priv->sarea_priv->boxes[0].x1; + y += dev_priv->sarea_priv->boxes[0].y1; + switch ( dev_priv->color_fmt ) { case RADEON_COLOR_FORMAT_RGB565: color = (((r & 0xf8) << 8) | @@ -425,8 +322,11 @@ break; } - offset = dev_priv->back_offset; - pitch = dev_priv->back_pitch >> 3; + BEGIN_RING( 4 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); + OUT_RING( 0xffffffff ); + ADVANCE_RING(); BEGIN_RING( 6 ); @@ -438,7 +338,12 @@ RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); - OUT_RING( (pitch << 22) | (offset >> 5) ); + if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + OUT_RING( dev_priv->front_pitch_offset ); + } else { + OUT_RING( dev_priv->back_pitch_offset ); + } + OUT_RING( color ); OUT_RING( (x << 16) | y ); @@ -449,53 +354,77 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) { - if ( atomic_read( &dev_priv->idle_count ) == 0 ) { - radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); - } else { - atomic_set( &dev_priv->idle_count, 0 ); + /* Collapse various things into a wait flag -- trying to + * guess if userspase slept -- better just to have them tell us. + */ + if (dev_priv->stats.last_frame_reads > 1 || + dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; } -} -#endif + if (dev_priv->stats.freelist_loops) { + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + } + + /* Purple box for page flipping + */ + if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) + radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 ); + /* Red box if we have to wait for idle at any point + */ + if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) + radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 ); + + /* Blue box: lost context? + */ + /* Yellow box for texture swaps + */ + if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) + radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 ); + + /* Green box if hardware never idles (as far as we can tell) + */ + if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) + radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + + + /* Draw bars indicating number of buffers allocated + * (not a great measure, easily confused) + */ + if (dev_priv->stats.requested_bufs) { + if (dev_priv->stats.requested_bufs > 100) + dev_priv->stats.requested_bufs = 100; + + radeon_clear_box( dev_priv, 4, 16, + dev_priv->stats.requested_bufs, 4, + 196, 128, 128 ); + } + + memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) ); + +} /* ================================================================ * CP command dispatch functions */ -static void radeon_print_dirty( const char *msg, unsigned int flags ) -{ - DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "", - (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", - (flags & RADEON_UPLOAD_LINE) ? "line, " : "", - (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", - (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "", - (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", - (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "", - (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "", - (flags & RADEON_UPLOAD_MISC) ? "misc, " : "", - (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "", - (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "", - (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "", - (flags & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", - (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); -} - static void radeon_cp_dispatch_clear( drm_device_t *dev, drm_radeon_clear_t *clear, drm_radeon_clear_rect_t *depth_boxes ) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; + u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "flags = 0x%x\n", flags ); + + dev_priv->stats.clears++; if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; @@ -505,127 +434,277 @@ if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; } - for ( i = 0 ; i < nbox ; i++ ) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; + if ( flags & (RADEON_FRONT | RADEON_BACK) ) { - DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", - x, y, w, h, flags ); + BEGIN_RING( 4 ); - if ( flags & (RADEON_FRONT | RADEON_BACK) ) { - BEGIN_RING( 4 ); + /* Ensure the 3D stream is idle before doing a + * 2D fill to clear the front or back buffer. + */ + RADEON_WAIT_UNTIL_3D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); + OUT_RING( clear->color_mask ); - /* Ensure the 3D stream is idle before doing a - * 2D fill to clear the front or back buffer. - */ - RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); - OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( clear->color_mask ); + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; - ADVANCE_RING(); + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", + x, y, w, h, flags ); + + if ( flags & RADEON_FRONT ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & RADEON_BACK ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( clear->clear_color ); - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_MASKS); + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } } + } - if ( flags & RADEON_FRONT ) { - BEGIN_RING( 6 ); + /* We have to clear the depth and/or stencil buffers by + * rendering a quad into just those buffers. Thus, we have to + * make sure the 3D engine is configured correctly. + */ + if ( dev_priv->is_r200 && + (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); + int tempPP_CNTL; + int tempRE_CNTL; + int tempRB3D_CNTL; + int tempRB3D_ZSTENCILCNTL; + int tempRB3D_STENCILREFMASK; + int tempRB3D_PLANEMASK; + int tempSE_CNTL; + int tempSE_VTE_CNTL; + int tempSE_VTX_FMT_0; + int tempSE_VTX_FMT_1; + int tempSE_VAP_CNTL; + int tempRE_AUX_SCISSOR_CNTL; - OUT_RING( dev_priv->front_pitch_offset ); - OUT_RING( clear->clear_color ); + tempPP_CNTL = 0; + tempRE_CNTL = 0; - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + tempRB3D_CNTL = depth_clear->rb3d_cntl; + tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */ - ADVANCE_RING(); + tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; + tempRB3D_STENCILREFMASK = 0x0; + + tempSE_CNTL = depth_clear->se_cntl; + + + + /* Disable TCL */ + + tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ + (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); + + tempRB3D_PLANEMASK = 0x0; + + tempRE_AUX_SCISSOR_CNTL = 0x0; + + tempSE_VTE_CNTL = + SE_VTE_CNTL__VTX_XY_FMT_MASK | + SE_VTE_CNTL__VTX_Z_FMT_MASK; + + /* Vertex format (X, Y, Z, W)*/ + tempSE_VTX_FMT_0 = + SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | + SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; + tempSE_VTX_FMT_1 = 0x0; + + + /* + * Depth buffer specific enables + */ + if (flags & RADEON_DEPTH) { + /* Enable depth buffer */ + tempRB3D_CNTL |= RADEON_Z_ENABLE; + } else { + /* Disable depth buffer */ + tempRB3D_CNTL &= ~RADEON_Z_ENABLE; } - if ( flags & RADEON_BACK ) { - BEGIN_RING( 6 ); + /* + * Stencil buffer specific enables + */ + if ( flags & RADEON_STENCIL ) { + tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; + tempRB3D_STENCILREFMASK = clear->depth_mask; + } else { + tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; + tempRB3D_STENCILREFMASK = 0x00000000; + } - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); + BEGIN_RING( 26 ); + RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING( dev_priv->back_pitch_offset ); - OUT_RING( clear->clear_color ); + OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL ); + OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL ); + OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL ); + OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, + tempRB3D_ZSTENCILCNTL ); + OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, + tempRB3D_STENCILREFMASK ); + OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK ); + OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL ); + OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL ); + OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 ); + OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 ); + OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL ); + OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, + tempRE_AUX_SCISSOR_CNTL ); + ADVANCE_RING(); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; - ADVANCE_RING(); + for ( i = 0 ; i < nbox ; i++ ) { + + /* Funny that this should be required -- + * sets top-left? + */ + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + BEGIN_RING( 14 ); + OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) ); + OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | + RADEON_PRIM_WALK_RING | + (3 << RADEON_NUM_VERTICES_SHIFT)) ); + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x3f800000 ); + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x3f800000 ); + OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x3f800000 ); + ADVANCE_RING(); } + } + else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { + + rb3d_cntl = depth_clear->rb3d_cntl; if ( flags & RADEON_DEPTH ) { - drm_radeon_depth_clear_t *depth_clear = - &dev_priv->depth_clear; + rb3d_cntl |= RADEON_Z_ENABLE; + } else { + rb3d_cntl &= ~RADEON_Z_ENABLE; + } - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv ); - } + if ( flags & RADEON_STENCIL ) { + rb3d_cntl |= RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ + } else { + rb3d_cntl &= ~RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = 0x00000000; + } - /* FIXME: Render a rectangle to clear the depth - * buffer. So much for those "fast Z clears"... - */ - BEGIN_RING( 23 ); + BEGIN_RING( 13 ); + RADEON_WAIT_UNTIL_2D_IDLE(); - RADEON_WAIT_UNTIL_2D_IDLE(); + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); + OUT_RING( 0x00000000 ); + OUT_RING( rb3d_cntl ); + + OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, + depth_clear->rb3d_zstencilcntl ); + OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, + rb3d_stencilrefmask ); + OUT_RING_REG( RADEON_RB3D_PLANEMASK, + 0x00000000 ); + OUT_RING_REG( RADEON_SE_CNTL, + depth_clear->se_cntl ); + ADVANCE_RING(); - OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); - OUT_RING( 0x00000000 ); - OUT_RING( depth_clear->rb3d_cntl ); - OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); - OUT_RING( depth_clear->rb3d_zstencilcntl ); - OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) ); - OUT_RING( 0x00000000 ); - OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); - OUT_RING( depth_clear->se_cntl ); + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; + + for ( i = 0 ; i < nbox ; i++ ) { + + /* Funny that this should be required -- + * sets top-left? + */ + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + + BEGIN_RING( 15 ); - OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) ); - OUT_RING( RADEON_VTX_Z_PRESENT ); + OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); + OUT_RING( RADEON_VTX_Z_PRESENT | + RADEON_VTX_PKCOLOR_PRESENT); OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | RADEON_PRIM_WALK_RING | RADEON_MAOS_ENABLE | RADEON_VTX_FMT_RADEON_MODE | (3 << RADEON_NUM_VERTICES_SHIFT)) ); + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_SETUP | - RADEON_UPLOAD_MASKS); } } @@ -651,13 +730,13 @@ drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); -#if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ - radeon_cp_performance_boxes( dev_priv ); -#endif + if (dev_priv->do_boxes) + radeon_cp_performance_boxes( dev_priv ); + /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. @@ -689,9 +768,17 @@ RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS ); - - OUT_RING( dev_priv->back_pitch_offset ); - OUT_RING( dev_priv->front_pitch_offset ); + + /* Make this work even if front & back are flipped: + */ + if (dev_priv->current_page == 0) { + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( dev_priv->front_pitch_offset ); + } + else { + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( dev_priv->back_pitch_offset ); + } OUT_RING( (x << 16) | y ); OUT_RING( (x << 16) | y ); @@ -717,29 +804,33 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; + int offset = (dev_priv->current_page == 1) + ? dev_priv->front_offset : dev_priv->back_offset; + RING_LOCALS; + DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pfCurrentPage); -#if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ - radeon_cp_performance_boxes( dev_priv ); -#endif + if (dev_priv->do_boxes) { + dev_priv->stats.boxes |= RADEON_BOX_FLIP; + radeon_cp_performance_boxes( dev_priv ); + } + /* Update the frame offsets for both CRTCs + */ BEGIN_RING( 6 ); RADEON_WAIT_UNTIL_3D_IDLE(); - RADEON_WAIT_UNTIL_PAGE_FLIPPED(); - - OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) ); - - if ( dev_priv->current_page == 0 ) { - OUT_RING( dev_priv->back_offset ); - dev_priv->current_page = 1; - } else { - OUT_RING( dev_priv->front_offset ); - dev_priv->current_page = 0; - } + OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch + + sarea->frame.x + * ( dev_priv->color_fmt - 2 ) ) & ~7 ) + + offset ); + OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + + offset ); ADVANCE_RING(); @@ -748,6 +839,8 @@ * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = + 1 - dev_priv->current_page; BEGIN_RING( 2 ); @@ -756,82 +849,118 @@ ADVANCE_RING(); } +static int bad_prim_vertex_nr( int primitive, int nr ) +{ + switch (primitive & RADEON_PRIM_TYPE_MASK) { + case RADEON_PRIM_TYPE_NONE: + case RADEON_PRIM_TYPE_POINT: + return nr < 1; + case RADEON_PRIM_TYPE_LINE: + return (nr & 1) || nr == 0; + case RADEON_PRIM_TYPE_LINE_STRIP: + return nr < 2; + case RADEON_PRIM_TYPE_TRI_LIST: + case RADEON_PRIM_TYPE_3VRT_POINT_LIST: + case RADEON_PRIM_TYPE_3VRT_LINE_LIST: + case RADEON_PRIM_TYPE_RECT_LIST: + return nr % 3 || nr == 0; + case RADEON_PRIM_TYPE_TRI_FAN: + case RADEON_PRIM_TYPE_TRI_STRIP: + return nr < 3; + default: + return 1; + } +} + + + +typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim; + unsigned int numverts; + unsigned int offset; + unsigned int vc_format; +} drm_radeon_tcl_prim_t; + static void radeon_cp_dispatch_vertex( drm_device_t *dev, - drm_buf_t *buf ) + drm_buf_t *buf, + drm_radeon_tcl_prim_t *prim, + drm_clip_rect_t *boxes, + int nbox ) + { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = dev_priv->agp_buffers_offset + buf->offset; - int size = buf->used; - int prim = buf_priv->prim; + drm_clip_rect_t box; + int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start; + int numverts = (int)prim->numverts; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox ); - - if ( 0 ) - radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty ); - if ( buf->used ) { - buf_priv->dispatched = 1; + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", + prim->prim, + prim->vc_format, + prim->start, + prim->finish, + prim->numverts); + + if (bad_prim_vertex_nr( prim->prim, prim->numverts )) { + DRM_ERROR( "bad prim %x numverts %d\n", + prim->prim, prim->numverts ); + return; + } + + do { + /* Emit the next cliprect */ + if ( i < nbox ) { + if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + return; - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv ); + radeon_emit_clip_rect( dev_priv, &box ); } - do { - /* Emit the next set of up to three cliprects */ - if ( i < sarea_priv->nbox ) { - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); - } + /* Emit the vertex buffer rendering commands */ + BEGIN_RING( 5 ); - /* Emit the vertex buffer rendering commands */ - BEGIN_RING( 5 ); + OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); + OUT_RING( offset ); + OUT_RING( numverts ); + OUT_RING( prim->vc_format ); + OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (numverts << RADEON_NUM_VERTICES_SHIFT) ); - OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); - OUT_RING( offset ); - OUT_RING( size ); - OUT_RING( format ); - OUT_RING( prim | RADEON_PRIM_WALK_LIST | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (size << RADEON_NUM_VERTICES_SHIFT) ); + ADVANCE_RING(); - ADVANCE_RING(); + i++; + } while ( i < nbox ); +} - i++; - } while ( i < sarea_priv->nbox ); - } - if ( buf_priv->discard ) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); - ADVANCE_RING(); +static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + RING_LOCALS; - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } + buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; - dev_priv->sarea_priv->last_dispatch++; + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + RADEON_DISPATCH_AGE( buf_priv->age ); + ADVANCE_RING(); - sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; + buf->pending = 1; + buf->used = 0; } - static void radeon_cp_dispatch_indirect( drm_device_t *dev, drm_buf_t *buf, int start, int end ) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end ); @@ -852,8 +981,6 @@ data[dwords++] = RADEON_CP_PACKET2; } - buf_priv->dispatched = 1; - /* Fire off the indirect buffer */ BEGIN_RING( 3 ); @@ -863,100 +990,75 @@ ADVANCE_RING(); } - - if ( buf_priv->discard ) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the indirect buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; } + static void radeon_cp_dispatch_indices( drm_device_t *dev, - drm_buf_t *buf, - int start, int end, - int count ) + drm_buf_t *elt_buf, + drm_radeon_tcl_prim_t *prim, + drm_clip_rect_t *boxes, + int nbox ) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = dev_priv->agp_buffers_offset; - int prim = buf_priv->prim; + drm_clip_rect_t box; + int offset = dev_priv->agp_buffers_offset + prim->offset; u32 *data; int dwords; int i = 0; - RING_LOCALS; - DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); - - if ( 0 ) - radeon_print_dirty( "dispatch_indices", sarea_priv->dirty ); - - if ( start != end ) { - buf_priv->dispatched = 1; - - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv ); - } - - dwords = (end - start + 3) / sizeof(u32); - - data = (u32 *)((char *)dev_priv->buffers->handle - + buf->offset + start); - - data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); - - data[1] = offset; - data[2] = RADEON_MAX_VB_VERTS; - data[3] = format; - data[4] = (prim | RADEON_PRIM_WALK_IND | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (count << RADEON_NUM_VERTICES_SHIFT) ); - - if ( count & 0x1 ) { - data[dwords-1] &= 0x0000ffff; - } - - do { - /* Emit the next set of up to three cliprects */ - if ( i < sarea_priv->nbox ) { - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); - } - - radeon_cp_dispatch_indirect( dev, buf, start, end ); + int start = prim->start + RADEON_INDEX_PRIM_OFFSET; + int count = (prim->finish - start) / sizeof(u16); - i++; - } while ( i < sarea_priv->nbox ); + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", + prim->prim, + prim->vc_format, + prim->start, + prim->finish, + prim->offset, + prim->numverts); + + if (bad_prim_vertex_nr( prim->prim, count )) { + DRM_ERROR( "bad prim %x count %d\n", + prim->prim, count ); + return; } - if ( buf_priv->discard ) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); - ADVANCE_RING(); + if ( start >= prim->finish || + (prim->start & 0x7) ) { + DRM_ERROR( "buffer prim %d\n", prim->prim ); + return; + } + + dwords = (prim->finish - prim->start + 3) / sizeof(u32); + + data = (u32 *)((char *)dev_priv->buffers->handle + + elt_buf->offset + prim->start); + + data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); + data[1] = offset; + data[2] = prim->numverts; + data[3] = prim->vc_format; + data[4] = (prim->prim | + RADEON_PRIM_WALK_IND | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (count << RADEON_NUM_VERTICES_SHIFT) ); + + do { + if ( i < nbox ) { + if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + return; + + radeon_emit_clip_rect( dev_priv, &box ); + } - buf->pending = 1; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } + radeon_cp_dispatch_indirect( dev, elt_buf, + prim->start, + prim->finish ); - dev_priv->sarea_priv->last_dispatch++; + i++; + } while ( i < nbox ); - sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; } #define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) @@ -967,25 +1069,36 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; u32 format; u32 *buffer; - u8 *data; + const u8 *data; int size, dwords, tex_width, blit_width; - u32 y, height; - int ret = 0, i; + u32 height; + int i; RING_LOCALS; - /* FIXME: Be smarter about this... + dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; + + /* Flush the pixel cache. This ensures no pixel data gets mixed + * up with the texture data from the host data blit, otherwise + * part of the texture image may be corrupted. */ - buf = radeon_freelist_get( dev ); - if ( !buf ) return -EAGAIN; - DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", - tex->offset >> 10, tex->pitch, tex->format, - image->x, image->y, image->width, image->height ); + BEGIN_RING( 4 ); + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_IDLE(); + ADVANCE_RING(); + +#ifdef __BIG_ENDIAN + /* The Mesa texture functions provide the data in little endian as the + * chip wants it, but we need to compensate for the fact that the CP + * ring gets byte-swapped + */ + BEGIN_RING( 2 ); + OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); + ADVANCE_RING(); +#endif - buf_priv = buf->dev_private; /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll @@ -1002,6 +1115,8 @@ case RADEON_TXFORMAT_ARGB1555: case RADEON_TXFORMAT_RGB565: case RADEON_TXFORMAT_ARGB4444: + case RADEON_TXFORMAT_VYUY422: + case RADEON_TXFORMAT_YVYU422: format = RADEON_COLOR_FORMAT_RGB565; tex_width = tex->width * 2; blit_width = image->width * 2; @@ -1020,122 +1135,119 @@ DRM_DEBUG( " tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); - /* Flush the pixel cache. This ensures no pixel data gets mixed - * up with the texture data from the host data blit, otherwise - * part of the texture image may be corrupted. - */ - BEGIN_RING( 4 ); - - RADEON_FLUSH_CACHE(); - RADEON_WAIT_UNTIL_IDLE(); - - ADVANCE_RING(); - - /* Make a copy of the parameters in case we have to update them - * for a multi-pass texture blit. - */ - y = image->y; - height = image->height; - data = (u8 *)image->data; - - size = height * blit_width; + DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); - if ( size > RADEON_MAX_TEXTURE_SIZE ) { - /* Texture image is too large, do a multipass upload */ - ret = -EAGAIN; + do { + DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", + tex->offset >> 10, tex->pitch, tex->format, + image->x, image->y, image->width, image->height ); - /* Adjust the blit size to fit the indirect buffer */ - height = RADEON_MAX_TEXTURE_SIZE / blit_width; + /* Make a copy of some parameters in case we have to + * update them for a multi-pass texture blit. + */ + height = image->height; + data = (const u8 *)image->data; + size = height * blit_width; - /* Update the input parameters for next time */ - image->y += height; - image->height -= height; - image->data = (char *)image->data + size; + if ( size > RADEON_MAX_TEXTURE_SIZE ) { + height = RADEON_MAX_TEXTURE_SIZE / blit_width; + size = height * blit_width; + } else if ( size < 4 && size > 0 ) { + size = 4; + } else if ( size == 0 ) { + return 0; + } - if ( copy_to_user( tex->image, image, sizeof(*image) ) ) { - DRM_ERROR( "EFAULT on tex->image\n" ); - return -EFAULT; + buf = radeon_freelist_get( dev ); + if ( 0 && !buf ) { + radeon_do_cp_idle( dev_priv ); + buf = radeon_freelist_get( dev ); + } + if ( !buf ) { + DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n"); + copy_to_user( tex->image, image, sizeof(*image) ); + return -EAGAIN; } - } else if ( size < 4 && size > 0 ) { - size = 4; - } - dwords = size / 4; + /* Dispatch the indirect buffer. + */ - /* Dispatch the indirect buffer. - */ - buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); - - buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); - buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (format << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_HOST_DATA | - RADEON_GMC_CLR_CMP_CNTL_DIS | - RADEON_GMC_WR_MSK_DIS); - - buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); - buffer[3] = 0xffffffff; - buffer[4] = 0xffffffff; - buffer[5] = (y << 16) | image->x; - buffer[6] = (height << 16) | image->width; - buffer[7] = dwords; - - buffer += 8; - - if ( tex_width >= 32 ) { - /* Texture image width is larger than the minimum, so we - * can upload it directly. - */ - if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) ) { - DRM_ERROR( "EFAULT on data, %d dwords\n", dwords ); - return -EFAULT; - } - } else { - /* Texture image width is less than the minimum, so we - * need to pad out each image scanline to the minimum - * width. - */ - for ( i = 0 ; i < tex->height ; i++ ) { - if ( copy_from_user( buffer, data, tex_width ) ) { - DRM_ERROR( "EFAULT on pad, %d bytes\n", - tex_width ); + buffer = (u32*)((char*)dev_priv->buffers->handle + buf->offset); + dwords = size / 4; + buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); + buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (format << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_HOST_DATA | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS); + + buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); + buffer[3] = 0xffffffff; + buffer[4] = 0xffffffff; + buffer[5] = (image->y << 16) | image->x; + buffer[6] = (height << 16) | image->width; + buffer[7] = dwords; + buffer += 8; + + if ( tex_width >= 32 ) { + /* Texture image width is larger than the minimum, so we + * can upload it directly. + */ + if ( copy_from_user( buffer, data, + dwords * sizeof(u32) ) ) { + DRM_ERROR( "EFAULT on data, %d dwords\n", + dwords ); return -EFAULT; } - buffer += 8; - data += tex_width; + } else { + /* Texture image width is less than the minimum, so we + * need to pad out each image scanline to the minimum + * width. + */ + for ( i = 0 ; i < tex->height ; i++ ) { + if ( copy_from_user( buffer, data, + tex_width ) ) { + DRM_ERROR( "EFAULT on pad, %d bytes\n", + tex_width ); + return -EFAULT; + } + buffer += 8; + data += tex_width; + } } - } + buf->pid = current->pid; + buf->used = (dwords + 8) * sizeof(u32); + radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); + radeon_cp_discard_buffer( dev, buf ); - buf->pid = current->pid; - buf->used = (dwords + 8) * sizeof(u32); - buf_priv->discard = 1; - - radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); + /* Update the input parameters for next time */ + image->y += height; + image->height -= height; + (const u8 *)image->data += size; + } while (image->height > 0); /* Flush the pixel cache after the blit completes. This ensures * the texture data is written out to memory before rendering * continues. */ BEGIN_RING( 4 ); - RADEON_FLUSH_CACHE(); RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - - return ret; + return 0; } + static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) { drm_radeon_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_RING( 35 ); @@ -1158,31 +1270,95 @@ int radeon_cp_clear( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_clear_t clear; + drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg, + sizeof(clear) ) ) + return -EFAULT; + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + + if ( copy_from_user( &depth_boxes, clear.depth_boxes, + sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) + return -EFAULT; + + radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); + + COMMIT_RING(); + return 0; +} + + +/* Not sure why this isn't set all the time: + */ +static int radeon_do_init_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "\n" ); + + BEGIN_RING( 6 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); + OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); + OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) ); + OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); + ADVANCE_RING(); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; + + return 0; +} + +/* Called whenever a client dies, from DRM(release). + * NOTE: Lock isn't necessarily held when this is called! + */ +int radeon_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + if (dev_priv->current_page != 0) + radeon_cp_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +/* Swapping and flipping are different operations, need different ioctls. + * They can & should be intermixed to support multiple 3d windows. + */ +int radeon_cp_flip(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_clear_t clear; - drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg, - sizeof(clear) ) ) - return -EFAULT; - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - - if ( copy_from_user( &depth_boxes, clear.depth_boxes, - sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) - return -EFAULT; - - radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); + if (!dev_priv->page_flipping) + radeon_do_init_pageflip( dev ); + + radeon_cp_dispatch_flip( dev ); + COMMIT_RING(); return 0; } @@ -1193,7 +1369,7 @@ drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -1202,14 +1378,10 @@ if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - if ( !dev_priv->page_flipping ) { - radeon_cp_dispatch_swap( dev ); - dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_MASKS); - } else { - radeon_cp_dispatch_flip( dev ); - } + radeon_cp_dispatch_swap( dev ); + dev_priv->sarea_priv->ctx_owner = 0; + COMMIT_RING(); return 0; } @@ -1219,10 +1391,11 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; drm_radeon_vertex_t vertex; + drm_radeon_tcl_prim_t prim; LOCK_TEST_WITH_RETURN( dev ); @@ -1235,8 +1408,8 @@ sizeof(vertex) ) ) return -EFAULT; - DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n", - __FUNCTION__, current->pid, + DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", + current->pid, vertex.idx, vertex.count, vertex.discard ); if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { @@ -1254,7 +1427,6 @@ VB_AGE_TEST_WITH_RETURN( dev_priv ); buf = dma->buflist[vertex.idx]; - buf_priv = buf->dev_private; if ( buf->pid != current->pid ) { DRM_ERROR( "process %d using buffer owned by %d\n", @@ -1266,12 +1438,39 @@ return -EINVAL; } - buf->used = vertex.count; - buf_priv->prim = vertex.prim; - buf_priv->discard = vertex.discard; + /* Build up a prim_t record: + */ + if (vertex.count) { + buf->used = vertex.count; /* not used? */ + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } + + prim.start = 0; + prim.finish = vertex.count; /* unused */ + prim.prim = vertex.prim; + prim.numverts = vertex.count; + prim.vc_format = dev_priv->sarea_priv->vc_format; + + radeon_cp_dispatch_vertex( dev, buf, &prim, + dev_priv->sarea_priv->boxes, + dev_priv->sarea_priv->nbox ); + } - radeon_cp_dispatch_vertex( dev, buf ); + if (vertex.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + COMMIT_RING(); return 0; } @@ -1281,10 +1480,11 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; drm_radeon_indices_t elts; + drm_radeon_tcl_prim_t prim; int count; LOCK_TEST_WITH_RETURN( dev ); @@ -1317,7 +1517,6 @@ VB_AGE_TEST_WITH_RETURN( dev_priv ); buf = dma->buflist[elts.idx]; - buf_priv = buf->dev_private; if ( buf->pid != current->pid ) { DRM_ERROR( "process %d using buffer owned by %d\n", @@ -1342,11 +1541,37 @@ } buf->used = elts.end; - buf_priv->prim = elts.prim; - buf_priv->discard = elts.discard; - radeon_cp_dispatch_indices( dev, buf, elts.start, elts.end, count ); + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } + + + /* Build up a prim_t record: + */ + prim.start = elts.start; + prim.finish = elts.end; + prim.prim = elts.prim; + prim.offset = 0; /* offset from start of dma buffers */ + prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + prim.vc_format = dev_priv->sarea_priv->vc_format; + + radeon_cp_dispatch_indices( dev, buf, &prim, + dev_priv->sarea_priv->boxes, + dev_priv->sarea_priv->nbox ); + if (elts.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + COMMIT_RING(); return 0; } @@ -1358,6 +1583,7 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_texture_t tex; drm_radeon_tex_image_t image; + int ret; LOCK_TEST_WITH_RETURN( dev ); @@ -1377,7 +1603,10 @@ RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return radeon_cp_dispatch_texture( dev, &tex, &image ); + ret = radeon_cp_dispatch_texture( dev, &tex, &image ); + + COMMIT_RING(); + return ret; } int radeon_cp_stipple( struct inode *inode, struct file *filp, @@ -1402,6 +1631,7 @@ radeon_cp_dispatch_stipple( dev, mask ); + COMMIT_RING(); return 0; } @@ -1413,7 +1643,6 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; drm_radeon_indirect_t indirect; RING_LOCALS; @@ -1439,7 +1668,6 @@ } buf = dma->buflist[indirect.idx]; - buf_priv = buf->dev_private; if ( buf->pid != current->pid ) { DRM_ERROR( "process %d using buffer owned by %d\n", @@ -1461,7 +1689,6 @@ VB_AGE_TEST_WITH_RETURN( dev_priv ); buf->used = indirect.end; - buf_priv->discard = indirect.discard; /* Wait for the 3D stream to idle before the indirect buffer * containing 2D acceleration commands is processed. @@ -1477,6 +1704,526 @@ * privileged clients. */ radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + if (indirect.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + + + COMMIT_RING(); + return 0; +} + +int radeon_cp_vertex2(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_vertex2_t vertex; + int i; + unsigned char laststate; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, + sizeof(vertex) ); + + DRM_DEBUG( "pid=%d index=%d discard=%d\n", + current->pid, + vertex.idx, vertex.discard ); + + if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1 ); + return -EINVAL; + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf = dma->buflist[vertex.idx]; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + return -EINVAL; + } + + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) + return -EINVAL; + + for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { + drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t tclprim; + + if ( copy_from_user( &prim, &vertex.prim[i], sizeof(prim) ) ) + return -EFAULT; + + if ( prim.stateidx != laststate ) { + drm_radeon_state_t state; + + if ( copy_from_user( &state, + &vertex.state[prim.stateidx], + sizeof(state) ) ) + return -EFAULT; + + radeon_emit_state2( dev_priv, &state ); + + laststate = prim.stateidx; + } + + tclprim.start = prim.start; + tclprim.finish = prim.finish; + tclprim.prim = prim.prim; + tclprim.vc_format = prim.vc_format; + + if ( prim.prim & RADEON_PRIM_WALK_IND ) { + tclprim.offset = prim.numverts * 64; + tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + + radeon_cp_dispatch_indices( dev, buf, &tclprim, + sarea_priv->boxes, + sarea_priv->nbox); + } else { + tclprim.numverts = prim.numverts; + tclprim.offset = 0; /* not used */ + + radeon_cp_dispatch_vertex( dev, buf, &tclprim, + sarea_priv->boxes, + sarea_priv->nbox); + } + + if (sarea_priv->nbox == 1) + sarea_priv->nbox = 0; + } + + if ( vertex.discard ) { + radeon_cp_discard_buffer( dev, buf ); + } + + COMMIT_RING(); + return 0; +} + + +static int radeon_emit_packets( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int id = (int)header.packet.packet_id; + int sz, reg; + int *data = (int *)cmdbuf->buf; + RING_LOCALS; + + if (id >= RADEON_MAX_STATE_PACKETS) + return -EINVAL; + + sz = packet[id].len; + reg = packet[id].start; + + if (sz * sizeof(int) > cmdbuf->bufsz) + return -EINVAL; + + BEGIN_RING(sz+1); + OUT_RING( CP_PACKET0( reg, (sz-1) ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +static __inline__ int radeon_emit_scalars( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset; + int stride = header.scalars.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +/* God this is ugly + */ +static __inline__ int radeon_emit_scalars2( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = ((unsigned int)header.scalars.offset) + 0x100; + int stride = header.scalars.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +static __inline__ int radeon_emit_vectors( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.vectors.count; + int *data = (int *)cmdbuf->buf; + int start = header.vectors.offset; + int stride = header.vectors.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_packet3( drm_device_t *dev, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int cmdsz, tmp; + int *cmd = (int *)cmdbuf->buf; + RING_LOCALS; + + DRM_DEBUG("\n"); + + if (__get_user( tmp, &cmd[0])) + return -EFAULT; + + cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz) + return -EINVAL; + + BEGIN_RING( cmdsz ); + OUT_RING_USER_TABLE( cmd, cmdsz ); + ADVANCE_RING(); + + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +static int radeon_emit_packet3_cliprect( drm_device_t *dev, + drm_radeon_cmd_buffer_t *cmdbuf, + int orig_nbox ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_clip_rect_t box; + int cmdsz, tmp; + int *cmd = (int *)cmdbuf->buf; + drm_clip_rect_t *boxes = cmdbuf->boxes; + int i = 0; + RING_LOCALS; + + DRM_DEBUG("\n"); + + if (__get_user( tmp, &cmd[0])) + return -EFAULT; + + cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz) + return -EINVAL; + + if (!orig_nbox) + goto out; + + do { + if ( i < cmdbuf->nbox ) { + if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + return -EFAULT; + /* FIXME The second and subsequent times round + * this loop, send a WAIT_UNTIL_3D_IDLE before + * calling emit_clip_rect(). This fixes a + * lockup on fast machines when sending + * several cliprects with a cmdbuf, as when + * waving a 2D window over a 3D + * window. Something in the commands from user + * space seems to hang the card when they're + * sent several times in a row. That would be + * the correct place to fix it but this works + * around it until I can figure that out - Tim + * Smith */ + if ( i ) { + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + } + radeon_emit_clip_rect( dev_priv, &box ); + } + + BEGIN_RING( cmdsz ); + OUT_RING_USER_TABLE( cmd, cmdsz ); + ADVANCE_RING(); + + } while ( ++i < cmdbuf->nbox ); + if (cmdbuf->nbox == 1) + cmdbuf->nbox = 0; + + out: + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +static int radeon_emit_wait( drm_device_t *dev, int flags ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG("%s: %x\n", __FUNCTION__, flags); + switch (flags) { + case RADEON_WAIT_2D: + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_2D_IDLE(); + ADVANCE_RING(); + break; + case RADEON_WAIT_3D: + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + break; + case RADEON_WAIT_2D|RADEON_WAIT_3D: + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_IDLE(); + ADVANCE_RING(); + break; + default: + return -EINVAL; + } + + return 0; +} + +int radeon_cp_cmdbuf(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = 0; + int idx; + drm_radeon_cmd_buffer_t cmdbuf; + drm_radeon_cmd_header_t header; + int orig_nbox; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, + sizeof(cmdbuf) ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + + if (verify_area( VERIFY_READ, cmdbuf.buf, cmdbuf.bufsz )) + return -EFAULT; + + if (cmdbuf.nbox && + verify_area( VERIFY_READ, cmdbuf.boxes, + cmdbuf.nbox * sizeof(drm_clip_rect_t))) + return -EFAULT; + + orig_nbox = cmdbuf.nbox; + + while ( cmdbuf.bufsz >= sizeof(header) ) { + + if (__get_user( header.i, (int *)cmdbuf.buf )) { + DRM_ERROR("__get_user %p\n", cmdbuf.buf); + return -EFAULT; + } + + cmdbuf.buf += sizeof(header); + cmdbuf.bufsz -= sizeof(header); + + switch (header.header.cmd_type) { + case RADEON_CMD_PACKET: + DRM_DEBUG("RADEON_CMD_PACKET\n"); + if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_packets failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS: + DRM_DEBUG("RADEON_CMD_SCALARS\n"); + if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_scalars failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_VECTORS: + DRM_DEBUG("RADEON_CMD_VECTORS\n"); + if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_vectors failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_DMA_DISCARD: + DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); + idx = header.dma.buf_idx; + if ( idx < 0 || idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + idx, dma->buf_count - 1 ); + return -EINVAL; + } + + buf = dma->buflist[idx]; + if ( buf->pid != current->pid || buf->pending ) { + DRM_ERROR( "bad buffer\n" ); + return -EINVAL; + } + + radeon_cp_discard_buffer( dev, buf ); + break; + + case RADEON_CMD_PACKET3: + DRM_DEBUG("RADEON_CMD_PACKET3\n"); + if (radeon_emit_packet3( dev, &cmdbuf )) { + DRM_ERROR("radeon_emit_packet3 failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_PACKET3_CLIP: + DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); + if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { + DRM_ERROR("radeon_emit_packet3_clip failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS2: + DRM_DEBUG("RADEON_CMD_SCALARS2\n"); + if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_scalars2 failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_WAIT: + DRM_DEBUG("RADEON_CMD_WAIT\n"); + if (radeon_emit_wait( dev, header.wait.flags )) { + DRM_ERROR("radeon_emit_wait failed\n"); + return -EINVAL; + } + break; + default: + DRM_ERROR("bad cmd_type %d at %p\n", + header.header.cmd_type, + cmdbuf.buf - sizeof(header)); + return -EINVAL; + } + } + + + DRM_DEBUG("DONE\n"); + COMMIT_RING(); + return 0; +} + + + +int radeon_cp_getparam(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_getparam_t param; + int value; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data, + sizeof(param) ); + + DRM_DEBUG( "pid=%d\n", current->pid ); + + switch( param.param ) { + case RADEON_PARAM_AGP_BUFFER_OFFSET: + value = dev_priv->agp_buffers_offset; + break; + case RADEON_PARAM_LAST_FRAME: + dev_priv->stats.last_frame_reads++; + value = GET_SCRATCH( 0 ); + break; + case RADEON_PARAM_LAST_DISPATCH: + value = GET_SCRATCH( 1 ); + break; + case RADEON_PARAM_LAST_CLEAR: + dev_priv->stats.last_clear_reads++; + value = GET_SCRATCH( 2 ); + break; + case RADEON_PARAM_IRQ_NR: + value = dev->irq; + break; + case RADEON_PARAM_AGP_BASE: + value = dev_priv->agp_vm_start; + break; + default: + return -EINVAL; + } + + if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/sis_drm.h linux.21pre4-ac6/drivers/char/drm/sis_drm.h --- linux.21pre4/drivers/char/drm/sis_drm.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/sis_drm.h 2003-01-06 17:28:08.000000000 +0000 @@ -2,6 +2,16 @@ #ifndef _sis_drm_public_h_ #define _sis_drm_public_h_ +/* SiS specific ioctls */ +#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) + typedef struct { int context; unsigned int offset; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/sis_drv.c linux.21pre4-ac6/drivers/char/drm/sis_drv.c --- linux.21pre4/drivers/char/drm/sis_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/sis_drv.c 2003-01-06 17:28:08.000000000 +0000 @@ -31,31 +31,6 @@ #include "sis_drm.h" #include "sis_drv.h" -#define DRIVER_AUTHOR "SIS" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20010503" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ - /* AGP Memory Management */ \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } -#if 0 /* these don't appear to be defined */ - /* SIS Stereo */ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } -#endif - -#define __HAVE_COUNTERS 5 - #include "drm_auth.h" #include "drm_agpsupport.h" #include "drm_bufs.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/sis_ds.c linux.21pre4-ac6/drivers/char/drm/sis_ds.c --- linux.21pre4/drivers/char/drm/sis_ds.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/sis_ds.c 2003-02-21 16:13:09.000000000 +0000 @@ -49,16 +49,19 @@ set_t *set; set = (set_t *)MALLOC(sizeof(set_t)); - if (set) { + if(set) + { for(i = 0; i < SET_SIZE; i++){ set->list[i].free_next = i+1; set->list[i].alloc_next = -1; - } + } + set->list[SET_SIZE-1].free_next = -1; set->free = 0; set->alloc = -1; set->trace = -1; } + return set; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/sis.h linux.21pre4-ac6/drivers/char/drm/sis.h --- linux.21pre4/drivers/char/drm/sis.h 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/sis.h 2003-01-06 17:28:08.000000000 +0000 @@ -24,7 +24,7 @@ * DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.1 2001/05/19 18:29:22 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.2 2001/12/19 21:25:59 dawes Exp $ */ #ifndef __SIS_H__ #define __SIS_H__ @@ -42,6 +42,31 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "SIS" +#define DRIVER_NAME "sis" +#define DRIVER_DESC "SIS 300/630/540" +#define DRIVER_DATE "20010503" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ + /* AGP Memory Management */ \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } +#if 0 /* these don't appear to be defined */ + /* SIS Stereo */ + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } +#endif + +#define __HAVE_COUNTERS 5 + /* Buffer customization: */ #define DRIVER_AGP_BUFFERS_MAP( dev ) \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm/tdfx_drv.c linux.21pre4-ac6/drivers/char/drm/tdfx_drv.c --- linux.21pre4/drivers/char/drm/tdfx_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm/tdfx_drv.c 2003-01-06 17:28:08.000000000 +0000 @@ -82,25 +82,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init tdfx_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", tdfx_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm-4.0/agpsupport.c linux.21pre4-ac6/drivers/char/drm-4.0/agpsupport.c --- linux.21pre4/drivers/char/drm-4.0/agpsupport.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm-4.0/agpsupport.c 2003-01-06 15:38:22.000000000 +0000 @@ -277,7 +277,6 @@ break; case VIA_APOLLO_KT400: head->chipset = "VIA Apollo KT400"; break; - case VIA_APOLLO_P4X400: head->chipset = "VIA Apollo P4X400"; #endif case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/drm-4.0/tdfx_drv.c linux.21pre4-ac6/drivers/char/drm-4.0/tdfx_drv.c --- linux.21pre4/drivers/char/drm-4.0/tdfx_drv.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/drm-4.0/tdfx_drv.c 2003-01-06 19:14:12.000000000 +0000 @@ -554,7 +554,6 @@ lock.context, current->pid, j, dev->lock.lock_time, jiffies); current->state = TASK_INTERRUPTIBLE; - current->policy |= SCHED_YIELD; schedule_timeout(DRM_LOCK_SLICE-j); DRM_DEBUG("jiffies=%d\n", jiffies); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/epca.c linux.21pre4-ac6/drivers/char/epca.c --- linux.21pre4/drivers/char/epca.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/epca.c 2003-02-19 16:15:53.000000000 +0000 @@ -3755,7 +3755,7 @@ case 5: board.port = (unsigned char *)ints[index]; - if (board.port <= 0) + if (ints[index] <= 0) { printk(KERN_ERR " - epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); invalid_lilo_config = 1; @@ -3767,7 +3767,7 @@ case 6: board.membase = (unsigned char *)ints[index]; - if (board.membase <= 0) + if (ints[index] <= 0) { printk(KERN_ERR " - epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase); invalid_lilo_config = 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/genrtc.c linux.21pre4-ac6/drivers/char/genrtc.c --- linux.21pre4/drivers/char/genrtc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/char/genrtc.c 2003-01-28 16:35:25.000000000 +0000 @@ -0,0 +1,533 @@ +/* + * Real Time Clock interface for + * - q40 and other m68k machines, + * - HP PARISC machines + * - PowerPC machines + * emulate some RTC irq capabilities in software + * + * Copyright (C) 1999 Richard Zidlicky + * + * based on Paul Gortmaker's rtc.c device and + * Sam Creasey Generic rtc driver + * + * This driver allows use of the real time clock (built into + * nearly all computers) from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the /proc/dev/rtc + * pseudo-file for status information. + * + * The ioctls can be used to set the interrupt behaviour where + * supported. + * + * The /dev/rtc interface will block on reads until an interrupt + * has been received. If a RTC interrupt has already happened, + * it will output an unsigned long and then block. The output value + * contains the interrupt status in the low byte and the number of + * interrupts since the last read in the remaining high bytes. The + * /dev/rtc interface can also be used with the select(2) call. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + + * 1.01 fix for 2.3.X rz@linux-m68k.org + * 1.02 merged with code from genrtc.c rz@linux-m68k.org + * 1.03 make it more portable zippel@linux-m68k.org + * 1.04 removed useless timer code rz@linux-m68k.org + * 1.05 portable RTC_UIE emulation rz@linux-m68k.org + * 1.06 set_rtc_time can return an error trini@kernel.crashing.org + * 1.07 ported to HP PARISC (hppa) Helge Deller + */ + +#define RTC_VERSION "1.07" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait); + +/* + * Bits in gen_rtc_status. + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ + +static unsigned char gen_rtc_status; /* bitmapped status byte. */ +static unsigned long gen_rtc_irq_data; /* our output to the world */ + +/* months start at 0 now */ +static unsigned char days_in_mo[] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int irq_active; + +#ifdef CONFIG_GEN_RTC_X +struct tq_struct genrtc_task; +static struct timer_list timer_task; + +static unsigned int oldsecs; +static int lostint; +static int tt_exp; + +static void gen_rtc_timer(unsigned long data); + +static volatile int stask_active; /* schedule_task */ +static volatile int ttask_active; /* timer_task */ +static int stop_rtc_timers; /* don't requeue tasks */ +static spinlock_t gen_rtc_lock = SPIN_LOCK_UNLOCKED; + +static void gen_rtc_interrupt(unsigned long arg); + +/* + * Routine to poll RTC seconds field for change as often as posible, + * after first RTC_UIE use timer to reduce polling + */ +static void genrtc_troutine(void *data) +{ + unsigned int tmp = get_rtc_ss(); + + if (stop_rtc_timers) { + stask_active = 0; + return; + } + + if (oldsecs != tmp){ + oldsecs = tmp; + + timer_task.function = gen_rtc_timer; + timer_task.expires = jiffies + HZ - (HZ/10); + tt_exp=timer_task.expires; + ttask_active=1; + stask_active=0; + add_timer(&timer_task); + + gen_rtc_interrupt(0); + } else if (schedule_task(&genrtc_task) == 0) + stask_active = 0; +} + +static void gen_rtc_timer(unsigned long data) +{ + lostint = get_rtc_ss() - oldsecs ; + if (lostint<0) + lostint = 60 - lostint; + if (time_after(jiffies, tt_exp)) + printk(KERN_INFO "genrtc: timer task delayed by %ld jiffies\n", + jiffies-tt_exp); + ttask_active=0; + stask_active=1; + if ((schedule_task(&genrtc_task) == 0)) + stask_active = 0; +} + +/* + * call gen_rtc_interrupt function to signal an RTC_UIE, + * arg is unused. + * Could be invoked either from a real interrupt handler or + * from some routine that periodically (eg 100HZ) monitors + * whether RTC_SECS changed + */ +static void gen_rtc_interrupt(unsigned long arg) +{ + /* We store the status in the low byte and the number of + * interrupts received since the last read in the remainder + * of rtc_irq_data. */ + + gen_rtc_irq_data += 0x100; + gen_rtc_irq_data &= ~0xff; + gen_rtc_irq_data |= RTC_UIE; + + if (lostint){ + printk("genrtc: system delaying clock ticks?\n"); + /* increment count so that userspace knows something is wrong */ + gen_rtc_irq_data += ((lostint-1)<<8); + lostint = 0; + } + + wake_up_interruptible(&gen_rtc_wait); +} + +/* + * Now all the various file operations that we export. + */ +static ssize_t gen_rtc_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long data; + ssize_t retval; + + if (count != sizeof (unsigned int) && count != sizeof (unsigned long)) + return -EINVAL; + + if (file->f_flags & O_NONBLOCK && !gen_rtc_irq_data) + return -EAGAIN; + + add_wait_queue(&gen_rtc_wait, &wait); + retval = -ERESTARTSYS; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + data = xchg(&gen_rtc_irq_data, 0); + if (data) + break; + if (signal_pending(current)) + goto out; + schedule(); + } + + /* first test allows optimizer to nuke this case for 32-bit machines */ + if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) { + unsigned int uidata = data; + retval = put_user(uidata, (unsigned long *)buf); + } + else { + retval = put_user(data, (unsigned long *)buf); + } + if (!retval) + retval = sizeof(unsigned long); + out: + current->state = TASK_RUNNING; + remove_wait_queue(&gen_rtc_wait, &wait); + + return retval; +} + +static unsigned int gen_rtc_poll(struct file *file, + struct poll_table_struct *wait) +{ + poll_wait(file, &gen_rtc_wait, wait); + if (gen_rtc_irq_data != 0) + return POLLIN | POLLRDNORM; + return 0; +} + +#endif + +/* + * Used to disable/enable interrupts, only RTC_UIE supported + * We also clear out any old irq data after an ioctl() that + * meddles with the interrupt enable/disable bits. + */ + +static inline void gen_clear_rtc_irq_bit(unsigned char bit) +{ +#ifdef CONFIG_GEN_RTC_X + stop_rtc_timers = 1; + if (ttask_active){ + del_timer_sync(&timer_task); + ttask_active = 0; + } + while (stask_active) + schedule(); + + spin_lock(&gen_rtc_lock); + irq_active = 0; + spin_unlock(&gen_rtc_lock); +#endif +} + +static inline int gen_set_rtc_irq_bit(unsigned char bit) +{ +#ifdef CONFIG_GEN_RTC_X + spin_lock(&gen_rtc_lock); + if ( !irq_active ) { + irq_active = 1; + stop_rtc_timers = 0; + lostint = 0; + genrtc_task.routine = genrtc_troutine; + oldsecs = get_rtc_ss(); + init_timer(&timer_task); + + stask_active = 1; + if (schedule_task(&genrtc_task) == 0){ + stask_active = 0; + } + } + spin_unlock(&gen_rtc_lock); + gen_rtc_irq_data = 0; + return 0; +#else + return -EINVAL; +#endif +} + +static int gen_rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct rtc_time wtime; + struct rtc_pll_info pll; + + switch (cmd) { + + case RTC_PLL_GET: + if (get_rtc_pll(&pll)) + return -EINVAL; + else + return copy_to_user((void *)arg, &pll, sizeof pll) ? -EFAULT : 0; + + case RTC_PLL_SET: + if (!capable(CAP_SYS_TIME)) + return -EACCES; + if (copy_from_user(&pll, (struct rtc_pll_info*)arg, + sizeof(pll))) + return -EFAULT; + return set_rtc_pll(&pll); + + case RTC_UIE_OFF: /* disable ints from RTC updates. */ + gen_clear_rtc_irq_bit(RTC_UIE); + return 0; + + case RTC_UIE_ON: /* enable ints for RTC updates. */ + return gen_set_rtc_irq_bit(RTC_UIE); + + case RTC_RD_TIME: /* Read the time/date from RTC */ + /* this doesn't get week-day, who cares */ + memset(&wtime, 0, sizeof(wtime)); + get_rtc_time(&wtime); + + return copy_to_user((void *)arg, &wtime, sizeof(wtime)) ? -EFAULT : 0; + + case RTC_SET_TIME: /* Set the RTC */ + { + int year; + unsigned char leap_yr; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&wtime, (struct rtc_time *)arg, + sizeof(wtime))) + return -EFAULT; + + year = wtime.tm_year + 1900; + leap_yr = ((!(year % 4) && (year % 100)) || + !(year % 400)); + + if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) + return -EINVAL; + + if (wtime.tm_mday < 0 || wtime.tm_mday > + (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) + return -EINVAL; + + if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || + wtime.tm_min < 0 || wtime.tm_min >= 60 || + wtime.tm_sec < 0 || wtime.tm_sec >= 60) + return -EINVAL; + + return set_rtc_time(&wtime); + } + } + + return -EINVAL; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int gen_rtc_open(struct inode *inode, struct file *file) +{ + if (gen_rtc_status & RTC_IS_OPEN) + return -EBUSY; + + MOD_INC_USE_COUNT; + + gen_rtc_status |= RTC_IS_OPEN; + gen_rtc_irq_data = 0; + irq_active = 0; + + return 0; +} + +static int gen_rtc_release(struct inode *inode, struct file *file) +{ + /* + * Turn off all interrupts once the device is no longer + * in use and clear the data. + */ + + gen_clear_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE); + + gen_rtc_status &= ~RTC_IS_OPEN; + MOD_DEC_USE_COUNT; + + return 0; +} + +static int gen_rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + + +/* + * The various file operations we support. + */ + +static struct file_operations gen_rtc_fops = { + .owner = THIS_MODULE, +#ifdef CONFIG_GEN_RTC_X + .read = gen_rtc_read, + .poll = gen_rtc_poll, +#endif + .ioctl = gen_rtc_ioctl, + .open = gen_rtc_open, + .release = gen_rtc_release, +}; + +static struct miscdevice rtc_gen_dev = +{ + .minor = RTC_MINOR, + .name = "rtc", + .fops = &gen_rtc_fops, +}; + +static int __init rtc_generic_init(void) +{ + int retval; + + printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); + + retval = misc_register(&rtc_gen_dev); + if(retval < 0) + return retval; + +#ifdef CONFIG_PROC_FS + if((create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL)) == NULL){ + misc_deregister(&rtc_gen_dev); + return -ENOMEM; + } +#endif + + return 0; +} + +static void __exit rtc_generic_exit(void) +{ + remove_proc_entry ("driver/rtc", NULL); + misc_deregister(&rtc_gen_dev); +} + +module_init(rtc_generic_init); +module_exit(rtc_generic_exit); +EXPORT_NO_SYMBOLS; + + +/* + * Info exported via "/proc/rtc". + */ + +#ifdef CONFIG_PROC_FS + +static int gen_rtc_proc_output(char *buf) +{ + char *p; + struct rtc_time tm; + unsigned int flags; + struct rtc_pll_info pll; + + p = buf; + + flags = get_rtc_time(&tm); + + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04u\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1900); + + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + + p += sprintf(p, "alarm\t\t: "); + if (tm.tm_hour <= 24) + p += sprintf(p, "%02d:", tm.tm_hour); + else + p += sprintf(p, "**:"); + + if (tm.tm_min <= 59) + p += sprintf(p, "%02d:", tm.tm_min); + else + p += sprintf(p, "**:"); + + if (tm.tm_sec <= 59) + p += sprintf(p, "%02d\n", tm.tm_sec); + else + p += sprintf(p, "**\n"); + + p += sprintf(p, + "DST_enable\t: %s\n" + "BCD\t\t: %s\n" + "24hr\t\t: %s\n" + "square_wave\t: %s\n" + "alarm_IRQ\t: %s\n" + "update_IRQ\t: %s\n" + "periodic_IRQ\t: %s\n" + "periodic_freq\t: %ld\n" + "batt_status\t: %s\n", + (flags & RTC_DST_EN) ? "yes" : "no", + (flags & RTC_DM_BINARY) ? "no" : "yes", + (flags & RTC_24H) ? "yes" : "no", + (flags & RTC_SQWE) ? "yes" : "no", + (flags & RTC_AIE) ? "yes" : "no", + irq_active ? "yes" : "no", + (flags & RTC_PIE) ? "yes" : "no", + 0L /* freq */, + (flags & RTC_BATT_BAD) ? "bad" : "okay"); + if (!get_rtc_pll(&pll)) + p += sprintf(p, + "PLL adjustment\t: %d\n" + "PLL max +ve adjustment\t: %d\n" + "PLL max -ve adjustment\t: %d\n" + "PLL +ve adjustment factor\t: %d\n" + "PLL -ve adjustment factor\t: %d\n" + "PLL frequency\t: %ld\n", + pll.pll_value, + pll.pll_max, + pll.pll_min, + pll.pll_posmult, + pll.pll_negmult, + pll.pll_clock); + return p - buf; +} + +static int gen_rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = gen_rtc_proc_output (page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +#endif /* CONFIG_PROC_FS */ + + +MODULE_AUTHOR("Richard Zidlicky"); +MODULE_LICENSE("GPL"); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/ipmi/ipmi_kcs_intf.c linux.21pre4-ac6/drivers/char/ipmi/ipmi_kcs_intf.c --- linux.21pre4/drivers/char/ipmi/ipmi_kcs_intf.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/ipmi/ipmi_kcs_intf.c 2003-01-09 00:30:24.000000000 +0000 @@ -252,6 +252,7 @@ if (kcs_info->msg_flags & WDT_PRE_TIMEOUT_INT) { /* Watchdog pre-timeout */ start_clear_flags(kcs_info); + kcs_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; spin_unlock(&(kcs_info->kcs_lock)); ipmi_smi_watchdog_pretimeout(kcs_info->intf); spin_lock(&(kcs_info->kcs_lock)); @@ -323,13 +324,18 @@ case KCS_GETTING_FLAGS: { unsigned char msg[4]; + unsigned int len; /* We got the flags from the KCS, now handle them. */ - kcs_get_result(kcs_info->kcs_sm, msg, 4); + len = kcs_get_result(kcs_info->kcs_sm, msg, 4); if (msg[2] != 0) { /* Error fetching flags, just give up for now. */ kcs_info->kcs_state = KCS_NORMAL; + } else if (len < 3) { + /* Hmm, no flags. That's technically illegal, but + don't use uninitialized data. */ + kcs_info->kcs_state = KCS_NORMAL; } else { kcs_info->msg_flags = msg[3]; handle_flags(kcs_info); @@ -1036,7 +1042,9 @@ int rv = 0; int pos = 0; int i = 0; +#ifdef CONFIG_ACPI unsigned long physaddr = 0; +#endif if (initialized) return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/ipmi/ipmi_kcs_sm.c linux.21pre4-ac6/drivers/char/ipmi/ipmi_kcs_sm.c --- linux.21pre4/drivers/char/ipmi/ipmi_kcs_sm.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/ipmi/ipmi_kcs_sm.c 2003-02-21 15:41:39.000000000 +0000 @@ -93,6 +93,7 @@ #define MAX_ERROR_RETRIES 10 #define IPMI_ERR_MSG_TRUNCATED 0xc6 +#define IPMI_ERR_UNSPECIFIED 0xff struct kcs_data { @@ -219,6 +220,7 @@ kcs->ibf_timeout -= time; if (kcs->ibf_timeout < 0) { start_error_recovery(kcs, "IBF not ready in time"); + kcs->ibf_timeout = IBF_RETRY_TIMEOUT; return 1; } return 0; @@ -291,6 +293,12 @@ memcpy(data, kcs->read_data, kcs->read_pos); + if ((length >= 3) && (kcs->read_pos < 3)) { + /* Guarantee that we return at least 3 bytes, with an + error in the third byte if it is too short. */ + data[2] = IPMI_ERR_UNSPECIFIED; + kcs->read_pos = 3; + } if (kcs->truncated) { /* Report a truncated error. We might overwrite another error, but that's too bad, the user needs @@ -324,6 +332,9 @@ switch (kcs->state) { case KCS_IDLE: + /* If there's and interrupt source, turn it off. */ + clear_obf(kcs, status); + if (GET_STATUS_ATN(status)) return KCS_ATTN; else @@ -391,13 +402,20 @@ "Not in read or idle in read state"); break; } - if (! check_obf(kcs, status, time)) - return KCS_CALL_WITH_DELAY; if (state == KCS_READ_STATE) { + if (! check_obf(kcs, status, time)) + return KCS_CALL_WITH_DELAY; read_next_byte(kcs); } else { - read_data(kcs); + /* We don't implement this exactly like the state + machine in the spec. Some broken hardware + does not write the final dummy byte to the + read register. Thus obf will never go high + here. We just go straight to idle, and we + handle clearing out obf in idle state if it + happens to come in. */ + clear_obf(kcs, status); kcs->orig_write_count = 0; kcs->state = KCS_IDLE; return KCS_TRANSACTION_COMPLETE; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/ipmi/ipmi_msghandler.c linux.21pre4-ac6/drivers/char/ipmi/ipmi_msghandler.c --- linux.21pre4/drivers/char/ipmi/ipmi_msghandler.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/ipmi/ipmi_msghandler.c 2003-02-21 15:41:43.000000000 +0000 @@ -52,6 +52,10 @@ #define MAX_EVENTS_IN_QUEUE 25 +/* Don't let a message sit in a queue forever, always time it with at lest + the max message timer. */ +#define MAX_MSG_TIMEOUT 60000 + struct ipmi_user { struct list_head link; @@ -76,6 +80,38 @@ unsigned char cmd; }; +struct seq_table +{ + int inuse : 1; + + unsigned long timeout; + unsigned long orig_timeout; + unsigned int retries_left; + + /* To verify on an incoming send message response that this is + the message that the response is for, we keep a sequence id + and increment it every time we send a message. */ + long seqid; + + /* This is held so we can properly respond to the message on a + timeout, and it is used to hold the temporary data for + retransmission, too. */ + struct ipmi_recv_msg *recv_msg; +}; + +/* Store the information in a msgid (long) to allow us to find a + sequence table entry from the msgid. */ +#define STORE_SEQ_IN_MSGID(seq, seqid) (((seq&0xff)<<26) | (seqid&0x3ffffff)) + +#define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \ + do { \ + seq = ((msgid >> 26) & 0x3f); \ + seqid = (msgid & 0x3fffff); \ + } while(0) + +#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3fffff) + + #define IPMI_IPMB_NUM_SEQ 64 struct ipmi_smi { @@ -99,12 +135,8 @@ sequence numbers for IPMB messages that go out of the interface to match them up with their responses. A routine is called periodically to time the items in this list. */ - spinlock_t seq_lock; - struct { - unsigned long timeout; - int inuse; - struct ipmi_recv_msg *recv_msg; - } seq_table[IPMI_IPMB_NUM_SEQ]; + spinlock_t seq_lock; + struct seq_table seq_table[IPMI_IPMB_NUM_SEQ]; int curr_seq; /* Messages that were delayed for some reason (out of memory, @@ -300,19 +332,20 @@ } /* Find the next sequence number not being used and add the given - message with the given timeout to the sequence table. */ + message with the given timeout to the sequence table. This must be + called with the interface's seq_lock held. */ static int intf_next_seq(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, unsigned long timeout, - unsigned char *seq) + int retries, + unsigned char *seq, + long *seqid) { - int rv = 0; - unsigned long flags; - unsigned int i; + int rv = 0; + unsigned int i; - spin_lock_irqsave(&(intf->seq_lock), flags); for (i=intf->curr_seq; - i!=(intf->curr_seq-1); + (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; i=(i+1)%IPMI_IPMB_NUM_SEQ) { if (! intf->seq_table[i].inuse) @@ -321,16 +354,21 @@ if (! intf->seq_table[i].inuse) { intf->seq_table[i].recv_msg = recv_msg; - intf->seq_table[i].timeout = timeout; + + /* Start with the maximum timeout, when the send response + comes in we will start the real timer. */ + intf->seq_table[i].timeout = MAX_MSG_TIMEOUT; + intf->seq_table[i].orig_timeout = timeout; + intf->seq_table[i].retries_left = retries; intf->seq_table[i].inuse = 1; + intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid); *seq = i; + *seqid = intf->seq_table[i].seqid; intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ; } else { rv = -EAGAIN; } - spin_unlock_irqrestore(&(intf->seq_lock), flags); - return rv; } @@ -373,6 +411,33 @@ } +/* Start the timer for a specific sequence table entry. */ +static int intf_start_seq_timer(ipmi_smi_t intf, + long msgid) +{ + int rv = -ENODEV; + unsigned long flags; + unsigned char seq; + unsigned long seqid; + + + GET_SEQ_FROM_MSGID(msgid, seq, seqid); + + spin_lock_irqsave(&(intf->seq_lock), flags); + /* We do this verification because the user can be deleted + while a message is outstanding. */ + if ((intf->seq_table[seq].inuse) + && (intf->seq_table[seq].seqid == seqid)) + { + struct seq_table *ent = &(intf->seq_table[seq]); + ent->timeout = ent->orig_timeout; + } + spin_unlock_irqrestore(&(intf->seq_lock), flags); + + return rv; +} + + int ipmi_create_user(unsigned int if_num, struct ipmi_user_hndl *handler, void *handler_data, @@ -649,6 +714,48 @@ return -csum; } +static inline void format_ipmb_msg(struct ipmi_smi_msg *smi_msg, + struct ipmi_msg *msg, + struct ipmi_ipmb_addr *ipmb_addr, + long msgid, + unsigned char ipmb_seq, + int broadcast, + unsigned char source_address, + unsigned char source_lun) +{ + int i = broadcast; + + /* Format the IPMB header data. */ + smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); + smi_msg->data[1] = IPMI_SEND_MSG_CMD; + smi_msg->data[2] = ipmb_addr->channel; + if (broadcast) + smi_msg->data[3] = 0; + smi_msg->data[i+3] = ipmb_addr->slave_addr; + smi_msg->data[i+4] = (msg->netfn << 2) | (ipmb_addr->lun & 0x3); + smi_msg->data[i+5] = ipmb_checksum(&(smi_msg->data[i+3]), 2); + smi_msg->data[i+6] = source_address; + smi_msg->data[i+7] = (ipmb_seq << 2) | source_lun; + smi_msg->data[i+8] = msg->cmd; + + /* Now tack on the data to the message. */ + if (msg->data_len > 0) + memcpy(&(smi_msg->data[i+9]), msg->data, + msg->data_len); + smi_msg->data_size = msg->data_len + 9; + + /* Now calculate the checksum and tack it on. */ + smi_msg->data[i+smi_msg->data_size] + = ipmb_checksum(&(smi_msg->data[i+6]), + smi_msg->data_size-6); + + /* Add on the checksum size and the offset from the + broadcast. */ + smi_msg->data_size += 1 + i; + + smi_msg->msgid = msgid; +} + /* Separate from ipmi_request so that the user does not have to be supplied in certain circumstances (mainly at panic time). If messages are supplied, they will be freed, even if an error @@ -667,6 +774,7 @@ int rv = 0; struct ipmi_smi_msg *smi_msg; struct ipmi_recv_msg *recv_msg; + unsigned long flags; if (supplied_recv) { @@ -693,13 +801,22 @@ goto out_err; } + recv_msg->user = user; + recv_msg->msgid = msgid; + /* Store the message to send in the receive message so timeout + responses can get the proper response data. */ + recv_msg->msg = *msg; + if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { struct ipmi_system_interface_addr *smi_addr; + smi_addr = (struct ipmi_system_interface_addr *) addr; if (smi_addr->lun > 3) return -EINVAL; + memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr)); + if ((msg->netfn == IPMI_NETFN_APP_REQUEST) && ((msg->cmd == IPMI_SEND_MSG_CMD) || (msg->cmd == IPMI_GET_MSG_CMD) @@ -716,11 +833,6 @@ goto out_err; } - recv_msg->user = user; - recv_msg->addr = *addr; - recv_msg->msgid = msgid; - recv_msg->msg = *msg; - smi_msg->data[0] = (msg->netfn << 2) | (smi_addr->lun & 0x3); smi_msg->data[1] = msg->cmd; smi_msg->msgid = msgid; @@ -733,7 +845,9 @@ { struct ipmi_ipmb_addr *ipmb_addr; unsigned char ipmb_seq; - int i; + long seqid; + int broadcast; + int retries; if (addr == NULL) { rv = -EINVAL; @@ -744,75 +858,80 @@ /* Broadcasts add a zero at the beginning of the message, but otherwise is the same as an IPMB address. */ - smi_msg->data[3] = 0; addr->addr_type = IPMI_IPMB_ADDR_TYPE; - i = 1; + broadcast = 1; + retries = 0; /* Don't retry broadcasts. */ } else { - i = 0; + broadcast = 0; + retries = 4; } /* 9 for the header and 1 for the checksum, plus possibly one for the broadcast. */ - if ((msg->data_len + 10 + i) > IPMI_MAX_MSG_LENGTH) { + if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) { rv = -EMSGSIZE; goto out_err; } ipmb_addr = (struct ipmi_ipmb_addr *) addr; - if (ipmb_addr->lun > 3) - return -EINVAL; - - memcpy(&(recv_msg->addr), ipmb_addr, sizeof(*ipmb_addr)); + if (ipmb_addr->lun > 3) { + rv = -EINVAL; + goto out_err; + } - recv_msg->user = user; - recv_msg->msgid = msgid; - recv_msg->msg = *msg; + memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr)); if (recv_msg->msg.netfn & 0x1) { - /* It's a response, so use the user's sequence. */ - ipmb_seq = msgid; + /* It's a response, so use the user's sequence + from msgid. */ + format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid, + msgid, broadcast, + source_address, source_lun); } else { /* It's a command, so get a sequence for it. */ - /* Create a sequence number with a 5 second timeout. */ + + spin_lock_irqsave(&(intf->seq_lock), flags); + + /* Create a sequence number with a 1 second + timeout and 4 retries. */ /* FIXME - magic number for the timeout. */ rv = intf_next_seq(intf, recv_msg, - 5000, - &ipmb_seq); + 1000, + retries, + &ipmb_seq, + &seqid); if (rv) { /* We have used up all the sequence numbers, probably, so abort. */ - ipmi_free_recv_msg(recv_msg); - smi_msg->done(smi_msg); + spin_unlock_irqrestore(&(intf->seq_lock), + flags); goto out_err; } - } - - /* Format the IPMB header data. */ - smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); - smi_msg->data[1] = IPMI_SEND_MSG_CMD; - smi_msg->data[2] = addr->channel; - smi_msg->data[i+3] = ipmb_addr->slave_addr; - smi_msg->data[i+4] = (msg->netfn << 2) | (ipmb_addr->lun & 0x3); - smi_msg->data[i+5] = ipmb_checksum(&(smi_msg->data[i+3]), 2); - smi_msg->data[i+6] = source_address; - smi_msg->data[i+7] = (ipmb_seq << 2) | source_lun; - smi_msg->data[i+8] = msg->cmd; - /* Now tack on the data to the message. */ - if (msg->data_len > 0) - memcpy(&(smi_msg->data[i+9]), msg->data, msg->data_len); - smi_msg->data_size = msg->data_len + 9; + /* Store the sequence number in the message, + so that when the send message response + comes back we can start the timer. */ + format_ipmb_msg(smi_msg, msg, ipmb_addr, + STORE_SEQ_IN_MSGID(ipmb_seq, seqid), + ipmb_seq, broadcast, + source_address, source_lun); + + /* Copy the message into the recv message data, so we + can retransmit it later if necessary. */ + memcpy(recv_msg->msg_data, smi_msg->data, + smi_msg->data_size); + recv_msg->msg.data = recv_msg->msg_data; + recv_msg->msg.data_len = smi_msg->data_size; - /* Now calculate the checksum and tack it on. */ - smi_msg->data[i+smi_msg->data_size] - = ipmb_checksum(&(smi_msg->data[i+6]), smi_msg->data_size-6); - - /* Add on the checksum size and the offset from the - broadcast. */ - smi_msg->data_size += 1 + i; - - smi_msg->msgid = msgid; + /* We don't unlock until here, because we need + to copy the completed message into the + recv_msg before we release the lock. + Otherwise, race conditions may bite us. I + know that's pretty paranoid, but I prefer + to be correct. */ + spin_unlock_irqrestore(&(intf->seq_lock), flags); + } } else { /* Unknown address type. */ rv = -EINVAL; @@ -832,8 +951,8 @@ return 0; out_err: - smi_msg->done(smi_msg); - recv_msg->done(recv_msg); + ipmi_free_smi_msg(smi_msg); + ipmi_free_recv_msg(recv_msg); return rv; } @@ -936,8 +1055,10 @@ new_intf->handlers = handlers; new_intf->send_info = send_info; spin_lock_init(&(new_intf->seq_lock)); - for (j=0; jseq_table[j].inuse = 0; + for (j=0; jseq_table[j].inuse = 0; + new_intf->seq_table[j].seqid = 0; + } new_intf->curr_seq = 0; spin_lock_init(&(new_intf->waiting_msgs_lock)); INIT_LIST_HEAD(&(new_intf->waiting_msgs)); @@ -1426,24 +1547,25 @@ int rv; - if ((msg->data_size >= 2) && (msg->data[1] == IPMI_SEND_MSG_CMD)) { - /* This is the local response to a send, we just - ignore these. */ - msg->done(msg); - return; - } - /* Lock the user lock so the user can't go away while we are working on it. */ read_lock(&(intf->users_lock)); + if ((msg->data_size >= 2) && (msg->data[1] == IPMI_SEND_MSG_CMD)) { + /* This is the local response to a send, start the + timer for these. */ + intf_start_seq_timer(intf, msg->msgid); + ipmi_free_smi_msg(msg); + goto out_unlock; + } + /* To preserve message order, if the list is not empty, we tack this message onto the end of the list. */ spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); if (!list_empty(&(intf->waiting_msgs))) { list_add_tail(&(msg->link), &(intf->waiting_msgs)); spin_unlock(&(intf->waiting_msgs_lock)); - return; + goto out_unlock; } spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); @@ -1455,9 +1577,10 @@ list_add_tail(&(msg->link), &(intf->waiting_msgs)); spin_unlock(&(intf->waiting_msgs_lock)); } else if (rv == 0) { - msg->done(msg); + ipmi_free_smi_msg(msg); } + out_unlock: read_unlock(&(intf->users_lock)); } @@ -1490,6 +1613,39 @@ } static void +send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, + struct ipmi_smi_msg *smi_msg, + unsigned char seq, long seqid) +{ + if (!smi_msg) + smi_msg = ipmi_alloc_smi_msg(); + if (!smi_msg) + /* If we can't allocate the message, then just return, we + get 4 retries, so this should be ok. */ + return; + + memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); + smi_msg->data_size = recv_msg->msg.data_len; + smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); + + /* Send the new message. We send with a zero priority. It + timed out, I doubt time is that critical now, and high + priority messages are really only for messages to the local + MC, which don't get resent. */ + intf->handlers->sender(intf->send_info, smi_msg, 0); + +#if DEBUG_MSGING + { + int m; + printk("Resend: "); + for (m=0; mdata_size; m++) + printk(" %2.2x", smi_msg->data[m]); + printk("\n"); + } +#endif +} + +static void ipmi_timeout_handler(long timeout_period) { ipmi_smi_t intf; @@ -1516,7 +1672,7 @@ smi_msg = list_entry(entry, struct ipmi_smi_msg, link); if (! handle_new_recv_msg(intf, smi_msg)) { list_del(entry); - smi_msg->done(smi_msg); + ipmi_free_smi_msg(smi_msg); } else { /* To preserve message order, quit if we can't handle a message. */ @@ -1530,13 +1686,28 @@ list. */ spin_lock_irqsave(&(intf->seq_lock), flags); for (j=0; jseq_table[j].inuse) { - intf->seq_table[j].timeout -= timeout_period; - if (intf->seq_table[j].timeout <= 0) { - intf->seq_table[j].inuse = 0; - msg = intf->seq_table[j].recv_msg; - list_add_tail(&(msg->link), &timeouts); - } + struct seq_table *ent = &(intf->seq_table[j]); + if (!ent->inuse) + continue; + + ent->timeout -= timeout_period; + if (ent->timeout > 0) + continue; + + if (ent->retries_left == 0) { + /* The message has used all its retries. */ + ent->inuse = 0; + msg = ent->recv_msg; + list_add_tail(&(msg->link), &timeouts); + } else { + /* More retries, send again. */ + + /* Start with the max timer, set to normal + timer after the message is sent. */ + ent->timeout = MAX_MSG_TIMEOUT; + ent->retries_left--; + send_from_recv_msg(intf, ent->recv_msg, NULL, + j, ent->seqid); } } spin_unlock_irqrestore(&(intf->seq_lock), flags); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/ipmi/ipmi_watchdog.c linux.21pre4-ac6/drivers/char/ipmi/ipmi_watchdog.c --- linux.21pre4/drivers/char/ipmi/ipmi_watchdog.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/ipmi/ipmi_watchdog.c 2003-01-09 00:30:24.000000000 +0000 @@ -44,6 +44,8 @@ #include #include #include +#include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #endif @@ -73,6 +75,14 @@ #define WDOG_PRETIMEOUT_NMI 2 #define WDOG_PRETIMEOUT_MSG_INT 3 +/* Operations that can be performed on a pretimout. */ +#define WDOG_PREOP_NONE 0 +#define WDOG_PREOP_PANIC 1 +#define WDOG_PREOP_GIVE_DATA 2 /* Cause data to be available to + read. Doesn't work in NMI + mode. */ + +/* Actions to perform on a full timeout. */ #define WDOG_SET_TIMEOUT_ACT(byte, use) \ byte = ((byte) & 0xf8) | ((use) & 0x7) #define WDOG_GET_TIMEOUT_ACT(byte) ((byte) & 0x7) @@ -133,10 +143,20 @@ static char *preaction = "pre_none"; +static unsigned char preop_val = WDOG_PREOP_NONE; + +static char *preop = "preop_none"; +static spinlock_t ipmi_read_lock = SPIN_LOCK_UNLOCKED; +static char data_to_read = 0; +static DECLARE_WAIT_QUEUE_HEAD(read_q); +static struct fasync_struct *fasync_q = NULL; +static char pretimeout_since_last_heartbeat = 0; + MODULE_PARM(timeout, "i"); MODULE_PARM(pretimeout, "i"); MODULE_PARM(action, "s"); MODULE_PARM(preaction, "s"); +MODULE_PARM(preop, "s"); /* Default state of the timer. */ static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE; @@ -373,6 +393,15 @@ return ipmi_set_timeout(); } + if (pretimeout_since_last_heartbeat) { + /* A pretimeout occurred, make sure we set the timeout. + We don't want to set the action, though, we want to + leave that alone (thus it can't be combined with the + above operation. */ + pretimeout_since_last_heartbeat = 0; + return ipmi_set_timeout(); + } + down(&heartbeat_lock); atomic_set(&heartbeat_tofree, 2); @@ -552,12 +581,53 @@ size_t count, loff_t *ppos) { + int rv = 0; + wait_queue_t wait; + /* Can't seek (pread) on this device */ if (ppos != &file->f_pos) return -ESPIPE; - /* Also can't read it. */ - return -EINVAL; + if (count <= 0) + return 0; + + /* Reading returns if the pretimeout has gone off, and it only does + it once per pretimeout. */ + spin_lock(&ipmi_read_lock); + if (!data_to_read) { + if (file->f_flags & O_NONBLOCK) { + rv = -EAGAIN; + goto out; + } + + init_waitqueue_entry(&wait, current); + add_wait_queue(&read_q, &wait); + while (!data_to_read) { + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock(&ipmi_read_lock); + schedule(); + spin_lock(&ipmi_read_lock); + } + remove_wait_queue(&read_q, &wait); + + if (signal_pending(current)) { + rv = -ERESTARTSYS; + goto out; + } + } + data_to_read = 0; + + out: + spin_unlock(&ipmi_read_lock); + + if (rv == 0) { + if (copy_to_user(buf, &data_to_read, 1)) + rv = -EFAULT; + else + rv = 1; + } + + return rv; } static int ipmi_open(struct inode *ino, struct file *filep) @@ -580,6 +650,29 @@ } } +static unsigned int ipmi_poll(struct file *file, poll_table *wait) +{ + unsigned int mask = 0; + + poll_wait(file, &read_q, wait); + + spin_lock(&ipmi_read_lock); + if (data_to_read) + mask |= (POLLIN | POLLRDNORM); + spin_unlock(&ipmi_read_lock); + + return mask; +} + +static int ipmi_fasync(int fd, struct file *file, int on) +{ + int result; + + result = fasync_helper(fd, file, on, &fasync_q); + + return (result); +} + static int ipmi_close(struct inode *ino, struct file *filep) { if (minor(ino->i_rdev)==WATCHDOG_MINOR) @@ -590,16 +683,21 @@ #endif ipmi_wdog_open = 0; } + + ipmi_fasync (-1, filep, 0); + return 0; } static struct file_operations ipmi_wdog_fops = { .owner = THIS_MODULE, .read = ipmi_read, + .poll = ipmi_poll, .write = ipmi_write, .ioctl = ipmi_ioctl, .open = ipmi_open, .release = ipmi_close, + .fasync = ipmi_fasync, }; static struct miscdevice ipmi_wdog_miscdev = { @@ -611,7 +709,7 @@ static DECLARE_RWSEM(register_sem); static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, - void *handler_data) + void *handler_data) { if (msg->msg.data[0] != 0) { printk(KERN_ERR "IPMI Watchdog response: Error %x on cmd %x\n", @@ -624,7 +722,23 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data) { - panic("Watchdog pre-timeout"); + if (preaction_val != WDOG_PRETIMEOUT_NONE) { + if (preop_val == WDOG_PREOP_PANIC) + panic("Watchdog pre-timeout"); + else if (preop_val == WDOG_PREOP_GIVE_DATA) { + spin_lock(&ipmi_read_lock); + data_to_read = 1; + wake_up_interruptible(&read_q); + kill_fasync(&fasync_q, SIGIO, POLL_IN); + + /* On some machines, the heartbeat will give + an error and not work unless we re-enable + the timer. So do so. */ + pretimeout_since_last_heartbeat = 1; + + spin_unlock(&ipmi_read_lock); + } + } } static struct ipmi_user_hndl ipmi_hndlrs = @@ -676,7 +790,7 @@ { /* If no one else handled the NMI, we assume it was the IPMI watchdog. */ - if (!handled) + if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) panic("IPMI watchdog pre-timeout"); return NOTIFY_DONE; } @@ -807,8 +921,27 @@ " none\n", preaction); } + if (strcmp(preop, "preop_none") == 0) { + preop_val = WDOG_PREOP_NONE; + } else if (strcmp(preop, "preop_panic") == 0) { + preop_val = WDOG_PREOP_PANIC; + } else if (strcmp(preop, "preop_give_data") == 0) { + preop_val = WDOG_PREOP_GIVE_DATA; + } else { + action_val = WDOG_PREOP_NONE; + printk("ipmi_watchdog: Unknown preop '%s', defaulting to" + " none\n", preop); + } + #ifdef HAVE_NMI_HANDLER if (preaction_val == WDOG_PRETIMEOUT_NMI) { + if (preop_val == WDOG_PREOP_GIVE_DATA) { + printk(KERN_WARNING + "ipmi_watchdog: Pretimeout op is to give data" + " but NMI pretimeout is enabled, setting" + " pretimeout op to none\n"); + preop_val = WDOG_PREOP_NONE; + } #ifdef CONFIG_X86_LOCAL_APIC if (nmi_watchdog == NMI_IO_APIC) { printk(KERN_WARNING @@ -864,15 +997,15 @@ release_nmi(&ipmi_nmi_handler); #endif + notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); + unregister_reboot_notifier(&wdog_reboot_notifier); + if (! watchdog_user) goto out; /* Make sure no one can call us any more. */ misc_deregister(&ipmi_wdog_miscdev); - notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); - unregister_reboot_notifier(&wdog_reboot_notifier); - /* Disable the timer. */ ipmi_watchdog_state = WDOG_TIMEOUT_NONE; ipmi_set_timeout(); @@ -955,6 +1088,15 @@ } else if (strcmp(option, "start_now") == 0) { start_now = 1; + } + else if (strcmp(option, "preop_none") == 0) { + preop = "preop_none"; + } + else if (strcmp(option, "preop_panic") == 0) { + preop = "preop_panic"; + } + else if (strcmp(option, "preop_none") == 0) { + preop = "preop_give_data"; } else { printk("Unknown IPMI watchdog option: '%s'\n", option); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/keyboard.c linux.21pre4-ac6/drivers/char/keyboard.c --- linux.21pre4/drivers/char/keyboard.c 2003-01-29 16:26:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/keyboard.c 2003-01-10 16:23:45.000000000 +0000 @@ -64,6 +64,7 @@ void (*kbd_ledfunc)(unsigned int led); EXPORT_SYMBOL(handle_scancode); EXPORT_SYMBOL(kbd_ledfunc); +EXPORT_SYMBOL(kbd_refresh_leds); extern void ctrl_alt_del(void); @@ -94,6 +95,7 @@ static struct tty_struct **ttytab; static struct kbd_struct * kbd = kbd_table; static struct tty_struct * tty; +static unsigned char prev_scancode; void compute_shiftstate(void); @@ -213,7 +215,17 @@ } kbd = kbd_table + fg_console; if ((raw_mode = (kbd->kbdmode == VC_RAW))) { - put_queue(scancode | up_flag); + /* + * The following is a workaround for hardware + * which sometimes send the key release event twice + */ + unsigned char next_scancode = scancode|up_flag; + if (up_flag && next_scancode==prev_scancode) { + /* unexpected 2nd release event */ + } else { + prev_scancode=next_scancode; + put_queue(next_scancode); + } /* we do not return yet, because we want to maintain the key_down array, so that we have the correct values when finishing RAW mode or when changing VT's */ @@ -899,9 +911,9 @@ * Aside from timing (which isn't really that important for * keyboard interrupts as they happen often), using the software * interrupt routines for this thing allows us to easily mask - * this when we don't want any of the above to happen. Not yet - * used, but this allows for easy and efficient race-condition - * prevention later on. + * this when we don't want any of the above to happen. + * This allows for easy and efficient race-condition prevention + * for kbd_ledfunc => input_event(dev, EV_LED, ...) => ... */ static void kbd_bh(unsigned long dummy) { @@ -917,6 +929,18 @@ EXPORT_SYMBOL(keyboard_tasklet); DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); +/* + * This allows a newly plugged keyboard to pick the LED state. + * We do it in this seemindly backwards fashion to ensure proper locking. + * Built-in keyboard does refresh on its own. + */ +void kbd_refresh_leds(void) +{ + tasklet_disable(&keyboard_tasklet); + if (ledstate != 0xff && kbd_ledfunc != NULL) kbd_ledfunc(ledstate); + tasklet_enable(&keyboard_tasklet); +} + typedef void (pm_kbd_func) (void); pm_callback pm_kbd_request_override = NULL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/Makefile linux.21pre4-ac6/drivers/char/Makefile --- linux.21pre4/drivers/char/Makefile 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/Makefile 2003-01-28 16:35:25.000000000 +0000 @@ -24,7 +24,7 @@ export-objs := busmouse.o console.o keyboard.o sysrq.o \ misc.o pty.o random.o selection.o serial.o \ sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ - au1000_gpio.o hp_psaux.o nvram.o + au1000_gpio.o hp_psaux.o nvram.o scx200.o mod-subdirs := joystick ftape drm drm-4.0 pcmcia @@ -199,6 +199,12 @@ obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_SPECIALIX) += specialix.o + +subdir-$(CONFIG_ATI_CD1865) += cd1865 +ifeq ($(CONFIG_ATI_CD1865),y) + obj-y += cd1865/SILX.o +endif + obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o obj-$(CONFIG_SX) += sx.o generic_serial.o @@ -237,6 +243,7 @@ obj-$(CONFIG_PC110_PAD) += pc110pad.o obj-$(CONFIG_MK712_MOUSE) += mk712.o obj-$(CONFIG_RTC) += rtc.o +obj-$(CONFIG_GEN_RTC) += genrtc.o obj-$(CONFIG_EFI_RTC) += efirtc.o ifeq ($(CONFIG_PPC),) obj-$(CONFIG_NVRAM) += nvram.o @@ -293,7 +300,7 @@ obj-$(CONFIG_SH_WDT) += shwdt.o obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o -#obj-$(CONFIG_ALIM1535_WDT) += alim1535d_wdt.o +obj-$(CONFIG_ALIM1535_WDT) += alim1535d_wdt.o obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/mem.c linux.21pre4-ac6/drivers/char/mem.c --- linux.21pre4/drivers/char/mem.c 2003-01-29 16:26:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/mem.c 2003-01-28 16:18:51.000000000 +0000 @@ -520,7 +520,91 @@ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } -#define mmap_kmem mmap_mem +struct page *kmem_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write) +{ + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long kaddr; + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + struct page *page = NULL; + + /* address is user VA; convert to kernel VA of desired page */ + kaddr = (address - vma->vm_start) + offset; + kaddr = VMALLOC_VMADDR(kaddr); + + spin_lock(&init_mm.page_table_lock); + + /* Lookup page structure for kernel VA */ + pgd = pgd_offset(&init_mm, kaddr); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + goto out; + pmd = pmd_offset(pgd, kaddr); + if (pmd_none(*pmd) || pmd_bad(*pmd)) + goto out; + ptep = pte_offset(pmd, kaddr); + if (!ptep) + goto out; + pte = *ptep; + if (!pte_present(pte)) + goto out; + if (write && !pte_write(pte)) + goto out; + page = pte_page(pte); + if (!VALID_PAGE(page)) { + page = NULL; + goto out; + } + + /* Increment reference count on page */ + get_page(page); + +out: + spin_unlock(&init_mm.page_table_lock); + + return page; +} + +struct vm_operations_struct kmem_vm_ops = { + nopage: kmem_vm_nopage, +}; + +static int mmap_kmem(struct file * file, struct vm_area_struct * vma) +{ + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + + /* + * If the user is not attempting to mmap a high memory address then + * the standard mmap_mem mechanism will work. High memory addresses + * need special handling, as remap_page_range expects a physically- + * contiguous range of kernel addresses (such as obtained in kmalloc). + */ + if ((offset + size) < (unsigned long) high_memory) + return mmap_mem(file, vma); + + /* + * Accessing memory above the top the kernel knows about or + * through a file pointer that was marked O_SYNC will be + * done non-cached. + */ + if (noncached_address(offset) || (file->f_flags & O_SYNC)) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* Don't do anything here; "nopage" will fill the holes */ + vma->vm_ops = &kmem_vm_ops; + + /* Don't try to swap out physical pages.. */ + vma->vm_flags |= VM_RESERVED; + + /* + * Don't dump addresses that are not real memory to a core file. + */ + vma->vm_flags |= VM_IO; + + return 0; +} + #define zero_lseek null_lseek #define full_lseek null_lseek #define write_zero write_null diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/mwave/mwavedd.c linux.21pre4-ac6/drivers/char/mwave/mwavedd.c --- linux.21pre4/drivers/char/mwave/mwavedd.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/mwave/mwavedd.c 2003-02-19 16:18:01.000000000 +0000 @@ -279,7 +279,6 @@ pDrvData->IPCs[ipcnum].bIsHere = FALSE; pDrvData->IPCs[ipcnum].bIsEnabled = TRUE; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - current->nice = -20; /* boost to provide priority timing */ #else current->priority = 0x28; /* boost to provide priority timing */ #endif @@ -500,7 +499,7 @@ { int i; int retval = 0; - unsigned int resultMiscRegister; + int resultMiscRegister; pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/n_hdlc.c linux.21pre4-ac6/drivers/char/n_hdlc.c --- linux.21pre4/drivers/char/n_hdlc.c 2003-01-29 16:26:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/n_hdlc.c 2003-01-06 15:38:20.000000000 +0000 @@ -9,7 +9,7 @@ * Al Longyear , Paul Mackerras * * Original release 01/11/99 - * $Id: n_hdlc.c,v 3.3 2001/11/08 16:16:03 paulkf Exp $ + * $Id: n_hdlc.c,v 3.6 2002/12/19 18:58:56 paulkf Exp $ * * This code is released under the GNU General Public License (GPL) * @@ -78,7 +78,7 @@ */ #define HDLC_MAGIC 0x239e -#define HDLC_VERSION "$Revision: 3.3 $" +#define HDLC_VERSION "$Revision: 3.6 $" #include #include @@ -172,9 +172,9 @@ /* * HDLC buffer list manipulation functions */ -void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); -void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); -N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); +static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); +static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); +static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); /* Local functions */ @@ -186,10 +186,10 @@ /* debug level can be set by insmod for debugging purposes */ #define DEBUG_LEVEL_INFO 1 -int debuglevel=0; +static int debuglevel=0; /* max frame size for memory allocations */ -ssize_t maxframe=4096; +static ssize_t maxframe=4096; /* TTY callbacks */ @@ -265,7 +265,8 @@ } else break; } - + if (n_hdlc->tbuf) + kfree(n_hdlc->tbuf); kfree(n_hdlc); } /* end of n_hdlc_release() */ @@ -905,7 +906,7 @@ * Arguments: list pointer to buffer list * Return Value: None */ -void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) +static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) { memset(list,0,sizeof(N_HDLC_BUF_LIST)); spin_lock_init(&list->spinlock); @@ -922,7 +923,7 @@ * * Return Value: None */ -void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) +static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) { unsigned long flags; spin_lock_irqsave(&list->spinlock,flags); @@ -952,7 +953,7 @@ * * pointer to HDLC buffer if available, otherwise NULL */ -N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) +static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) { unsigned long flags; N_HDLC_BUF *buf; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/nwflash.c linux.21pre4-ac6/drivers/char/nwflash.c --- linux.21pre4/drivers/char/nwflash.c 2003-01-29 16:26:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/nwflash.c 2003-01-06 17:28:32.000000000 +0000 @@ -154,12 +154,11 @@ if (down_interruptible(&nwflash_sem)) return -ERESTARTSYS; - ret = copy_to_user(buf, (void *)(FLASH_BASE + p), count); - if (ret == 0) { - ret = count; - *ppos += count; - } + ret = count - copy_to_user(buf, (void *)(FLASH_BASE + p), count); + *ppos += ret; up(&nwflash_sem); + if (ret == 0) + ret = -EFAULT; } return ret; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/pc_keyb.c linux.21pre4-ac6/drivers/char/pc_keyb.c --- linux.21pre4/drivers/char/pc_keyb.c 2003-01-29 16:26:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/pc_keyb.c 2003-01-06 15:42:16.000000000 +0000 @@ -1225,41 +1225,13 @@ #endif /* CONFIG_PSMOUSE */ -static int blink_frequency = HZ/2; +void pckbd_blink (char led) { + led = led ? (0x01 | 0x04) : 0x00; -/* Tell the user who may be running in X and not see the console that we have - panic'ed. This is to distingush panics from "real" lockups. - Could in theory send the panic message as morse, but that is left as an - exercise for the reader. */ -void panic_blink(void) -{ - static unsigned long last_jiffie; - static char led; - /* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is - different. */ - if (!blink_frequency) - return; - if (jiffies - last_jiffie > blink_frequency) { - led ^= 0x01 | 0x04; while (kbd_read_status() & KBD_STAT_IBF) mdelay(1); kbd_write_output(KBD_CMD_SET_LEDS); mdelay(1); while (kbd_read_status() & KBD_STAT_IBF) mdelay(1); mdelay(1); kbd_write_output(led); - last_jiffie = jiffies; - } -} - -static int __init panicblink_setup(char *str) -{ - int par; - if (get_option(&str,&par)) - blink_frequency = par*(1000/HZ); - return 1; } - -/* panicblink=0 disables the blinking as it caused problems with some console - switches. otherwise argument is ms of a blink period. */ -__setup("panicblink=", panicblink_setup); - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/raw.c linux.21pre4-ac6/drivers/char/raw.c --- linux.21pre4/drivers/char/raw.c 2003-01-29 16:26:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/raw.c 2003-01-28 15:47:22.000000000 +0000 @@ -170,7 +170,7 @@ { int minor = minor(inode->i_rdev), err; struct block_device *b; - if (minor < 1 && minor > 255) + if (minor < 1 || minor > 255) return -ENODEV; b = raw_devices[minor].binding; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/serial.c linux.21pre4-ac6/drivers/char/serial.c --- linux.21pre4/drivers/char/serial.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/serial.c 2003-01-06 23:14:19.000000000 +0000 @@ -62,6 +62,10 @@ * Robert Schwebel , * Juergen Beisert , * Theodore Ts'o + * 4/02: added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUTS + * to waiting processes + * Sapan Bhatia + * */ static char *serial_version = "5.05c"; @@ -203,6 +207,7 @@ #include #include #include +#include #if (LINUX_VERSION_CODE >= 131343) #include #endif @@ -1218,7 +1223,7 @@ if (!page) return -ENOMEM; - save_flags(flags); cli(); + spin_lock_irqsave( &info->irq_spinlock, flags); if (info->flags & ASYNC_INITIALIZED) { free_page(page); @@ -1456,11 +1461,11 @@ change_speed(info, 0); info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); + spin_unlock_irqrestore( &info->irq_spinlock, flags); return 0; errout: - restore_flags(flags); + spin_unlock_irqrestore( &info->irq_spinlock, flags); return retval; } @@ -1484,7 +1489,7 @@ state->irq); #endif - save_flags(flags); cli(); /* Disable interrupts */ + spin_lock_irqsave( &info->irq_spinlock, flags); /* * clear delta_msr_wait queue to avoid mem leaks: we may free the irq @@ -1492,41 +1497,6 @@ */ wake_up_interruptible(&info->delta_msr_wait); - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - figure_IRQ_timeout(state->irq); - - /* - * Free the IRQ, if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, &IRQ_ports[state->irq]); - retval = request_irq(state->irq, rs_interrupt_single, - SA_SHIRQ, "serial", - &IRQ_ports[state->irq]); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, &IRQ_ports[state->irq]); - } - - if (info->xmit.buf) { - unsigned long pg = (unsigned long) info->xmit.buf; - info->xmit.buf = 0; - free_page(pg); - } - info->IER = 0; serial_outp(info, UART_IER, 0x00); /* disable all intrs */ #ifdef CONFIG_SERIAL_MANY_PORTS @@ -1583,7 +1553,43 @@ serial_outp(info, UART_IER, UART_IERX_SLEEP); } info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); + + /* + * First unlink the serial port from the IRQ chain... + */ + if (info->next_port) + info->next_port->prev_port = info->prev_port; + if (info->prev_port) + info->prev_port->next_port = info->next_port; + else + IRQ_ports[state->irq] = info->next_port; + figure_IRQ_timeout(state->irq); + + /* + * Free the IRQ, if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + free_irq(state->irq, &IRQ_ports[state->irq]); + retval = request_irq(state->irq, rs_interrupt_single, + SA_SHIRQ, "serial", + &IRQ_ports[state->irq]); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, &IRQ_ports[state->irq]); + } + + if (info->xmit.buf) { + unsigned long pg = (unsigned long) info->xmit.buf; + info->xmit.buf = 0; + free_page(pg); + } + + spin_unlock_irqrestore( &info->irq_spinlock, flags); } #if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ @@ -3128,6 +3134,7 @@ info->tqueue.routine = do_softint; info->tqueue.data = info; info->state = sstate; + spin_lock_init(&info->irq_spinlock); if (sstate->info) { kfree(info); *ret_info = sstate->info; @@ -3242,6 +3249,7 @@ #ifdef SERIAL_DEBUG_OPEN printk("rs_open ttys%d successful...", info->line); #endif + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); return 0; } @@ -3655,6 +3663,7 @@ info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; + info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED; save_flags(flags); cli(); @@ -3907,7 +3916,14 @@ case 6: /* BAR 4*/ case 7: base_idx=idx-2; /* BAR 5*/ } - + + /* AFAVLAB uses a different mixture of BARs and offsets */ + /* Not that ugly ;) -- HW */ + if (dev->vendor == PCI_VENDOR_ID_AFAVLAB && idx >= 4) { + base_idx = 4; + offset = (idx - 4) * 8; + } + /* Some Titan cards are also a little weird */ if (dev->vendor == PCI_VENDOR_ID_TITAN && (dev->device == PCI_DEVICE_ID_TITAN_400L || @@ -4311,9 +4327,11 @@ pbn_b0_bt_1_115200, pbn_b0_bt_2_115200, + pbn_b0_bt_8_115200, pbn_b0_bt_1_460800, pbn_b0_bt_2_460800, pbn_b0_bt_2_921600, + pbn_b0_bt_4_460800, pbn_b1_1_115200, pbn_b1_2_115200, @@ -4392,9 +4410,11 @@ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */ + { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 8, 115200 }, /* pbn_b0_bt_8_115200 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b0_bt_2_921600 */ + { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 460800 }, /* pbn_b0_bt_4_460800 */ { SPCI_FL_BASE1, 1, 115200 }, /* pbn_b1_1_115200 */ { SPCI_FL_BASE1, 2, 115200 }, /* pbn_b1_2_115200 */ @@ -4859,6 +4879,12 @@ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_4_460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_4_460800 }, { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_1_115200 }, @@ -4871,6 +4897,11 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_bt_2_115200 }, + /* AFAVLAB serial card, from Harald Welte */ + { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_8_115200 }, + /* EKF addition for i960 Boards form EKF with serial port */ { PCI_VENDOR_ID_INTEL, 0x1960, 0xE4BF, PCI_ANY_ID, 0, 0, @@ -4890,6 +4921,7 @@ 0x1048, 0x1500, 0, 0, pbn_b1_1_115200 }, + /* SGI IOC3 board */ { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, 0xFF00, 0, 0, 0, pbn_sgi_ioc3 }, @@ -5542,12 +5574,22 @@ tty_register_devfs(&callout_driver, 0, callout_driver.minor_start + state->line); } +#ifdef CONFIG_SERIAL_GSC + probe_serial_gsc(); +#endif +#ifdef CONFIG_SUPERIO + superio_serial_init(); +#endif #ifdef ENABLE_SERIAL_PCI probe_serial_pci(); #endif #ifdef ENABLE_SERIAL_PNP probe_serial_pnp(); #endif + // FIXME: Clean this one up +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_PARISC) + serial_console_init(); +#endif return 0; } @@ -5657,6 +5699,7 @@ info->io_type = req->io_type; info->iomem_base = req->iomem_base; info->iomem_reg_shift = req->iomem_reg_shift; + info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED; } autoconfig(state); if (state->type == PORT_UNKNOWN) { @@ -5964,6 +6007,7 @@ info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; + info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED; quot = state->baud_base / baud; cval = cflag & (CSIZE | CSTOPB); #if defined(__powerpc__) || defined(__alpha__) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/sonypi.c linux.21pre4-ac6/drivers/char/sonypi.c --- linux.21pre4/drivers/char/sonypi.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/sonypi.c 2003-02-24 00:00:39.000000000 +0000 @@ -1,7 +1,7 @@ /* * Sony Programmable I/O Control Device driver for VAIO * - * Copyright (C) 2001-2002 Stelian Pop + * Copyright (C) 2001-2003 Stelian Pop * * Copyright (C) 2001-2002 Alcôve * @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,7 @@ static int fnkeyinit; /* = 0 */ static int camera; /* = 0 */ static int compat; /* = 0 */ +static int useinput = 1; static unsigned long mask = 0xffffffff; /* Inits the queue */ @@ -335,6 +337,21 @@ return; found: +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + if (useinput) { + struct input_dev *jog_dev = &sonypi_device.jog_dev; + if (event == SONYPI_EVENT_JOGDIAL_PRESSED) + input_report_key(jog_dev, BTN_MIDDLE, 1); + else if (event == SONYPI_EVENT_ANYBUTTON_RELEASED) + input_report_key(jog_dev, BTN_MIDDLE, 0); + else if ((event == SONYPI_EVENT_JOGDIAL_UP) || + (event == SONYPI_EVENT_JOGDIAL_UP_PRESSED)) + input_report_rel(jog_dev, REL_WHEEL, 1); + else if ((event == SONYPI_EVENT_JOGDIAL_DOWN) || + (event == SONYPI_EVENT_JOGDIAL_DOWN_PRESSED)) + input_report_rel(jog_dev, REL_WHEEL, -1); + } +#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */ sonypi_pushq(event); } @@ -579,7 +596,7 @@ -1, "sonypi", &sonypi_misc_fops }; -#if CONFIG_PM +#ifdef CONFIG_PM static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) { static int old_camera_power; @@ -594,14 +611,14 @@ sonypi_type2_dis(); else sonypi_type1_dis(); -#if !defined(CONFIG_ACPI) +#ifndef CONFIG_ACPI /* disable ACPI mode */ if (fnkeyinit) outb(0xf1, 0xb2); #endif break; case PM_RESUME: -#if !defined(CONFIG_ACPI) +#ifndef CONFIG_ACPI /* Enable ACPI mode to get Fn key events */ if (fnkeyinit) outb(0xf0, 0xb2); @@ -692,7 +709,7 @@ goto out3; } -#if !defined(CONFIG_ACPI) +#ifndef CONFIG_ACPI /* Enable ACPI mode to get Fn key events */ if (fnkeyinit) outb(0xf0, 0xb2); @@ -715,14 +732,15 @@ SONYPI_DRIVER_MINORVERSION); printk(KERN_INFO "sonypi: detected %s model, " "verbose = %d, fnkeyinit = %s, camera = %s, " - "compat = %s, mask = 0x%08lx\n", + "compat = %s, mask = 0x%08lx, useinput = %s\n", (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? "type1" : "type2", verbose, fnkeyinit ? "on" : "off", camera ? "on" : "off", compat ? "on" : "off", - mask); + mask, + useinput ? "on" : "off"); printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", sonypi_device.irq, sonypi_device.ioport1, sonypi_device.ioport2); @@ -730,7 +748,26 @@ printk(KERN_INFO "sonypi: device allocated minor is %d\n", sonypi_misc_device.minor); -#if CONFIG_PM +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + if (useinput) { + /* Initialize the Input Drivers: */ + sonypi_device.jog_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + sonypi_device.jog_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); + sonypi_device.jog_dev.relbit[0] = BIT(REL_WHEEL); + sonypi_device.jog_dev.name = (char *) kmalloc( + sizeof(SONYPI_INPUTNAME), GFP_KERNEL); + sprintf(sonypi_device.jog_dev.name, SONYPI_INPUTNAME); + sonypi_device.jog_dev.idbus = BUS_ISA; + sonypi_device.jog_dev.idvendor = PCI_VENDOR_ID_SONY; + + input_register_device(&sonypi_device.jog_dev); + printk(KERN_INFO "%s installed at input event device #%d.\n", + sonypi_device.jog_dev.name, + sonypi_device.jog_dev.number); + } +#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */ + +#ifdef CONFIG_PM sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback); #endif @@ -746,18 +783,26 @@ static void __devexit sonypi_remove(void) { -#if CONFIG_PM +#ifdef CONFIG_PM pm_unregister(sonypi_device.pm); #endif sonypi_call2(0x81, 0); /* make sure we don't get any more events */ + +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + if (useinput) { + input_unregister_device(&sonypi_device.jog_dev); + kfree(sonypi_device.jog_dev.name); + } +#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */ + if (camera) sonypi_camera_off(); if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) sonypi_type2_dis(); else sonypi_type1_dis(); -#if !defined(CONFIG_ACPI) +#ifndef CONFIG_ACPI /* disable ACPI mode */ if (fnkeyinit) outb(0xf1, 0xb2); @@ -787,7 +832,7 @@ #ifndef MODULE static int __init sonypi_setup(char *str) { - int ints[7]; + int ints[8]; str = get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] <= 0) @@ -808,6 +853,9 @@ if (ints[0] == 5) goto out; mask = ints[6]; + if (ints[0] == 6) + goto out; + useinput = ints[7]; out: return 1; } @@ -836,5 +884,7 @@ MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode"); MODULE_PARM(mask, "i"); MODULE_PARM_DESC(mask, "set this to the mask of event you want to enable (see doc)"); +MODULE_PARM(useinput, "i"); +MODULE_PARM_DESC(useinput, "if you have a jogdial, set this if you would like it to use the modern Linux Input Driver system"); EXPORT_SYMBOL(sonypi_camera_command); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/char/sonypi.h linux.21pre4-ac6/drivers/char/sonypi.h --- linux.21pre4/drivers/char/sonypi.h 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/char/sonypi.h 2003-02-24 00:00:39.000000000 +0000 @@ -1,7 +1,7 @@ /* * Sony Programmable I/O Control Device driver for VAIO * - * Copyright (C) 2001-2002 Stelian Pop + * Copyright (C) 2001-2003 Stelian Pop * * Copyright (C) 2001-2002 Alcôve * @@ -37,7 +37,7 @@ #ifdef __KERNEL__ #define SONYPI_DRIVER_MAJORVERSION 1 -#define SONYPI_DRIVER_MINORVERSION 17 +#define SONYPI_DRIVER_MINORVERSION 18 #define SONYPI_DEVICE_MODEL_TYPE1 1 #define SONYPI_DEVICE_MODEL_TYPE2 2 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include "linux/sonypi.h" @@ -334,6 +335,9 @@ unsigned char buf[SONYPI_BUF_SIZE]; }; +/* The name of the Jog Dial for the input device drivers */ +#define SONYPI_INPUTNAME "Sony VAIO Jog Dial" + struct sonypi_device { struct pci_dev *dev; u16 irq; @@ -347,7 +351,10 @@ struct sonypi_queue queue; int open_count; int model; -#if CONFIG_PM +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + struct input_dev jog_dev; +#endif +#ifdef CONFIG_PM struct pm_dev *pm; #endif }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/hotplug/Config.in linux.21pre4-ac6/drivers/hotplug/Config.in --- linux.21pre4/drivers/hotplug/Config.in 2003-01-29 16:27:05.000000000 +0000 +++ linux.21pre4-ac6/drivers/hotplug/Config.in 2003-01-06 17:28:43.000000000 +0000 @@ -6,11 +6,11 @@ dep_tristate 'Support for PCI Hotplug (EXPERIMENTAL)' CONFIG_HOTPLUG_PCI $CONFIG_EXPERIMENTAL $CONFIG_PCI +dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_ACPI $CONFIG_HOTPLUG_PCI dep_tristate ' Compaq PCI Hotplug driver' CONFIG_HOTPLUG_PCI_COMPAQ $CONFIG_HOTPLUG_PCI $CONFIG_X86 dep_mbool ' Save configuration into NVRAM on Compaq servers' CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM $CONFIG_HOTPLUG_PCI_COMPAQ if [ "$CONFIG_X86_IO_APIC" = "y" ]; then dep_tristate ' IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86 fi -dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_ACPI $CONFIG_HOTPLUG_PCI - +dep_tristate ' IBM Thinkpad (20H2999) Docking driver (VERY EXPERIMENTAL) ' CONFIG_HOTPLUG_PCI_H2999 $CONFIG_HOTPLUG_PCI $CONFIG_X86 endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/hotplug/Makefile linux.21pre4-ac6/drivers/hotplug/Makefile --- linux.21pre4/drivers/hotplug/Makefile 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/hotplug/Makefile 2003-01-06 17:28:43.000000000 +0000 @@ -12,6 +12,7 @@ obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o +obj-$(CONFIG_HOTPLUG_PCI_H2999) += tp600.o pci_hotplug-objs := pci_hotplug_core.o \ pci_hotplug_util.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/hotplug/tp600.c linux.21pre4-ac6/drivers/hotplug/tp600.c --- linux.21pre4/drivers/hotplug/tp600.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/hotplug/tp600.c 2003-01-06 17:28:43.000000000 +0000 @@ -0,0 +1,500 @@ +/* + * Drivers for the IBM 20H2999 found in the IBM thinkpad series + * machines. + * + * This driver was done without documentation from IBM + * + * _ + * { } + * | | All reverse engineering done + * | | in accordance with 92/250/EEC + * .-.! !.-. and Copyright (Computer Programs) + * .-! ! ! !.-. Regulations 1992 (S.I. 1992 No. 3233) + * ! ! ! ; + * \ ; + * \ ; + * ! : + * ! | + * | | + * + * + * Various other IBM's tried to obtain docs but failed. For that + * reason we only support warm not hot undocking at the moment. + * + * Known bugs: + * Sometimes we hang with an IRQ storm. I don't know what + * deals with the IRQ disables yet. (Hot dock) + * Sometimes busmastering (and maybe IRQs) don't come back + * (Seems to be a buffering issue for hot dock) + * + * Yet to do: + * ISA is not yet handled (oh god help us) + * Instead of saving/restoring pci devices we should + * re-enumerate that subtree so you can change devices + * (That also deals with stale save problems) + * We need to do a proper warm save/restore interface + * Bridged cards don't yet work + * + * Usage: + * Load module + * Pray + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pci_hotplug.h" +#include "tp600.h" + +static struct h2999_dev *testdev; + +/** + * pci_save_slot - save slot PCI data + * @slot: slot to save + * + * Save the slot data from a PCI device + */ + +static void pci_save_slot(struct h2999_slot *s) +{ + int i, n; + + for(i=0;i<8;i++) + { + struct pci_dev *p = pci_find_slot(s->dev->hotplug_bus, PCI_DEVFN(s->slotid, i)); + s->pci[i] = p; + if(p) + { + for(n = 0; n < 64; n++) + pci_read_config_dword(p, n * 4, &s->save[i][n]); +// printk("Saved %02X:%02X.%X\n", +// s->dev->hotplug_bus, s->slotid, i); + } + } +} + +static void pci_restore_slot(struct h2999_slot *s) +{ + int i,n; + + for(i = 0 ; i < 8; i++) + { + if(s->pci[i]) + { + pci_set_power_state(s->pci[i], 0); + + for(n = 0; n < 54; n++) + if(n!=1) + pci_write_config_dword(s->pci[i], n * 4, s->save[i][n]); + pci_write_config_dword(s->pci[i], 4, s->save[i][1]); +// printk("Restored %02X:%02X.%X\n", +// s->dev->hotplug_bus, s->slotid, i); + } + } +} + +/** + * slot_enable - enable H2999 slot + * @slot: slot to enable + * + * Enable a slot. Its not actually clear what this means with + * a hot dock. We can certainly 'discover' the PCI device in the + * slot when asked. + */ + +static int slot_enable(struct hotplug_slot *slot) +{ + struct h2999_slot *s = slot->private; + int i; + pci_restore_slot(s); + for(i=0; i < 8; i++) + { + if(s->pci[i] && (s->drivermap&(1<pci[i]); + } + return 0; +} + +/** + * slot_disable - disable H2999 slot + * @slot: slot to disable + * + * Disable a slot. Its not actually clear what to do here. We could + * report the device as having been removed when we are told to do + * this. + */ + +static int slot_disable(struct hotplug_slot *slot) +{ + struct h2999_slot *s = slot->private; + struct pci_dev *pdev; + int i; + + for(i = 0; i < 8; i++) + { + pdev = s->pci[i]; + /* Hack for now */ + if (pdev && pdev->driver) { + if (!pdev->driver->remove) + return -EBUSY; + } + } + + s->drivermap = 0; + + for(i = 0; i < 8; i++) + { + pdev = s->pci[i]; + if(pdev) + { + if(pdev->driver) + { + s->drivermap|=(1<driver->remove(pdev); + pdev->driver = NULL; + } + } + } + return 0; +} + +/** + * set_attention_status - set attention callback + * @slot: slot to set + * @value: on/off + * + * Called when the hotplug layer wants to set the attention status of + * the hotplug slot. The H2999 doesn't have an attention control (at + * least not that we know of). So we ignore this. + */ + +static int set_attention_status(struct hotplug_slot *slot, u8 value) +{ + return 0; +} + +/** + * hardware_test - test hardware callback + * @slot: slot to test + * value: test to run + * + * The H2999 does not support any hardware tests that we know of. + */ + +static int hardware_test(struct hotplug_slot *slot, u32 value) +{ + return 0; +} + +/** + * get_power_status - power query callback + * @slot; slot to query + * @value: returned state + * + * Called when the hotplug layer wants to ask us if the slot is + * powered. We work on the basis that all slots are powered when + * the unit is docked. This seems to be correct but I've not actually + * rammed a voltmeter into the slots to see if they are cleverer than + * that. + */ + +static int get_power_status(struct hotplug_slot *slot, u8 *value) +{ + struct h2999_slot *s = slot->private; + + /* Slots are all powered when docked */ + if(s->dev->docked > 0) + *value = 1; + else + *value = 0; + return 0; +} + +/** + * get_adapter_status - card presence query + * @slot: slot to query + * @value: returned state + * + * If we are not docked, we know the "slot" is empty. If we are + * docked its a bit more complicated. + */ + +static int get_adapter_status(struct hotplug_slot *slot, u8 *value) +{ + struct h2999_slot *s = slot->private; + + *value = 0; + + if(s->dev->docked) + *value = 1; + return 0; +} + +static struct hotplug_slot_ops h2999_ops = { + THIS_MODULE, + slot_enable, + slot_disable, + set_attention_status, + hardware_test, + get_power_status, + NULL, + NULL, + get_adapter_status +}; + +/** + * h2999_is_docked - check if docked + * @dev: h2999 device + * + * Check if we are currently docked. The method we use at the moment + * relies on poking around behind the bridge. There is no doubt a + * correct way to do this. Maybe one day IBM will be decide to + * actually provide documentation + */ + +static int h2999_is_docked(struct h2999_dev *dev) +{ + struct pci_dev *pdev = pci_find_slot(dev->hotplug_bus, PCI_DEVFN(0,0)); + u32 status; + + if(pdev == NULL) + return 0; /* Shouldnt happen - must be undocked */ + + if(pci_read_config_dword(pdev, PCI_VENDOR_ID, &status)) + return 0; /* Config read failed - its missing */ + + if(status == 0xFFFFFFFFUL) /* Failed */ + return 0; + + /* Must be docked */ + return 1; +} +/** + * h2999_reconfigure_dock - redock event handler + * @dev: h2999 device + * + * A redocking event has occurred. There may also have been an undock + * before hand. If so then the unconfigure routine is called first. + */ + +static void h2999_reconfigure_dock(struct h2999_dev *dev) +{ + int docked, i; + + docked = h2999_is_docked(dev); + + if(docked ^ dev->docked) + { + printk("h2999: Now %sdocked.\n", + docked?"":"un"); + if(docked) + { + /* We should do the re-enumeration of the bus here + The current save/restore is a test hack */ + for(i=0; i < H2999_SLOTS; i++) + { + if(dev->slots[i].hotplug_slot.private != &dev->slots[i]) + BUG(); + slot_enable(&dev->slots[i].hotplug_slot); + } + } + else + { + for(i=0; i < H2999_SLOTS; i++) + { + if(slot_disable(&dev->slots[i].hotplug_slot)) + printk(KERN_ERR "h2999: someone undocked while devices were in use, how rude!\n"); + } + } + dev->docked = docked; + } + /* Clear bits */ + pci_write_config_byte(dev->pdev, 0x1f, 0xf0); +} + +/* + * h2999_attach - attach an H2999 bridge + * @pdev: PCI device + * @unused: unused + * + * Called when the PCI layer discovers an H2999 docking bridge is + * present in the system. We scan the bridge to obtain its current + * status and register it with the hot plug layer + */ + +static int __devinit h2999_attach(struct pci_dev *pdev, const struct pci_device_id *unused) +{ + /* PCI core found a new H2999 */ + struct h2999_dev *dev; + u8 bus; + int i; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if(dev == NULL) + goto nomem; + + memset(dev, 0, sizeof(*dev)); + + dev->pdev = pdev; + + pci_read_config_byte(pdev, PCI_SECONDARY_BUS, &bus); + dev->hotplug_bus = bus; + + /* Requires hotplug_bus and pdev are set */ + + dev->docked = h2999_is_docked(dev); + + printk(KERN_INFO "Found IBM 20H2999. Status is %sdocked, docking bus is %d.\n", + dev->docked?"":"un", dev->hotplug_bus); + + /* + * Allow for 8 devices. On the TP600 at least we have + * 0-3 as the onboard devices, and 4-7 as the slots. + * To add more fun there is an ISA bridge which we + * don't really handle yet. + */ + + for(i = 0; i < H2999_SLOTS; i++) + { + struct h2999_slot *s = &dev->slots[i]; + int ret; + + s->hotplug_slot.info = &s->hotplug_info; + s->hotplug_slot.private = s; + s->slotid = i; + s->dev = dev; + s->live = 1; + s->hotplug_slot.ops = &h2999_ops; + s->hotplug_slot.name = s->name; + s->hotplug_info.power_status = dev->docked; + /* FIXME - should probe here + In truth the hp_register ought to call thse as needed! */ + s->hotplug_info.adapter_status = 0; + s->pdev = pci_find_slot(dev->hotplug_bus, PCI_DEVFN(i, 0)); + snprintf(s->name, SLOT_NAME_SIZE, "Dock%d.%d", dev->hotplug_bus, i); + pci_save_slot(s); + ret = pci_hp_register(&s->hotplug_slot); + if(ret) + { + printk(KERN_ERR "pci_hp_register failed for slot %d with error %d\n", i, ret); + s->live = 0; + } + } + pci_set_drvdata(pdev, dev); + + testdev = dev; + return 0; +nomem: + printk(KERN_ERR "h2999_attach: out of memory.\n"); + return -ENOMEM; +} + +/** + * h2999_cleanup - free H2999 memory resources + * @dev: h2999 device + * + * Unregister and free up all of our slots + */ + +static int __devinit h2999_cleanup(struct h2999_dev *dev) +{ + struct h2999_slot *s; + int slot; + + for(slot = 0; slot < H2999_SLOTS; slot++) + { + s = &dev->slots[slot]; + if(s->live) + pci_hp_deregister(&s->hotplug_slot); + } + kfree(dev); +} + +/** + * h2999_detach - an H2999 controller vanished + * @dev: device that vanished + * + * Called when the PCI layer sees the bridge unplugged. At the moment + * this doesn't happen and since its currently unclear what to do + * in the hot plug layer if it does this may be a good thing 8) + */ + +static void __devinit h2999_detach(struct pci_dev *pdev) +{ + struct h2999_dev *dev = pci_get_drvdata(pdev); + h2999_cleanup(dev); +} + + +static struct pci_device_id h2999_id_tbl[] __devinitdata = { + { PCI_VENDOR_ID_IBM, 0x0095, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, h2999_id_tbl); + +static struct pci_driver h2999_driver = { + name: "h2999", + id_table: h2999_id_tbl, + probe: h2999_attach, + remove: __devexit_p(h2999_detach) + /* FIXME - PM functions */ +}; + +/* + * Test harness + */ + +static struct completion thread_done; + +static int h2999_thread(void *unused) +{ + lock_kernel(); + while(testdev != NULL) + { + set_current_state(TASK_INTERRUPTIBLE); + if(signal_pending(current)) + break; + schedule_timeout(HZ); + h2999_reconfigure_dock(testdev); + } + unlock_kernel(); + complete_and_exit(&thread_done, 0); +} + +static int __init h2999_init_module(void) +{ + int rc; + printk(KERN_INFO "IBM 20H2999 PCI docking bridge driver v0.01\n"); + + init_completion(&thread_done); + + rc = pci_module_init(&h2999_driver); + if (rc == 0) + { + if( kernel_thread(h2999_thread, NULL, CLONE_SIGHAND) >= 0) + return 0; + } + complete(&thread_done); + return rc; +} + +static void __exit h2999_cleanup_module(void) +{ + pci_unregister_driver(&h2999_driver); + wait_for_completion(&thread_done); +} + +module_init(h2999_init_module); +module_exit(h2999_cleanup_module); + +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("IBM 20H2999 Docking Bridge Driver"); +MODULE_LICENSE("GPL"); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/hotplug/tp600.h linux.21pre4-ac6/drivers/hotplug/tp600.h --- linux.21pre4/drivers/hotplug/tp600.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/hotplug/tp600.h 2003-01-06 17:28:43.000000000 +0000 @@ -0,0 +1,29 @@ +#define SLOT_NAME_SIZE 12 + +struct h2999_slot +{ + int slotid; + + struct hotplug_slot hotplug_slot; + struct hotplug_slot_info hotplug_info; + char name[SLOT_NAME_SIZE]; + + struct h2999_dev *dev; + struct pci_dev *pdev; + int live; + + struct pci_dev *pci[8]; + u32 save[8][64]; + u8 drivermap; +}; + +#define H2999_SLOTS 8 + +struct h2999_dev +{ + int docked; + int hotplug_bus; + struct pci_dev *pdev; + + struct h2999_slot slots[H2999_SLOTS]; +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/arm/icside.c linux.21pre4-ac6/drivers/ide/arm/icside.c --- linux.21pre4/drivers/ide/arm/icside.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/arm/icside.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/icside.c + * linux/drivers/ide/arm/icside.c * * Copyright (c) 1996,1997 Russell King. * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/arm/rapide.c linux.21pre4-ac6/drivers/ide/arm/rapide.c --- linux.21pre4/drivers/ide/arm/rapide.c 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/arm/rapide.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/rapide.c + * linux/drivers/ide/arm/rapide.c * * Copyright (c) 1996-1998 Russell King. * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/Config.in linux.21pre4-ac6/drivers/ide/Config.in --- linux.21pre4/drivers/ide/Config.in 2003-01-29 17:07:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/Config.in 2003-02-05 17:39:46.000000000 +0000 @@ -56,12 +56,11 @@ dep_tristate ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP - dep_tristate ' HPT366/368/370 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' HPT36X/37X chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI fi - dep_tristate ' nVidia NFORCE support' CONFIG_BLK_DEV_NFORCE $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' NS87415 chipset support' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL dep_tristate ' PROMISE PDC202{46|62|65|67} support' CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide.c linux.21pre4-ac6/drivers/ide/ide.c --- linux.21pre4/drivers/ide/ide.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide.c 2003-02-11 16:03:33.000000000 +0000 @@ -863,6 +863,7 @@ hwif->iops = old_hwif.iops; #else hwif->OUTB = old_hwif.OUTB; + hwif->OUTBSYNC = old_hwif.OUTBSYNC; hwif->OUTW = old_hwif.OUTW; hwif->OUTL = old_hwif.OUTL; hwif->OUTSW = old_hwif.OUTSW; @@ -1021,10 +1022,45 @@ EXPORT_SYMBOL(ide_register); -void ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) + +/* + * Locks for IDE setting functionality + */ + +DECLARE_MUTEX(ide_setting_sem); +EXPORT_SYMBOL(ide_setting_sem); + +/** + * ide_add_setting - add an ide setting option + * @drive: drive to use + * @name: setting name + * @rw: true if the function is read write + * @read_ioctl: function to call on read + * @write_ioctl: function to call on write + * @data_type: type of data + * @min: range minimum + * @max: range maximum + * @mul_factor: multiplication scale + * @div_factor: divison scale + * @data: private data field + * @set: setting + * + * Removes the setting named from the device if it is present. + * The function takes the settings_lock to protect against + * parallel changes. This function must not be called from IRQ + * context. Returns 0 on success or -1 on failure. + * + * BUGS: This code is seriously over-engineered. There is also + * magic about how the driver specific features are setup. If + * a driver is attached we assume the driver settings are auto + * remove. + */ + +int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) { ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; + down(&ide_setting_sem); while ((*p) && strcmp((*p)->name, name) < 0) p = &((*p)->next); if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL) @@ -1043,33 +1079,78 @@ setting->div_factor = div_factor; setting->data = data; setting->set = set; + setting->next = *p; if (drive->driver) setting->auto_remove = 1; *p = setting; - return; + up(&ide_setting_sem); + return 0; abort: + up(&ide_setting_sem); if (setting) kfree(setting); + return -1; } EXPORT_SYMBOL(ide_add_setting); -void ide_remove_setting (ide_drive_t *drive, char *name) +/** + * __ide_remove_setting - remove an ide setting option + * @drive: drive to use + * @name: setting name + * + * Removes the setting named from the device if it is present. + * The caller must hold the setting semaphore. + */ + +static void __ide_remove_setting (ide_drive_t *drive, char *name) { - ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting; + ide_settings_t **p, *setting; + + p = (ide_settings_t **) &drive->settings; while ((*p) && strcmp((*p)->name, name)) p = &((*p)->next); if ((setting = (*p)) == NULL) return; + (*p) = setting->next; + kfree(setting->name); kfree(setting); } +/** + * ide_remove_setting - remove an ide setting option + * @drive: drive to use + * @name: setting name + * + * Removes the setting named from the device if it is present. + * The function takes the settings_lock to protect against + * parallel changes. This function must not be called from IRQ + * context. + */ + +void ide_remove_setting (ide_drive_t *drive, char *name) +{ + down(&ide_setting_sem); + __ide_remove_setting(drive, name); + up(&ide_setting_sem); +} + EXPORT_SYMBOL(ide_remove_setting); +/** + * ide_find_setting_by_ioctl - find a drive specific ioctl + * @drive: drive to scan + * @cmd: ioctl command to handle + * + * Scan's the device setting table for a matching entry and returns + * this or NULL if no entry is found. The caller must hold the + * setting semaphore + */ + static ide_settings_t *ide_find_setting_by_ioctl (ide_drive_t *drive, int cmd) { ide_settings_t *setting = drive->settings; @@ -1079,9 +1160,20 @@ break; setting = setting->next; } + return setting; } +/** + * ide_find_setting_by_name - find a drive specific setting + * @drive: drive to scan + * @name: setting name + * + * Scan's the device setting table for a matching entry and returns + * this or NULL if no entry is found. The caller must hold the + * setting semaphore + */ + ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) { ide_settings_t *setting = drive->settings; @@ -1094,20 +1186,44 @@ return setting; } +/** + * auto_remove_settings - remove driver specific settings + * @drive: drive + * + * Automatically remove all the driver specific settings for this + * drive. This function may sleep and must not be called from IRQ + * context. Takes the settings_lock + */ + static void auto_remove_settings (ide_drive_t *drive) { ide_settings_t *setting; + down(&ide_setting_sem); repeat: setting = drive->settings; while (setting) { if (setting->auto_remove) { - ide_remove_setting(drive, setting->name); + __ide_remove_setting(drive, setting->name); goto repeat; } setting = setting->next; } + up(&ide_setting_sem); } +/** + * ide_read_setting - read an IDE setting + * @drive: drive to read from + * @setting: drive setting + * + * Read a drive setting and return the value. The caller + * must hold the ide_setting_sem when making this call. + * + * BUGS: the data return and error are the same return value + * so an error -EINVAL and true return of the same value cannot + * be told apart + */ + int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting) { int val = -EINVAL; @@ -1156,10 +1272,22 @@ EXPORT_SYMBOL(ide_spin_wait_hwgroup); -/* - * FIXME: This should be changed to enqueue a special request - * to the driver to change settings, and then wait on a sema for completion. - * The current scheme of polling is kludgey, though safe enough. +/** + * ide_write_setting - read an IDE setting + * @drive: drive to read from + * @setting: drive setting + * @val: value + * + * Write a drive setting if it is possible. The caller + * must hold the ide_setting_sem when making this call. + * + * BUGS: the data return and error are the same return value + * so an error -EINVAL and true return of the same value cannot + * be told apart + * + * FIXME: This should be changed to enqueue a special request + * to the driver to change settings, and then wait on a sema for completion. + * The current scheme of polling is kludgy, though safe enough. */ int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val) { @@ -1407,16 +1535,22 @@ if ((drive = get_info_ptr(inode->i_rdev)) == NULL) return -ENODEV; + down(&ide_setting_sem); if ((setting = ide_find_setting_by_ioctl(drive, cmd)) != NULL) { if (cmd == setting->read_ioctl) { err = ide_read_setting(drive, setting); + up(&ide_setting_sem); return err >= 0 ? put_user(err, (long *) arg) : err; } else { if ((MINOR(inode->i_rdev) & PARTN_MASK)) - return -EINVAL; - return ide_write_setting(drive, setting, arg); + err = -EINVAL; + else + err = ide_write_setting(drive, setting, arg); + up(&ide_setting_sem); + return err; } } + up(&ide_setting_sem); ide_init_drive_cmd (&rq); switch (cmd) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-cd.c linux.21pre4-ac6/drivers/ide/ide-cd.c --- linux.21pre4/drivers/ide/ide-cd.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-cd.c 2003-01-30 17:23:48.000000000 +0000 @@ -863,11 +863,8 @@ HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { - if (HWGROUP(drive)->handler != NULL) - BUG(); - ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry); /* packet command */ - HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); + ide_execute_command(drive, WIN_PACKETCMD, handler, WAIT_CMD, cdrom_timer_expiry); return ide_started; } else { /* packet command */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-disk.c linux.21pre4-ac6/drivers/ide/ide-disk.c --- linux.21pre4/drivers/ide/ide-disk.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-disk.c 2003-02-04 15:16:44.000000000 +0000 @@ -38,9 +38,11 @@ * Version 1.15 convert all calls to ide_raw_taskfile * since args will return register content. * Version 1.16 added suspend-resume-checkpower + * Version 1.17 do flush on standy, do flush on ATA < ATA6 + * fix wcache setup. */ -#define IDEDISK_VERSION "1.16" +#define IDEDISK_VERSION "1.17" #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -67,7 +69,7 @@ #include #include -/* FIXME: soem day we shouldnt need to look in here! */ +/* FIXME: some day we shouldnt need to look in here! */ #include "legacy/pdc4030.h" @@ -467,12 +469,12 @@ #endif /* CONFIG_BLK_DEV_IDEDMA */ if (HWGROUP(drive)->handler != NULL) BUG(); - ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); command = ((drive->mult_count) ? ((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) : ((lba48) ? WIN_READ_EXT : WIN_READ)); - hwif->OUTB(command, IDE_COMMAND_REG); + + ide_execute_command(drive, command, &read_intr, WAIT_CMD, NULL); return ide_started; } else if (rq_data_dir(rq) == WRITE) { ide_startstop_t startstop; @@ -716,6 +718,7 @@ MOD_INC_USE_COUNT; if (drive->removable && drive->usage == 1) { ide_task_t args; + int cf; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK; args.command_type = ide_cmd_type_parser(&args); @@ -727,12 +730,38 @@ */ if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) drive->doorlocking = 0; + drive->wcache = 0; + /* Cache enabled ? */ + if (drive->id->csfo & 1) + drive->wcache = 1; + /* Cache command set available ? */ + if (drive->id->cfs_enable_1 & (1<<5)) + drive->wcache = 1; + /* ATA6 cache extended commands */ + cf = drive->id->command_set_2 >> 24; + if((cf & 0xC0) == 0x40 && (cf & 0x30) != 0) + drive->wcache = 1; } return 0; } static int do_idedisk_flushcache(ide_drive_t *drive); +static int ide_cacheflush_p(ide_drive_t *drive) +{ + if(drive->wcache) + { + if (do_idedisk_flushcache(drive)) + { + printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", + drive->name); + return -EIO; + } + return 1; + } + return 0; +} + static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive) { if (drive->removable && !drive->usage) { @@ -744,10 +773,7 @@ if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) drive->doorlocking = 0; } - if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) - if (do_idedisk_flushcache(drive)) - printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", - drive->name); + ide_cacheflush_p(drive); MOD_DEC_USE_COUNT; } @@ -1435,7 +1461,7 @@ { if (drive->suspend_reset) return 1; - + ide_cacheflush_p(drive); return call_idedisk_suspend(drive, 0); } @@ -1679,10 +1705,7 @@ static int idedisk_cleanup(ide_drive_t *drive) { - if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) - if (do_idedisk_flushcache(drive)) - printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", - drive->name); + ide_cacheflush_p(drive); return ide_unregister_subdriver(drive); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-dma.c linux.21pre4-ac6/drivers/ide/ide-dma.c --- linux.21pre4/drivers/ide/ide-dma.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-dma.c 2003-02-07 21:58:12.000000000 +0000 @@ -689,11 +689,6 @@ drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - /* paranoia check */ - if (HWGROUP(drive)->handler != NULL) - BUG(); - ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); - /* * FIX ME to use only ACB ide_task_t args Struct */ @@ -710,8 +705,7 @@ } #endif /* issue cmd to drive */ - hwif->OUTB(command, IDE_COMMAND_REG); - + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); return HWIF(drive)->ide_dma_count(drive); } @@ -741,10 +735,6 @@ drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - /* paranoia check */ - if (HWGROUP(drive)->handler != NULL) - BUG(); - ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); /* * FIX ME to use only ACB ide_task_t args Struct */ @@ -761,7 +751,7 @@ } #endif /* issue cmd to drive */ - hwif->OUTB(command, IDE_COMMAND_REG); + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); return HWIF(drive)->ide_dma_count(drive); } @@ -825,7 +815,9 @@ if (!drive->waiting_for_dma) printk(KERN_WARNING "%s: (%s) called while not waiting\n", drive->name, __FUNCTION__); +#if 0 drive->waiting_for_dma++; +#endif return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-floppy.c linux.21pre4-ac6/drivers/ide/ide-floppy.c --- linux.21pre4/drivers/ide/ide-floppy.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-floppy.c 2003-02-04 15:21:39.000000000 +0000 @@ -1123,14 +1123,11 @@ } if (test_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { - if (HWGROUP(drive)->handler != NULL) - BUG(); - ide_set_handler(drive, + /* Issue the packet command */ + ide_execute_command(drive, WIN_PACKETCMD, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); - /* Issue the packet command */ - HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); return ide_started; } else { /* Issue the packet command */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-geometry.c linux.21pre4-ac6/drivers/ide/ide-geometry.c --- linux.21pre4/drivers/ide/ide-geometry.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-geometry.c 2003-02-11 17:38:26.000000000 +0000 @@ -211,7 +211,7 @@ drive->part[0].nr_sects = current_capacity(drive); if (ret) - printk(KERN_INFO "%s%s [%d/%d/%d]", msg, msg1, + printk("%s%s [%d/%d/%d]", msg, msg1, drive->bios_cyl, drive->bios_head, drive->bios_sect); return ret; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-io.c linux.21pre4-ac6/drivers/ide/ide-io.c --- linux.21pre4/drivers/ide/ide-io.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-io.c 2003-02-11 15:51:50.000000000 +0000 @@ -363,14 +363,11 @@ void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, ide_handler_t *handler) { ide_hwif_t *hwif = HWIF(drive); - if (HWGROUP(drive)->handler != NULL) - BUG(); - ide_set_handler(drive, handler, WAIT_CMD, NULL); if (IDE_CONTROL_REG) hwif->OUTB(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ SELECT_MASK(drive,0); hwif->OUTB(nsect,IDE_NSECTOR_REG); - hwif->OUTB(cmd,IDE_COMMAND_REG); + ide_execute_command(drive, cmd, handler, WAIT_CMD, NULL); } EXPORT_SYMBOL(ide_cmd); @@ -403,7 +400,7 @@ udelay(100); } - if (!OK_STAT(stat, READY_STAT, BAD_STAT)) + if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL) return DRIVER(drive)->error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); @@ -833,14 +830,14 @@ * happens anyway when any interrupt comes in, IDE or otherwise * -- the kernel masks the IRQ while it is being handled. */ - if (masked_irq && hwif->irq != masked_irq) + if (hwif->irq != masked_irq) disable_irq_nosync(hwif->irq); spin_unlock(&io_request_lock); local_irq_enable(); /* allow other IRQs while we start this request */ startstop = start_request(drive, rq); spin_lock_irq(&io_request_lock); - if (masked_irq && hwif->irq != masked_irq) + if (hwif->irq != masked_irq) enable_irq(hwif->irq); if (startstop == ide_stopped) hwgroup->busy = 0; @@ -866,7 +863,7 @@ */ void do_ide_request(request_queue_t *q) { - ide_do_request(q->queuedata, 0); + ide_do_request(q->queuedata, IDE_NO_IRQ); } /* @@ -1003,8 +1000,12 @@ if (drive->waiting_for_dma) { startstop = ide_stopped; ide_dma_timeout_retry(drive); - } else - startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); + } else { + if(DRIVER(drive) != NULL) + startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); + else + startstop = ide_error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); + } } set_recovery_timer(hwif); drive->service_time = jiffies - drive->service_start; @@ -1014,7 +1015,7 @@ hwgroup->busy = 0; } } - ide_do_request(hwgroup, 0); + ide_do_request(hwgroup, IDE_NO_IRQ); spin_unlock_irqrestore(&io_request_lock, flags); } @@ -1319,7 +1320,7 @@ queue_head = queue_head->next; } list_add(&rq->queue, queue_head); - ide_do_request(hwgroup, 0); + ide_do_request(hwgroup, IDE_NO_IRQ); spin_unlock_irqrestore(&io_request_lock, flags); if (action == ide_wait) { /* wait for it to be serviced */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-iops.c linux.21pre4-ac6/drivers/ide/ide-iops.c --- linux.21pre4/drivers/ide/ide-iops.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-iops.c 2003-02-19 15:42:38.000000000 +0000 @@ -31,6 +31,78 @@ #include #include +/* + * IDE operator we assign to an unplugged device so that + * we don't trash new hardware assigned the same resources + */ + +static u8 ide_unplugged_inb (unsigned long port) +{ + return 0xFF; +} + +static u16 ide_unplugged_inw (unsigned long port) +{ + return 0xFFFF; +} + +static void ide_unplugged_insw (unsigned long port, void *addr, u32 count) +{ +} + +static u32 ide_unplugged_inl (unsigned long port) +{ + return 0xFFFFFFFF; +} + +static void ide_unplugged_insl (unsigned long port, void *addr, u32 count) +{ +} + +static void ide_unplugged_outb (u8 addr, unsigned long port) +{ +} + +static void ide_unplugged_outbsync (ide_drive_t *drive, u8 addr, unsigned long port) +{ +} + +static void ide_unplugged_outw (u16 addr, unsigned long port) +{ +} + +static void ide_unplugged_outsw (unsigned long port, void *addr, u32 count) +{ +} + +static void ide_unplugged_outl (u32 addr, unsigned long port) +{ +} + +static void ide_unplugged_outsl (unsigned long port, void *addr, u32 count) +{ +} + +void unplugged_hwif_iops (ide_hwif_t *hwif) +{ + hwif->OUTB = ide_unplugged_outb; + hwif->OUTBSYNC = ide_unplugged_outbsync; + hwif->OUTW = ide_unplugged_outw; + hwif->OUTL = ide_unplugged_outl; + hwif->OUTSW = ide_unplugged_outsw; + hwif->OUTSL = ide_unplugged_outsl; + hwif->INB = ide_unplugged_inb; + hwif->INW = ide_unplugged_inw; + hwif->INL = ide_unplugged_inl; + hwif->INSW = ide_unplugged_insw; + hwif->INSL = ide_unplugged_insl; +} + +EXPORT_SYMBOL(unplugged_hwif_iops); + +/* + * Conventional PIO operations for ATA devices + */ static u8 ide_inb (unsigned long port) { @@ -62,6 +134,11 @@ outb(addr, port); } +static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port) +{ + outb(addr, port); +} + static void ide_outw (u16 addr, unsigned long port) { outw(addr, port); @@ -85,6 +162,7 @@ void default_hwif_iops (ide_hwif_t *hwif) { hwif->OUTB = ide_outb; + hwif->OUTBSYNC = ide_outbsync; hwif->OUTW = ide_outw; hwif->OUTL = ide_outl; hwif->OUTSW = ide_outsw; @@ -98,6 +176,10 @@ EXPORT_SYMBOL(default_hwif_iops); +/* + * MMIO operations, typically used for SATA controllers + */ + static u8 ide_mm_inb (unsigned long port) { return (u8) readb(port); @@ -128,6 +210,11 @@ writeb(value, port); } +static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port) +{ + writeb(value, port); +} + static void ide_mm_outw (u16 value, unsigned long port) { writew(value, port); @@ -151,6 +238,9 @@ void default_hwif_mmiops (ide_hwif_t *hwif) { hwif->OUTB = ide_mm_outb; + /* Most systems will need to override OUTBSYNC, alas however + this one is controller specific! */ + hwif->OUTBSYNC = ide_mm_outbsync; hwif->OUTW = ide_mm_outw; hwif->OUTL = ide_mm_outl; hwif->OUTSW = ide_mm_outsw; @@ -872,7 +962,7 @@ if (speed >= XFER_SW_DMA_0) hwif->ide_dma_host_on(drive); else - hwif->ide_dma_off(drive); + hwif->ide_dma_off_quietly(drive); #endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ switch(speed) { @@ -907,6 +997,8 @@ * at the appropriate code to handle the next interrupt, and a * timer is started to prevent us from waiting forever in case * something goes wrong (see the ide_timer_expiry() handler later on). + * + * See also ide_execute_command */ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) @@ -916,7 +1008,7 @@ spin_lock_irqsave(&io_request_lock, flags); if (hwgroup->handler != NULL) { - printk("%s: ide_set_handler: handler not null; " + printk(KERN_CRIT "%s: ide_set_handler: handler not null; " "old=%p, new=%p\n", drive->name, hwgroup->handler, handler); } @@ -929,6 +1021,46 @@ EXPORT_SYMBOL(ide_set_handler); +/** + * ide_execute_command - execute an IDE command + * @drive: IDE drive to issue the command against + * @command: command byte to write + * @handler: handler for next phase + * @timeout: timeout for command + * @expiry: handler to run on timeout + * + * Helper function to issue an IDE command. This handles the + * atomicity requirements, command timing and ensures that the + * handler and IRQ setup do not race. All IDE command kick off + * should go via this function or do equivalent locking. + */ + +void ide_execute_command(ide_drive_t *drive, task_ioreg_t cmd, ide_handler_t *handler, unsigned timeout, ide_expiry_t *expiry) +{ + unsigned long flags; + ide_hwgroup_t *hwgroup = HWGROUP(drive); + ide_hwif_t *hwif = HWIF(drive); + + spin_lock_irqsave(&io_request_lock, flags); + + if(hwgroup->handler) + BUG(); + hwgroup->handler = handler; + hwgroup->expiry = expiry; + hwgroup->timer.expires = jiffies + timeout; + add_timer(&hwgroup->timer); + hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG); + /* Drive takes 400nS to respond, we must avoid the IRQ being + serviced before that. + + FIXME: we could skip this delay with care on non shared + devices + */ + ndelay(400); + spin_unlock_irqrestore(&io_request_lock, flags); +} + +EXPORT_SYMBOL(ide_execute_command); /* needed below */ ide_startstop_t do_reset1 (ide_drive_t *, int); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-probe.c linux.21pre4-ac6/drivers/ide/ide-probe.c --- linux.21pre4/drivers/ide/ide-probe.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-probe.c 2003-02-11 01:11:57.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-probe.c Version 1.07 March 18, 2001 + * linux/drivers/ide/ide-probe.c Version 1.10 Feb 11, 2003 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -27,6 +27,8 @@ * Version 1.06 stream line request queue and prep for cascade project. * Version 1.07 max_sect <= 255; slower disks would get behind and * then fall over when they get to 256. Paul G. + * Version 1.10 Update set for new IDE. drive->id is now always + * valid after probe time even with noprobe */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -54,22 +56,54 @@ #include #include -/* - * CompactFlash cards and their brethern pretend to be removable - * hard disks, except: - * (1) they never have a slave unit, and - * (2) they don't have doorlock mechanisms. - * This test catches them, and is invoked elsewhere when setting - * appropriate config bits. - * - * FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD) - * devices, so in linux 2.3.x we should change this to just treat all PCMCIA - * drives this way, and get rid of the model-name tests below - * (too big of an interface change for 2.2.x). - * At that time, we might also consider parameterizing the timeouts and retries, - * since these are MUCH faster than mechanical drives. -M.Lord +/** + * generic_id - add a generic drive id + * @drive: drive to make an ID block for + * + * Add a fake id field to the drive we are passed. This allows + * use to skip a ton of NULL checks (which people always miss) + * and make drive properties unconditional outside of this file */ -inline int drive_is_flashcard (ide_drive_t *drive) + +static int generic_id(ide_drive_t *drive) +{ + drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL); + if(drive->id == NULL) + { + printk(KERN_ERR "ide: out of memory for id data.\n"); + return -ENOMEM; + } + memset(drive->id, 0, SECTOR_WORDS * 4); + drive->id->cyls = drive->cyl; + drive->id->heads = drive->head; + drive->id->sectors = drive->sect; + drive->id->cur_cyls = drive->cyl; + drive->id->cur_heads = drive->head; + drive->id->cur_sectors = drive->sect; + strcpy(drive->id->model, "UNKNOWN"); + return 0; +} + +/** + * drive_is_flashcard - check for compact flash + * @drive: drive to check + * + * CompactFlash cards and their brethern pretend to be removable + * hard disks, except: + * (1) they never have a slave unit, and + * (2) they don't have doorlock mechanisms. + * This test catches them, and is invoked elsewhere when setting + * appropriate config bits. + * + * FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD) + * devices, so in linux 2.3.x we should change this to just treat all + * PCMCIA drives this way, and get rid of the model-name tests below + * (too big of an interface change for 2.4.x). + * At that time, we might also consider parameterizing the timeouts and + * retries, since these are MUCH faster than mechanical drives. -M.Lord + */ + +static inline int drive_is_flashcard (ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -88,6 +122,16 @@ return 0; /* no, it is not a flash memory card */ } +/** + * do_identify - identify a drive + * @drive: drive to identify + * @cmd: command used + * + * Called when we have issued a drive identify command to + * read and parse the results. This function is run with + * interrupts disabled. + */ + static inline void do_identify (ide_drive_t *drive, u8 cmd) { ide_hwif_t *hwif = HWIF(drive); @@ -207,6 +251,7 @@ */ if (id->config & (1<<7)) drive->removable = 1; + /* * Prevent long system lockup probing later for non-existant * slave drive if the hwif is actually a flash memory card of @@ -214,11 +259,16 @@ */ drive->is_flash = 0; if (drive_is_flashcard(drive)) { - ide_drive_t *mate = &hwif->drives[1^drive->select.b.unit]; +#if 0 + /* The new IDE adapter widgets don't follow this heuristic + so we must nowdays just bite the bullet and take the + probe hit */ + ide_drive_t *mate = &hwif->drives[1^drive->select.b.unit]; if (!mate->ata_flash) { mate->present = 0; mate->noprobe = 1; } +#endif drive->is_flash = 1; } drive->media = ide_disk; @@ -233,16 +283,21 @@ return; } -/* - * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive - * and waits for a response. It also monitors irqs while this is - * happening, in hope of automatically determining which one is - * being used by the interface. +/** + * actual_try_to_identify - send ata/atapi identify + * @drive: drive to identify + * @cmd: comamnd to use * - * Returns: 0 device was identified - * 1 device timed-out (no response to identify request) - * 2 device aborted the command (refused to identify itself) + * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive + * and waits for a response. It also monitors irqs while this is + * happening, in hope of automatically determining which one is + * being used by the interface. + * + * Returns: 0 device was identified + * 1 device timed-out (no response to identify request) + * 2 device aborted the command (refused to identify itself) */ + static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) { ide_hwif_t *hwif = HWIF(drive); @@ -257,7 +312,7 @@ a = hwif->INB(IDE_ALTSTATUS_REG); s = hwif->INB(IDE_STATUS_REG); if ((a ^ s) & ~INDEX_STAT) { - printk("%s: probing with STATUS(0x%02x) instead of " + printk(KERN_INFO "%s: probing with STATUS(0x%02x) instead of " "ALTSTATUS(0x%02x)\n", drive->name, s, a); /* ancient Seagate drives, broken interfaces */ hd_status = IDE_STATUS_REG; @@ -316,6 +371,16 @@ return rc; } +/** + * try_to_identify - try to identify a drive + * @drive: drive to probe + * @cmd: comamnd to use + * + * Issue the identify command and then do IRQ probing to + * complete the identification when needed by finding the + * IRQ the drive is attached to + */ + static int try_to_identify (ide_drive_t *drive, u8 cmd) { ide_hwif_t *hwif = HWIF(drive); @@ -365,15 +430,19 @@ } -/* - * do_probe() has the difficult job of finding a drive if it exists, - * without getting hung up if it doesn't exist, without trampling on - * ethernet cards, and without leaving any IRQs dangling to haunt us later. - * - * If a drive is "known" to exist (from CMOS or kernel parameters), - * but does not respond right away, the probe will "hang in there" - * for the maximum wait time (about 30 seconds), otherwise it will - * exit much more quickly. +/** + * do_probe - probe an IDE device + * @drive: drive to probe + * @cmd: command to use + * + * do_probe() has the difficult job of finding a drive if it exists, + * without getting hung up if it doesn't exist, without trampling on + * ethernet cards, and without leaving any IRQs dangling to haunt us later. + * + * If a drive is "known" to exist (from CMOS or kernel parameters), + * but does not respond right away, the probe will "hang in there" + * for the maximum wait time (about 30 seconds), otherwise it will + * exit much more quickly. * * Returns: 0 device was identified * 1 device timed-out (no response to identify request) @@ -381,6 +450,7 @@ * 3 bad status from device (possible for ATAPI drives) * 4 probe was not attempted because failure was obvious */ + static int do_probe (ide_drive_t *drive, u8 cmd) { int rc; @@ -496,49 +566,70 @@ } } -/* - * probe_for_drive() tests for existence of a given drive using do_probe(). +/** + * probe_for_drives - upper level drive probe + * @drive: drive to probe for + * + * probe_for_drive() tests for existence of a given drive using do_probe() + * and presents things to the user as needed. * - * Returns: 0 no device was found - * 1 device was found (note: drive->present might still be 0) + * Returns: 0 no device was found + * 1 device was found (note: drive->present might + * still be 0) */ + static inline u8 probe_for_drive (ide_drive_t *drive) { /* skip probing? */ - if (drive->noprobe) - return drive->present; - - /* if !(success||timed-out) */ - if (do_probe(drive, WIN_IDENTIFY) >= 2) { - /* look for ATAPI device */ - (void) do_probe(drive, WIN_PIDENTIFY); + if (!drive->noprobe) + { + /* if !(success||timed-out) */ + if (do_probe(drive, WIN_IDENTIFY) >= 2) { + /* look for ATAPI device */ + (void) do_probe(drive, WIN_PIDENTIFY); + } + if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T")) + enable_nest(drive); + if (!drive->present) + /* drive not found */ + return 0; + + /* identification failed? */ + if (drive->id == NULL) { + if (drive->media == ide_disk) { + printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d\n", + drive->name, drive->cyl, + drive->head, drive->sect); + } else if (drive->media == ide_cdrom) { + printk(KERN_INFO "%s: ATAPI cdrom (?)\n", drive->name); + } else { + /* nuke it */ + drive->present = 0; + } + } + /* drive was found */ } - if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T")) - enable_nest(drive); - if (!drive->present) - /* drive not found */ + if(!drive->present) return 0; - - /* identification failed? */ - if (drive->id == NULL) { - if (drive->media == ide_disk) { - printk("%s: non-IDE drive, CHS=%d/%d/%d\n", - drive->name, drive->cyl, - drive->head, drive->sect); - } else if (drive->media == ide_cdrom) { - printk("%s: ATAPI cdrom (?)\n", drive->name); - } else { - /* nuke it */ + if(drive->id == NULL) + if(generic_id(drive) < 0) drive->present = 0; - } - } - /* drive was found */ - return 1; + return drive->present; } #define hwif_check_region(addr, num) \ ((hwif->mmio) ? check_mem_region((addr),(num)) : check_region((addr),(num))) +/** + * hwif_check_regions - check resources for IDE + * @hwif: interface to use + * + * Checks if all the needed resources for an interface are free + * providing the interface is PIO. Right now core IDE code does + * this work which is deeply wrong. MMIO leaves it to the controller + * driver, PIO will migrate this way over time + */ + static int hwif_check_regions (ide_hwif_t *hwif) { u32 i = 0; @@ -590,6 +681,72 @@ //EXPORT_SYMBOL(hwif_register); +/* Enable code below on all archs later, for now, I want it on PPC + */ +#ifdef CONFIG_PPC +/* + * This function waits for the hwif to report a non-busy status + * see comments in probe_hwif() + */ +static int wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) +{ + u8 stat = 0; + + while(timeout--) { + /* Turn this into a schedule() sleep once I'm sure + * about locking issues (2.5 work ?) + */ + mdelay(1); + stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); + if ((stat & BUSY_STAT) == 0) + break; + /* Assume a value of 0xff means nothing is connected to + * the interface and it doesn't implement the pull-down + * resistor on D7 + */ + if (stat == 0xff) + break; + } + return ((stat & BUSY_STAT) == 0) ? 0 : -EBUSY; +} + +static int wait_hwif_ready(ide_hwif_t *hwif) +{ + int rc; + + printk(KERN_INFO "Probing IDE interface %s...\n", hwif->name); + + /* Let HW settle down a bit from whatever init state we + * come from */ + mdelay(2); + + /* Wait for BSY bit to go away, spec timeout is 30 seconds, + * I know of at least one disk who takes 31 seconds, I use 35 + * here to be safe + */ + rc = wait_not_busy(hwif, 35000); + if (rc) + return rc; + + /* Now make sure both master & slave are ready */ + SELECT_DRIVE(&hwif->drives[0]); + hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); + mdelay(2); + rc = wait_not_busy(hwif, 10000); + if (rc) + return rc; + SELECT_DRIVE(&hwif->drives[1]); + hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); + mdelay(2); + rc = wait_not_busy(hwif, 10000); + + /* Exit function with master reselected (let's be sane) */ + SELECT_DRIVE(&hwif->drives[0]); + + return rc; +} +#endif /* CONFIG_PPC */ + /* * This routine only knows how to look for drive units 0 and 1 * on an interface, so any setting of MAX_DRIVES > 2 won't work here. @@ -618,13 +775,13 @@ ide_drive_t *drive = &hwif->drives[unit]; if (drive->present) { drive->present = 0; - printk("%s: ERROR, PORTS ALREADY IN USE\n", + printk(KERN_ERR "%s: ERROR, PORTS ALREADY IN USE\n", drive->name); msgout = 1; } } if (!msgout) - printk("%s: ports already in use, skipping probe\n", + printk(KERN_ERR "%s: ports already in use, skipping probe\n", hwif->name); return; } @@ -638,6 +795,31 @@ disable_irq(hwif->irq); local_irq_set(flags); + +#ifdef CONFIG_PPC + /* This is needed on some PPCs and a bunch of BIOS-less embedded + * platforms. Typical cases are: + * + * - The firmware hard reset the disk before booting the kernel, + * the drive is still doing it's poweron-reset sequence, that + * can take up to 30 seconds + * - The firmware does nothing (or no firmware), the device is + * still in POST state (same as above actually). + * - Some CD/DVD/Writer combo drives tend to drive the bus during + * their reset sequence even when they are non-selected slave + * devices, thus preventing discovery of the main HD + * + * Doing this wait-for-busy should not harm any existing configuration + * (at least things won't be worse than what current code does, that + * is blindly go & talk to the drive) and fix some issues like the + * above. + * + * BenH. + */ + if (wait_hwif_ready(hwif)) + printk(KERN_WARNING "%s: Wait for ready failed before probe !\n", hwif->name); +#endif /* CONFIG_PPC */ + /* * Second drive should only exist if first drive was found, * but a lot of cdrom drives are configured as single slaves. @@ -660,7 +842,7 @@ unsigned long timeout = jiffies + WAIT_WORSTCASE; u8 stat; - printk("%s: reset\n", hwif->name); + printk(KERN_WARNING "%s: reset\n", hwif->name); hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); udelay(10); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-proc.c linux.21pre4-ac6/drivers/ide/ide-proc.c --- linux.21pre4/drivers/ide/ide-proc.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-proc.c 2003-02-11 16:51:37.000000000 +0000 @@ -461,20 +461,40 @@ { ide_drive_t *drive = (ide_drive_t *)data; int len = 0, i = 0; + int err = 0; - if (drive && !taskfile_lib_get_identify(drive, page)) { + len = sprintf(page, "\n"); + + if (drive) + { unsigned short *val = (unsigned short *) page; - char *out = ((char *)val) + (SECTOR_WORDS * 4); - page = out; - do { - out += sprintf(out, "%04x%c", - le16_to_cpu(*val), (++i & 7) ? ' ' : '\n'); - val += 1; - } while (i < (SECTOR_WORDS * 2)); - len = out - page; + + /* + * The current code can't handle a driverless + * identify query taskfile. Now the right fix is + * to add a 'default' driver but that is a bit + * more work. + * + * FIXME: this has to be fixed for hotswap devices + */ + + if(DRIVER(drive)) + err = taskfile_lib_get_identify(drive, page); + else /* This relies on the ID changes */ + val = drive->id; + + if(!err) + { + char *out = ((char *)page) + (SECTOR_WORDS * 4); + page = out; + do { + out += sprintf(out, "%04x%c", + le16_to_cpu(*val), (++i & 7) ? ' ' : '\n'); + val += 1; + } while (i < (SECTOR_WORDS * 2)); + len = out - page; + } } - else - len = sprintf(page, "\n"); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } @@ -488,6 +508,7 @@ char *out = page; int len, rc, mul_factor, div_factor; + down(&ide_setting_sem); out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); while(setting) { @@ -507,6 +528,7 @@ setting = setting->next; } len = out - page; + up(&ide_setting_sem); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } @@ -575,12 +597,17 @@ --n; ++p; } + + down(&ide_setting_sem); setting = ide_find_setting_by_name(drive, name); if (!setting) + { + up(&ide_setting_sem); goto parse_error; - + } if (for_real) ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor); + up(&ide_setting_sem); } } while (!for_real++); return count; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-tape.c linux.21pre4-ac6/drivers/ide/ide-tape.c --- linux.21pre4/drivers/ide/ide-tape.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-tape.c 2003-02-04 15:24:51.000000000 +0000 @@ -2450,13 +2450,10 @@ set_bit(PC_DMA_IN_PROGRESS, &pc->flags); #endif /* CONFIG_BLK_DEV_IDEDMA */ if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { - if (HWGROUP(drive)->handler != NULL) - BUG(); - ide_set_handler(drive, + ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); - HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); return ide_started; } else { HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-taskfile.c linux.21pre4-ac6/drivers/ide/ide-taskfile.c --- linux.21pre4/drivers/ide/ide-taskfile.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-taskfile.c 2003-02-11 16:53:04.000000000 +0000 @@ -201,8 +201,7 @@ hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); if (task->handler != NULL) { - ide_set_handler(drive, task->handler, WAIT_WORSTCASE, NULL); - hwif->OUTB(taskfile->command, IDE_COMMAND_REG); + ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); if (task->prehandler != NULL) return task->prehandler(drive, task->rq); return ide_started; @@ -244,13 +243,13 @@ case WIN_WRITEDMA_ONCE: case WIN_WRITEDMA: case WIN_WRITEDMA_EXT: - if (drive->using_dma && !(hwif->ide_dma_write(drive))); + if (drive->using_dma && !(hwif->ide_dma_write(drive))) return ide_started; case WIN_READDMA_ONCE: case WIN_READDMA: case WIN_READDMA_EXT: case WIN_IDENTIFY_DMA: - if (drive->using_dma && !(hwif->ide_dma_read(drive))); + if (drive->using_dma && !(hwif->ide_dma_read(drive))) return ide_started; default: break; @@ -909,7 +908,7 @@ * NOTE: could rewind beyond beginning :-/ */ } else { - printk("%s: MULTI-WRITE assume all data " \ + printk(KERN_ERR "%s: MULTI-WRITE assume all data " \ "transfered is bad status=0x%02x\n", drive->name, stat); } @@ -930,7 +929,7 @@ * NOTE: could rewind beyond beginning :-/ */ } else { - printk("%s: MULTI-WRITE assume all data " \ + printk(KERN_ERR "%s: MULTI-WRITE assume all data " \ "transfered is bad status=0x%02x\n", drive->name, stat); } @@ -1547,7 +1546,7 @@ case TASKFILE_MULTI_OUT: if (!drive->mult_count) { /* (hs): give up if multcount is not set */ - printk("%s: %s Multimode Write " \ + printk(KERN_ERR "%s: %s Multimode Write " \ "multcount is not set\n", drive->name, __FUNCTION__); err = -EPERM; @@ -1575,7 +1574,7 @@ case TASKFILE_MULTI_IN: if (!drive->mult_count) { /* (hs): give up if multcount is not set */ - printk("%s: %s Multimode Read failure " \ + printk(KERN_ERR "%s: %s Multimode Read failure " \ "multcount is not set\n", drive->name, __FUNCTION__); err = -EPERM; @@ -1929,9 +1928,8 @@ if (task->handler == NULL) return ide_stopped; - ide_set_handler(drive, task->handler, WAIT_WORSTCASE, NULL); /* Issue the command */ - hwif->OUTB(taskfile->command, IDE_COMMAND_REG); + ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); if (task->prehandler != NULL) return task->prehandler(drive, HWGROUP(drive)->rq); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ide-timing.h linux.21pre4-ac6/drivers/ide/ide-timing.h --- linux.21pre4/drivers/ide/ide-timing.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ide-timing.h 2003-02-07 15:49:47.000000000 +0000 @@ -245,14 +245,6 @@ } /* - * If the drive is an ATAPI device it may need slower address setup timing, - * so we stay on the safe side. - */ - - if (drive->media != ide_disk) - p.setup = 120; - -/* * Convert the timing to bus clock counts. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/ali14xx.c linux.21pre4-ac6/drivers/ide/legacy/ali14xx.c --- linux.21pre4/drivers/ide/legacy/ali14xx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/ali14xx.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ali14xx.c Version 0.03 Feb 09, 1996 + * linux/drivers/ide/legacy/ali14xx.c Version 0.03 Feb 09, 1996 * * Copyright (C) 1996 Linus Torvalds & author (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/buddha.c linux.21pre4-ac6/drivers/ide/legacy/buddha.c --- linux.21pre4/drivers/ide/legacy/buddha.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/buddha.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/buddha.c -- Amiga Buddha, Catweasel and X-Surf IDE Driver + * linux/drivers/ide/legacy/buddha.c -- Amiga Buddha, Catweasel and X-Surf IDE Driver * * Copyright (C) 1997, 2001 by Geert Uytterhoeven and others * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/dtc2278.c linux.21pre4-ac6/drivers/ide/legacy/dtc2278.c --- linux.21pre4/drivers/ide/legacy/dtc2278.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/dtc2278.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/dtc2278.c Version 0.02 Feb 10, 1996 + * linux/drivers/ide/legacy/dtc2278.c Version 0.02 Feb 10, 1996 * * Copyright (C) 1996 Linus Torvalds & author (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/falconide.c linux.21pre4-ac6/drivers/ide/legacy/falconide.c --- linux.21pre4/drivers/ide/legacy/falconide.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/falconide.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/falconide.c -- Atari Falcon IDE Driver + * linux/drivers/ide/legacy/falconide.c -- Atari Falcon IDE Driver * * Created 12 Jul 1997 by Geert Uytterhoeven * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/gayle.c linux.21pre4-ac6/drivers/ide/legacy/gayle.c --- linux.21pre4/drivers/ide/legacy/gayle.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/gayle.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/gayle.c -- Amiga Gayle IDE Driver + * linux/drivers/ide/legacy/gayle.c -- Amiga Gayle IDE Driver * * Created 9 Jul 1997 by Geert Uytterhoeven * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/hd.c linux.21pre4-ac6/drivers/ide/legacy/hd.c --- linux.21pre4/drivers/ide/legacy/hd.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/hd.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/hd.c + * linux/drivers/ide/legacy/hd.c * * Copyright (C) 1991, 1992 Linus Torvalds */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/ht6560b.c linux.21pre4-ac6/drivers/ide/legacy/ht6560b.c --- linux.21pre4/drivers/ide/legacy/ht6560b.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/ht6560b.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ht6560b.c Version 0.07 Feb 1, 2000 + * linux/drivers/ide/legacy/ht6560b.c Version 0.07 Feb 1, 2000 * * Copyright (C) 1995-2000 Linus Torvalds & author (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/ide-cs.c linux.21pre4-ac6/drivers/ide/legacy/ide-cs.c --- linux.21pre4/drivers/ide/legacy/ide-cs.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/ide-cs.c 2003-01-28 16:22:27.000000000 +0000 @@ -92,10 +92,11 @@ int ndev; dev_node_t node; int hd; + struct tq_struct rel_task; } ide_info_t; static void ide_config(dev_link_t *link); -static void ide_release(u_long arg); +static void ide_release(void *arg); static int ide_event(event_t event, int priority, event_callback_args_t *args); @@ -136,9 +137,8 @@ if (!info) return NULL; memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + INIT_TQUEUE(&info->rel_task, ide_release, link); - link->release.function = &ide_release; - link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; @@ -187,6 +187,7 @@ static void ide_detach(dev_link_t *link) { dev_link_t **linkp; + ide_info_t *info = link->priv; int ret; DEBUG(0, "ide_detach(0x%p)\n", link); @@ -197,9 +198,10 @@ if (*linkp == NULL) return; - del_timer(&link->release); - if (link->state & DEV_CONFIG) - ide_release((u_long)link); + if (link->state & DEV_CONFIG) { + schedule_task(&info->rel_task); + flush_scheduled_tasks(); + } if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -209,7 +211,7 @@ /* Unlink, free device structure */ *linkp = link->next; - kfree(link->priv); + kfree(info); } /* ide_detach */ @@ -381,7 +383,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); failed: - ide_release((u_long)link); + ide_release(link); } /* ide_config */ @@ -393,12 +395,15 @@ ======================================================================*/ -void ide_release(u_long arg) +static void ide_release(void *arg) { - dev_link_t *link = (dev_link_t *)arg; + dev_link_t *link = arg; ide_info_t *info = link->priv; - DEBUG(0, "ide_release(0x%p)\n", link); + if (!(link->state & DEV_CONFIG)) + return; + + DEBUG(0, "ide_do_release(0x%p)\n", link); if (info->ndev) { /* FIXME: if this fails we need to queue the cleanup somehow @@ -435,6 +440,7 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; + ide_info_t *info = link->priv; DEBUG(1, "ide_event(0x%06x)\n", event); @@ -442,7 +448,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + schedule_task(&info->rel_task); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/macide.c linux.21pre4-ac6/drivers/ide/legacy/macide.c --- linux.21pre4/drivers/ide/legacy/macide.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/macide.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/macide.c -- Macintosh IDE Driver + * linux/drivers/ide/legacy/macide.c -- Macintosh IDE Driver * * Copyright (C) 1998 by Michael Schmitz * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/pdc4030.c linux.21pre4-ac6/drivers/ide/legacy/pdc4030.c --- linux.21pre4/drivers/ide/legacy/pdc4030.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/pdc4030.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* -*- linux-c -*- - * linux/drivers/ide/pdc4030.c Version 0.90 May 27, 1999 + * linux/drivers/ide/legacy/pdc4030.c Version 0.90 May 27, 1999 * * Copyright (C) 1995-2002 Linus Torvalds & authors (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/pdc4030.h linux.21pre4-ac6/drivers/ide/legacy/pdc4030.h --- linux.21pre4/drivers/ide/legacy/pdc4030.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/pdc4030.h 2003-02-07 15:49:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pdc4030.h + * linux/drivers/ide/legacy/pdc4030.h * * Copyright (C) 1995-1998 Linus Torvalds & authors */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/q40ide.c linux.21pre4-ac6/drivers/ide/legacy/q40ide.c --- linux.21pre4/drivers/ide/legacy/q40ide.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/q40ide.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/q40ide.c -- Q40 I/O port IDE Driver + * linux/drivers/ide/legacy/q40ide.c -- Q40 I/O port IDE Driver * * (c) Richard Zidlicky * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/qd65xx.c linux.21pre4-ac6/drivers/ide/legacy/qd65xx.c --- linux.21pre4/drivers/ide/legacy/qd65xx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/qd65xx.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/qd65xx.c Version 0.07 Sep 30, 2001 + * linux/drivers/ide/legacy/qd65xx.c Version 0.07 Sep 30, 2001 * * Copyright (C) 1996-2001 Linus Torvalds & author (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/qd65xx.h linux.21pre4-ac6/drivers/ide/legacy/qd65xx.h --- linux.21pre4/drivers/ide/legacy/qd65xx.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/qd65xx.h 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/qd65xx.h + * linux/drivers/ide/legacy/qd65xx.h * * Copyright (c) 2000 Linus Torvalds & authors */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/legacy/umc8672.c linux.21pre4-ac6/drivers/ide/legacy/umc8672.c --- linux.21pre4/drivers/ide/legacy/umc8672.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/legacy/umc8672.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/umc8672.c Version 0.05 Jul 31, 1996 + * linux/drivers/ide/legacy/umc8672.c Version 0.05 Jul 31, 1996 * * Copyright (C) 1995-1996 Linus Torvalds & author (see below) */ @@ -137,7 +137,7 @@ unsigned long flags; local_irq_save(flags); - if (check_region(0x108, 2)) { + if (!request_region(0x108, 2, "umc8672")) { local_irq_restore(flags); printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n"); return 1; @@ -146,6 +146,7 @@ if (in_umc (0xd5) != 0xa0) { local_irq_restore(flags); printk(KERN_ERR "umc8672: not found\n"); + release_region(0x108, 2); return 1; } outb_p(0xa5,0x108); /* disable umc */ @@ -153,7 +154,6 @@ umc_set_speeds (current_speeds); local_irq_restore(flags); - request_region(0x108, 2, "umc8672"); ide_hwifs[0].chipset = ide_umc8672; ide_hwifs[1].chipset = ide_umc8672; ide_hwifs[0].tuneproc = &tune_umc; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/adma100.c linux.21pre4-ac6/drivers/ide/pci/adma100.c --- linux.21pre4/drivers/ide/pci/adma100.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/adma100.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/adma100.c -- basic support for Pacific Digital ADMA-100 boards + * linux/drivers/ide/pci/adma100.c -- basic support for Pacific Digital ADMA-100 boards * * Created 09 Apr 2002 by Mark Lord * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/aec62xx.c linux.21pre4-ac6/drivers/ide/pci/aec62xx.c --- linux.21pre4/drivers/ide/pci/aec62xx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/aec62xx.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/aec62xx.c Version 0.11 March 27, 2002 + * linux/drivers/ide/pci/aec62xx.c Version 0.11 March 27, 2002 * * Copyright (C) 1999-2002 Andre Hedrick * @@ -409,7 +409,7 @@ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } #if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/alim15x3.c linux.21pre4-ac6/drivers/ide/pci/alim15x3.c --- linux.21pre4/drivers/ide/pci/alim15x3.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/alim15x3.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/alim15x3.c Version 0.16 2003/01/02 + * linux/drivers/ide/pci/alim15x3.c Version 0.16 2003/01/02 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer @@ -19,6 +19,10 @@ * Don't use LBA48 mode on ALi <= 0xC4 * Don't poke 0x79 with a non ALi northbridge * Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang) + * + * Documentation + * Chipset documentation available under NDA only + * */ #include @@ -296,6 +300,7 @@ int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; u8 cd_dma_fifo = 0; + int unit = drive->select.b.unit & 1; pio = ide_get_best_pio_mode(drive, pio, 5, &d); s_time = ide_pio_timings[pio].setup_time; @@ -324,13 +329,13 @@ */ pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); if (drive->media==ide_disk) { - if (hwif->channel) { + if (unit) { pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); } else { pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); } } else { - if (hwif->channel) { + if (unit) { pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); } else { pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/amd74xx.c linux.21pre4-ac6/drivers/ide/pci/amd74xx.c --- linux.21pre4/drivers/ide/pci/amd74xx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/amd74xx.c 2003-02-13 21:38:17.000000000 +0000 @@ -1,390 +1,440 @@ /* - * linux/drivers/ide/amd74xx.c Version 0.05 June 9, 2000 + * Version 2.9 * - * Copyright (C) 1999-2000 Andre Hedrick - * May be copied or modified under the terms of the GNU General Public License + * AMD 755/756/766/8111 and nVidia nForce IDE driver for Linux. * + * Copyright (c) 2000-2002 Vojtech Pavlik + * + * Based on the work of: + * Andre Hedrick + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. */ #include #include -#include #include -#include -#include -#include #include #include -#include - -#include -#include #include +#include #include - #include -#include -#include "ide_modes.h" +#include "ide-timing.h" #include "amd74xx.h" -#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) +#define AMD_IDE_ENABLE (0x00 + amd_config->base) +#define AMD_IDE_CONFIG (0x01 + amd_config->base) +#define AMD_CABLE_DETECT (0x02 + amd_config->base) +#define AMD_DRIVE_TIMING (0x08 + amd_config->base) +#define AMD_8BIT_TIMING (0x0e + amd_config->base) +#define AMD_ADDRESS_SETUP (0x0c + amd_config->base) +#define AMD_UDMA_TIMING (0x10 + amd_config->base) + +#define AMD_UDMA 0x07 +#define AMD_UDMA_33 0x01 +#define AMD_UDMA_66 0x02 +#define AMD_UDMA_100 0x03 +#define AMD_CHECK_SWDMA 0x08 +#define AMD_BAD_SWDMA 0x10 +#define AMD_BAD_FIFO 0x20 + +/* + * AMD SouthBridge chips. + */ + +static struct amd_ide_chip { + unsigned short id; + unsigned char rev; + unsigned long base; + unsigned char flags; +} amd_ide_chips[] = { + { PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, /* AMD-755 Cobra */ + { PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA }, /* AMD-756 Viper */ + { PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, /* AMD-766 Viper */ + { PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-768 Opus */ + { PCI_DEVICE_ID_AMD_8111_IDE, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-8111 */ + { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce */ + { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce */ + + { 0 } +}; + +static struct amd_ide_chip *amd_config; +static unsigned char amd_enabled; +static unsigned int amd_80w; +static unsigned int amd_clock; + +static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 }; +static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 }; +static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" }; + +/* + * AMD /proc entry. + */ + +#ifdef CONFIG_PROC_FS + #include #include -static u8 amd74xx_proc = 0; - +static unsigned long amd_base; static struct pci_dev *bmide_dev; +extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ -static int amd74xx_get_info (char *buffer, char **addr, off_t offset, int count) -{ +#define amd_print(format, arg...) p += sprintf(p, format "\n" , ## arg) +#define amd_print_drive(name, format, arg...)\ + p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n"); + +static int amd74xx_get_info(char *buffer, char **addr, off_t offset, int count) +{ + int speed[4], cycle[4], setup[4], active[4], recover[4], den[4], + uen[4], udma[4], active8b[4], recover8b[4]; + struct pci_dev *dev = bmide_dev; + unsigned int v, u, i; + unsigned short c, w; + unsigned char t; char *p = buffer; - u32 bibma = pci_resource_start(bmide_dev, 4); - u8 c0 = 0, c1 = 0; - /* - * at that point bibma+0x2 et bibma+0xa are byte registers - * to investigate: - */ - c0 = inb((unsigned short)bibma + 0x02); - c1 = inb((unsigned short)bibma + 0x0a); - - p += sprintf(p, "\n " - "AMD %04X VIPER Chipset.\n", bmide_dev->device); - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - p += sprintf(p, " %sabled " - " %sabled\n", - (c0&0x80) ? "dis" : " en", - (c1&0x80) ? "dis" : " en"); - p += sprintf(p, "--------------- drive0 --------- drive1 " - "-------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s " - " %s %s\n", - (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ", - (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " ); - p += sprintf(p, "UDMA\n"); - p += sprintf(p, "DMA\n"); - p += sprintf(p, "PIO\n"); - - return p-buffer; /* => must be less than 4k! */ -} -#endif /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */ - -static int amd74xx_mode5_check (struct pci_dev *dev) -{ - switch(dev->device) { - case PCI_DEVICE_ID_AMD_VIPER_7411: - case PCI_DEVICE_ID_AMD_VIPER_7441: - case PCI_DEVICE_ID_AMD_8111_IDE: - return 1; - default: - return 0; + amd_print("----------AMD BusMastering IDE Configuration----------------"); + + amd_print("Driver Version: 2.9"); + amd_print("South Bridge: %s", bmide_dev->name); + + pci_read_config_byte(dev, PCI_REVISION_ID, &t); + amd_print("Revision: IDE %#x", t); + amd_print("Highest DMA rate: %s", amd_dma[amd_config->flags & AMD_UDMA]); + + amd_print("BM-DMA base: %#lx", amd_base); + amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10); + + amd_print("-----------------------Primary IDE-------Secondary IDE------"); + + pci_read_config_byte(dev, AMD_IDE_CONFIG, &t); + amd_print("Prefetch Buffer: %10s%20s", (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no"); + amd_print("Post Write Buffer: %10s%20s", (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no"); + + pci_read_config_byte(dev, AMD_IDE_ENABLE, &t); + amd_print("Enabled: %10s%20s", (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no"); + + c = inb(amd_base + 0x02) | (inb(amd_base + 0x0a) << 8); + amd_print("Simplex only: %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no"); + + amd_print("Cable Type: %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w"); + + if (!amd_clock) + return p - buffer; + + amd_print("-------------------drive0----drive1----drive2----drive3-----"); + + pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t); + pci_read_config_dword(dev, AMD_DRIVE_TIMING, &v); + pci_read_config_word(dev, AMD_8BIT_TIMING, &w); + pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); + + for (i = 0; i < 4; i++) { + setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1; + recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1; + active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1; + active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1; + recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1; + + udma[i] = amd_udma2cyc[((u >> ((3 - i) << 3)) & 0x7)]; + uen[i] = ((u >> ((3 - i) << 3)) & 0x40) ? 1 : 0; + den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); + + if (den[i] && uen[i] && udma[i] == 1) { + speed[i] = amd_clock * 3; + cycle[i] = 666666 / amd_clock; + continue; + } + + speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2); + cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2; } -} -static unsigned int amd74xx_swdma_check (struct pci_dev *dev) -{ - unsigned int class_rev; + amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); - if (amd74xx_mode5_check(dev)) - return 1; + amd_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / amd_clock); + amd_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / amd_clock); + amd_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / amd_clock); + amd_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / amd_clock); + amd_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / amd_clock); + amd_print_drive("Cycle Time: ", "%8dns", cycle[i]); + amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10); - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - return ((int) (class_rev >= 7) ? 1 : 0); + return p - buffer; /* hoping it is less than 4K... */ } -static u8 amd74xx_ratemask (ide_drive_t *drive) +#endif + +/* + * amd_set_speed() writes timing values to the chipset registers + */ + +static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timing *timing) { - u8 mode; + unsigned char t; - switch(HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_AMD_8111_IDE: - case PCI_DEVICE_ID_AMD_VIPER_7441: - case PCI_DEVICE_ID_AMD_VIPER_7411: - mode = 3; - break; - case PCI_DEVICE_ID_AMD_VIPER_7409: - mode = 2; - break; - case PCI_DEVICE_ID_AMD_COBRA_7401: - return 1; - default: - return 0; - } + pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t); + t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); + pci_write_config_byte(dev, AMD_ADDRESS_SETUP, t); - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); + pci_write_config_byte(dev, AMD_8BIT_TIMING + (1 - (dn >> 1)), + ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); - return mode; + pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn), + ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); + + switch (amd_config->flags & AMD_UDMA) { + case AMD_UDMA_33: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; + case AMD_UDMA_66: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; + case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; + default: return; + } + + pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t); } /* - * Here is where all the hard work goes to program the chipset. + * amd_set_drive() computes timing values configures the drive and + * the chipset to a desired transfer mode. It also can be called + * by upper layers. */ -static int amd74xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) + +static int amd_set_drive(ide_drive_t *drive, u8 speed) { - u8 drive_pci[] = { 0x53, 0x52, 0x51, 0x50 }; - u8 drive_pci2[] = { 0x4b, 0x4a, 0x49, 0x48 }; -#if 0 - u8 ultra_rate[] = { 0x42, 0x41, 0x40, 0x44, 0x45, 0x46 }; - u8 mwdma_rate[] = { 0x77, 0x21, 0x20 }; - u8 swdma_rate[] = { 0xA8, 0x65, 0x42 }; - u8 pio_rate[] = { 0xA8, 0x65, 0x42, 0x22, 0x20}; -#endif - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(amd74xx_ratemask(drive), xferspeed); - u8 ultra_timing = 0, dma_pio_timing = 0, pio_timing = 0; - - pci_read_config_byte(dev, drive_pci[drive->dn], &ultra_timing); - pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_pio_timing); - pci_read_config_byte(dev, 0x4c, &pio_timing); - - ultra_timing &= ~0xC7; - dma_pio_timing &= ~0xFF; - pio_timing &= ~(0x03 << drive->dn); - - switch(speed) { - case XFER_UDMA_7: - case XFER_UDMA_6: - speed = XFER_UDMA_5; - case XFER_UDMA_5: - ultra_timing |= 0x46; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_4: - ultra_timing |= 0x45; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_3: - ultra_timing |= 0x44; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_2: - ultra_timing |= 0x40; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_1: - ultra_timing |= 0x41; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_0: - ultra_timing |= 0x42; - dma_pio_timing |= 0x20; - break; - case XFER_MW_DMA_2: - dma_pio_timing |= 0x20; - break; - case XFER_MW_DMA_1: - dma_pio_timing |= 0x21; - break; - case XFER_MW_DMA_0: - dma_pio_timing |= 0x77; - break; - case XFER_SW_DMA_2: - dma_pio_timing |= 0x42; - break; - case XFER_SW_DMA_1: - dma_pio_timing |= 0x65; - break; - case XFER_SW_DMA_0: - dma_pio_timing |= 0xA8; - break; - case XFER_PIO_4: - dma_pio_timing |= 0x20; - break; - case XFER_PIO_3: - dma_pio_timing |= 0x22; - break; - case XFER_PIO_2: - dma_pio_timing |= 0x42; - break; - case XFER_PIO_1: - dma_pio_timing |= 0x65; - break; - case XFER_PIO_0: - default: - dma_pio_timing |= 0xA8; - break; - } + ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); + struct ide_timing t, p; + int T, UT; + + if (speed != XFER_PIO_SLOW && speed != drive->current_speed) + if (ide_config_drive_speed(drive, speed)) + printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n", + drive->dn >> 1, drive->dn & 1); - pio_timing |= (0x03 << drive->dn); + T = 1000000000 / amd_clock; + UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); - pci_write_config_byte(dev, drive_pci[drive->dn], ultra_timing); - pci_write_config_byte(dev, drive_pci2[drive->dn], dma_pio_timing); - pci_write_config_byte(dev, 0x4c, pio_timing); + ide_timing_compute(drive, speed, &t, T, UT); + + if (peer->present) { + ide_timing_compute(peer, peer->current_speed, &p, T, UT); + ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); + } - return (ide_config_drive_speed(drive, speed)); + if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; + + amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); + + if (!drive->init_speed) + drive->init_speed = speed; + drive->current_speed = speed; + + return 0; } -static void amd74xx_tune_drive (ide_drive_t *drive, u8 pio) +/* + * amd74xx_tune_drive() is a callback from upper layers for + * PIO-only tuning. + */ + +static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - (void) amd74xx_tune_chipset(drive, (XFER_PIO_0 + pio)); + if (!((amd_enabled >> HWIF(drive)->channel) & 1)) + return; + + if (pio == 255) { + amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); + return; + } + + amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); } /* - * This allows the configuration of ide_pci chipset registers - * for cards that learn about the drive's UDMA, DMA, PIO capabilities - * after the drive is reported by the OS. + * amd74xx_dmaproc() is a callback from upper layers that can do + * a lot, but we use it for DMA/PIO tuning only, delegating everything + * else to the default ide_dmaproc(). */ -static int config_chipset_for_dma (ide_drive_t *drive) + +static int amd74xx_ide_dma_check(ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, amd74xx_ratemask(drive)); + int w80 = HWIF(drive)->udma_four; + + u8 speed = ide_find_best_mode(drive, + XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | + ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | + (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | + (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0)); - if (!(speed)) - return 0; + amd_set_drive(drive, speed); - (void) amd74xx_tune_chipset(drive, speed); - return ide_dma_enable(drive); + if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) + return HWIF(drive)->ide_dma_on(drive); + return HWIF(drive)->ide_dma_off_quietly(drive); } -static int amd74xx_config_drive_xfer_rate (ide_drive_t *drive) +/* + * The initialization callback. Here we determine the IDE chip type + * and initialize its drive independent registers. + */ + +static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char *name) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; + unsigned char t; + unsigned int u; + int i; - drive->init_speed = 0; +/* + * Check for bad SWDMA. + */ - if (id && (id->capability & 1) && drive->autodma) { - /* Consult the list of known "bad" drives */ - if (hwif->ide_dma_bad_drive(drive)) - goto fast_ata_pio; - if (id->field_valid & 4) { - if (id->dma_ultra & hwif->ultra_mask) { - /* Force if Capable UltraDMA */ - int dma = config_chipset_for_dma(drive); - if ((id->field_valid & 2) && dma) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) { - /* Force if Capable regular DMA modes */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } + if (amd_config->flags & AMD_CHECK_SWDMA) { + pci_read_config_byte(dev, PCI_REVISION_ID, &t); + if (t <= 7) + amd_config->flags |= AMD_BAD_SWDMA; + } - } else if (hwif->ide_dma_good_drive(drive) && - (id->eide_dma_time < 150)) { - /* Consult the list of known "good" drives */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: -no_dma_set: - amd74xx_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); +/* + * Check 80-wire cable presence. + */ + + switch (amd_config->flags & AMD_UDMA) { + + case AMD_UDMA_100: + pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); + amd_80w = ((u & 0x3) ? 1 : 0) | ((u & 0xc) ? 2 : 0); + for (i = 24; i >= 0; i -= 8) + if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) { + printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits corectly. Enabling workaround.\n"); + amd_80w |= (1 << (1 - (i >> 4))); + } + break; + + case AMD_UDMA_66: + pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); + for (i = 24; i >= 0; i -= 8) + if ((u >> i) & 4) + amd_80w |= (1 << (1 - (i >> 4))); + break; } - return hwif->ide_dma_on(drive); -} -static unsigned int __init init_chipset_amd74xx (struct pci_dev *dev, const char *name) -{ - if (!amd74xx_swdma_check(dev)) - printk("%s: disabling single-word DMA support (revision < C4)\n", name); + pci_read_config_dword(dev, AMD_IDE_ENABLE, &u); + amd_enabled = ((u & 1) ? 2 : 0) | ((u & 2) ? 1 : 0); -#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) - if (!amd74xx_proc) { - amd74xx_proc = 1; - bmide_dev = dev; - ide_pci_register_host_proc(&amd74xx_procs[0]); +/* + * Take care of prefetch & postwrite. + */ + + pci_read_config_byte(dev, AMD_IDE_CONFIG, &t); + pci_write_config_byte(dev, AMD_IDE_CONFIG, + (amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0)); + +/* + * Determine the system bus clock. + */ + + amd_clock = system_bus_clock() * 1000; + + switch (amd_clock) { + case 33000: amd_clock = 33333; break; + case 37000: amd_clock = 37500; break; + case 41000: amd_clock = 41666; break; + } + + if (amd_clock < 20000 || amd_clock > 50000) { + printk(KERN_WARNING "AMD_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", amd_clock); + printk(KERN_WARNING "AMD_IDE: Use ide0=ata66 if you want to assume 80-wire cable\n"); + amd_clock = 33333; } -#endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */ + +/* + * Print the boot message. + */ + + pci_read_config_byte(dev, PCI_REVISION_ID, &t); + printk(KERN_INFO "AMD_IDE: %s (rev %02x) %s controller on pci%s\n", + dev->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name); + +/* + * Register /proc/ide/amd74xx entry + */ + +#if defined(DISPLAY_AMD_TIMINGS) && defined(CONFIG_PROC_FS) + if (!amd74xx_proc) { + amd_base = pci_resource_start(dev, 4); + bmide_dev = dev; + ide_pci_register_host_proc(&amd74xx_procs[0]); + amd74xx_proc = 1; + } +#endif /* DISPLAY_AMD_TIMINGS && CONFIG_PROC_FS */ + return 0; } -static unsigned int __init ata66_amd74xx (ide_hwif_t *hwif) +static unsigned int __init ata66_amd74xx(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; - u8 cable_80_pin[2] = { 0, 0 }; - u8 ata66 = 0; - u8 tmpbyte; - - /* - * Ultra66 cable detection (from Host View) - * 7411, 7441, 0x42, bit0: primary, bit2: secondary 80 pin - */ - pci_read_config_byte(dev, 0x42, &tmpbyte); - - /* - * 0x42, bit0 is 1 => primary channel - * has 80-pin (from host view) - */ - if (tmpbyte & 0x01) cable_80_pin[0] = 1; - - /* - * 0x42, bit2 is 1 => secondary channel - * has 80-pin (from host view) - */ - if (tmpbyte & 0x04) cable_80_pin[1] = 1; - - switch(dev->device) { - case PCI_DEVICE_ID_AMD_COBRA_7401: - cable_80_pin[hwif->channel] = 0; - return 0; - case PCI_DEVICE_ID_AMD_8111_IDE: - case PCI_DEVICE_ID_AMD_VIPER_7441: - case PCI_DEVICE_ID_AMD_VIPER_7411: - ata66 = (hwif->channel) ? - cable_80_pin[1] : - cable_80_pin[0]; - default: - break; - } - return (unsigned int) ata66; + return ((amd_enabled & amd_80w) >> hwif->channel) & 1; } -static void __init init_hwif_amd74xx (ide_hwif_t *hwif) +static void __init init_hwif_amd74xx(ide_hwif_t *hwif) { + int i; + hwif->autodma = 0; + hwif->tuneproc = &amd74xx_tune_drive; - hwif->speedproc = &amd74xx_tune_chipset; + hwif->speedproc = &amd_set_drive; - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; + for (i = 0; i < 2; i++) { + hwif->drives[i].io_32bit = 1; + hwif->drives[i].unmask = 1; + hwif->drives[i].autotune = 1; + hwif->drives[i].dn = hwif->channel * 2 + i; } - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x3f; - hwif->mwdma_mask = 0x07; - if (amd74xx_swdma_check(hwif->pci_dev)) - hwif->swdma_mask = 0x07; - - if (!(hwif->udma_four)) - hwif->udma_four = ata66_amd74xx(hwif); - hwif->ide_dma_check = &amd74xx_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static void __init init_dma_amd74xx (ide_hwif_t *hwif, unsigned long dmabase) -{ - if (!(hwif->channel)) - hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2); - ide_setup_dma(hwif, dmabase, 8); + if (!hwif->dma_base) + return; + + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; + + if (!(hwif->udma_four)) + hwif->udma_four = ((amd_enabled & amd_80w) >> hwif->channel) & 1; + hwif->ide_dma_check = &amd74xx_ide_dma_check; + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; } -extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); +/* + * We allow the BM-DMA driver only work on enabled interfaces. + */ +static void __init init_dma_amd74xx(ide_hwif_t *hwif, unsigned long dmabase) +{ + if ((amd_enabled >> hwif->channel) & 1) + ide_setup_dma(hwif, dmabase, 8); +} + +extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); -static int __devinit amd74xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) +static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &amd74xx_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); + ide_pci_device_t *d = amd74xx_chipsets + id->driver_data; + amd_config = amd_ide_chips + id->driver_data; + if (dev->device != d->device) BUG(); + if (dev->device != amd_config->id) BUG(); ide_setup_pci_device(dev, d); MOD_INC_USE_COUNT; return 0; @@ -396,13 +446,15 @@ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, { 0, }, }; static struct pci_driver driver = { .name = "AMD IDE", .id_table = amd74xx_pci_tbl, - .probe = amd74xx_init_one, + .probe = amd74xx_probe, }; static int amd74xx_ide_init(void) @@ -418,8 +470,8 @@ module_init(amd74xx_ide_init); module_exit(amd74xx_ide_exit); -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for AMD IDE"); +MODULE_AUTHOR("Vojtech Pavlik"); +MODULE_DESCRIPTION("AMD PCI IDE driver"); MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/amd74xx.h linux.21pre4-ac6/drivers/ide/pci/amd74xx.h --- linux.21pre4/drivers/ide/pci/amd74xx.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/amd74xx.h 2003-02-21 16:32:35.000000000 +0000 @@ -5,9 +5,9 @@ #include #include -#define DISPLAY_VIPER_TIMINGS +#define DISPLAY_AMD_TIMINGS -#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) +#if defined(DISPLAY_AMD_TIMINGS) && defined(CONFIG_PROC_FS) #include #include @@ -17,13 +17,13 @@ static ide_pci_host_proc_t amd74xx_procs[] __initdata = { { - name: "amd74xx", - set: 1, - get_info: amd74xx_get_info, - parent: NULL, + .name = "amd74xx", + .set = 1, + .get_info = amd74xx_get_info, + .parent = NULL, }, }; -#endif /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */ +#endif /* defined(DISPLAY_AMD_TIMINGS) && defined(CONFIG_PROC_FS) */ static unsigned int init_chipset_amd74xx(struct pci_dev *, const char *); static void init_hwif_amd74xx(ide_hwif_t *); @@ -31,75 +31,104 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { { /* 0 */ - vendor: PCI_VENDOR_ID_AMD, - device: PCI_DEVICE_ID_AMD_COBRA_7401, - name: "AMD7401", - init_chipset: init_chipset_amd74xx, - init_iops: NULL, - init_hwif: init_hwif_amd74xx, - init_dma: init_dma_amd74xx, - channels: 2, - autodma: AUTODMA, - enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0 + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_COBRA_7401, + .name = "AMD7401", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0 },{ /* 1 */ - vendor: PCI_VENDOR_ID_AMD, - device: PCI_DEVICE_ID_AMD_VIPER_7409, - name: "AMD7409", - init_chipset: init_chipset_amd74xx, - init_iops: NULL, - init_hwif: init_hwif_amd74xx, - init_dma: init_dma_amd74xx, - channels: 2, - autodma: AUTODMA, - enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0 + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_VIPER_7409, + .name = "AMD7409", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0 },{ /* 2 */ - vendor: PCI_VENDOR_ID_AMD, - device: PCI_DEVICE_ID_AMD_VIPER_7411, - name: "AMD7411", - init_chipset: init_chipset_amd74xx, - init_iops: NULL, - init_hwif: init_hwif_amd74xx, - init_dma: init_dma_amd74xx, - channels: 2, - autodma: AUTODMA, - enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0 + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_VIPER_7411, + .name = "AMD7411", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0 },{ /* 3 */ - vendor: PCI_VENDOR_ID_AMD, - device: PCI_DEVICE_ID_AMD_OPUS_7441, - name: "AMD7441", - init_chipset: init_chipset_amd74xx, - init_iops: NULL, - init_hwif: init_hwif_amd74xx, - init_dma: init_dma_amd74xx, - channels: 2, - autodma: AUTODMA, - enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0 + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_OPUS_7441, + .name = "AMD7441", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0 },{ /* 4 */ - vendor: PCI_VENDOR_ID_AMD, - device: PCI_DEVICE_ID_AMD_8111_IDE, - name: "AMD8111", - init_chipset: init_chipset_amd74xx, - init_iops: NULL, - init_hwif: init_hwif_amd74xx, - init_dma: init_dma_amd74xx, - autodma: AUTODMA, - channels: 2, - enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0 - },{ - vendor: 0, - device: 0, - channels: 0, - bootable: EOL, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_8111_IDE, + .name = "AMD8111", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .autodma = AUTODMA, + .channels = 2, + .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0 + }, + { /* 5 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, + .name = "NFORCE", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0, + }, + { /* 6 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, + .name = "NFORCE2", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0, + }, + { + .vendor = 0, + .device = 0, + .channels = 0, + .bootable = EOL, } }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/cmd640.c linux.21pre4-ac6/drivers/ide/pci/cmd640.c --- linux.21pre4/drivers/ide/pci/cmd640.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/cmd640.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/cmd640.c Version 1.02 Sep 01, 1996 + * linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996 * * Copyright (C) 1995-1996 Linus Torvalds & authors (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/cmd64x.c linux.21pre4-ac6/drivers/ide/pci/cmd64x.c --- linux.21pre4/drivers/ide/pci/cmd64x.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/cmd64x.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,6 +1,6 @@ /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 * - * linux/drivers/ide/cmd64x.c Version 1.30 Sept 10, 2002 + * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Note, this driver is not used at all on other systems because @@ -596,7 +596,7 @@ #ifdef __i386__ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } #endif @@ -604,7 +604,7 @@ case PCI_DEVICE_ID_CMD_643: break; case PCI_DEVICE_ID_CMD_646: - printk("%s: chipset revision 0x%02X, ", name, class_rev); + printk(KERN_INFO "%s: chipset revision 0x%02X, ", name, class_rev); switch(class_rev) { case 0x07: case 0x05: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/cs5530.c linux.21pre4-ac6/drivers/ide/pci/cs5530.c --- linux.21pre4/drivers/ide/pci/cs5530.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/cs5530.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/cs5530.c Version 0.7 Sept 10, 2002 + * linux/drivers/ide/pci/cs5530.c Version 0.7 Sept 10, 2002 * * Copyright (C) 2000 Andre Hedrick * Ditto of GNU General Public License. @@ -9,6 +9,9 @@ * * Development of this chipset driver was funded * by the nice folks at National Semiconductor. + * + * Documentation: + * CS5530 documentation available from National Semiconductor. */ #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/cy82c693.c linux.21pre4-ac6/drivers/ide/pci/cy82c693.c --- linux.21pre4/drivers/ide/pci/cy82c693.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/cy82c693.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/cy82c693.c Version 0.40 Sep. 10, 2002 + * linux/drivers/ide/pci/cy82c693.c Version 0.40 Sep. 10, 2002 * * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-2002 Andre Hedrick , Integrater @@ -335,7 +335,7 @@ /* * this function is called during init and is used to setup the cy82c693 chip */ -unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name) +static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name) { if (PCI_FUNC(dev->devfn) != 1) return 0; @@ -387,7 +387,7 @@ /* * the init function - called for each ide channel once */ -void __init init_hwif_cy82c693(ide_hwif_t *hwif) +static void __init init_hwif_cy82c693(ide_hwif_t *hwif) { hwif->autodma = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/cy82c693.h linux.21pre4-ac6/drivers/ide/pci/cy82c693.h --- linux.21pre4/drivers/ide/pci/cy82c693.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/cy82c693.h 2003-02-21 16:32:35.000000000 +0000 @@ -64,9 +64,9 @@ u8 time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ } pio_clocks_t; -extern unsigned int init_chipset_cy82c693(struct pci_dev *, const char *); -extern void init_hwif_cy82c693(ide_hwif_t *); -extern void init_iops_cy82c693(ide_hwif_t *); +static unsigned int init_chipset_cy82c693(struct pci_dev *, const char *); +static void init_hwif_cy82c693(ide_hwif_t *); +static void init_iops_cy82c693(ide_hwif_t *); static ide_pci_device_t cy82c693_chipsets[] __devinitdata = { { /* 0 */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/generic.c linux.21pre4-ac6/drivers/ide/pci/generic.c --- linux.21pre4/drivers/ide/pci/generic.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/generic.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/generic.c Version 0.11 December 30, 2002 + * linux/drivers/ide/pci/generic.c Version 0.11 December 30, 2002 * * Copyright (C) 2001-2002 Andre Hedrick * Portions (C) Copyright 2002 Red Hat Inc diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/hpt34x.c linux.21pre4-ac6/drivers/ide/pci/hpt34x.c --- linux.21pre4/drivers/ide/pci/hpt34x.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/hpt34x.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/hpt34x.c Version 0.40 Sept 10, 2002 + * linux/drivers/ide/pci/hpt34x.c Version 0.40 Sept 10, 2002 * * Copyright (C) 1998-2000 Andre Hedrick * May be copied or modified under the terms of the GNU General Public License diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/hpt366.c linux.21pre4-ac6/drivers/ide/pci/hpt366.c --- linux.21pre4/drivers/ide/pci/hpt366.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/hpt366.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/hpt366.c Version 0.34 Sept 17, 2002 + * linux/drivers/ide/pci/hpt366.c Version 0.34 Sept 17, 2002 * * Copyright (C) 1999-2002 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -807,7 +807,7 @@ } else if (freq < 0xc8) { pll = F_LOW_PCI_50; if (hpt_minimum_revision(dev,8)) - return -EOPNOTSUPP; + pci_set_drvdata(dev, NULL); else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) fifty_base_hpt372); else if (hpt_minimum_revision(dev,4)) @@ -820,7 +820,7 @@ if (hpt_minimum_revision(dev,8)) { printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n"); - return -EOPNOTSUPP; + pci_set_drvdata(dev, NULL); } else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) sixty_six_base_hpt372); @@ -923,7 +923,7 @@ if (!pci_get_drvdata(dev)) { printk(KERN_ERR "hpt366: unknown bus timing.\n"); - return -EOPNOTSUPP; + pci_set_drvdata(dev, NULL); } return 0; } @@ -1061,6 +1061,12 @@ if (!dmabase) return; + + if(pci_get_drvdata(hwif->pci_dev) == NULL) + { + printk(KERN_WARNING "hpt: no known IDE timings, disabling DMA.\n"); + return; + } dma_old = hwif->INB(dmabase+2); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/Makefile linux.21pre4-ac6/drivers/ide/pci/Makefile --- linux.21pre4/drivers/ide/pci/Makefile 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/Makefile 2003-02-05 17:40:00.000000000 +0000 @@ -18,7 +18,6 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o -obj-$(CONFIG_BLK_DEV_NFORCE) += nvidia.o obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o obj-$(CONFIG_BLK_DEV_PDC202XX_NEW) += pdc202xx_new.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/ns87415.c linux.21pre4-ac6/drivers/ide/pci/ns87415.c --- linux.21pre4/drivers/ide/pci/ns87415.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/ns87415.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ns87415.c Version 2.00 Sep. 10, 2002 + * linux/drivers/ide/pci/ns87415.c Version 2.00 Sep. 10, 2002 * * Copyright (C) 1997-1998 Mark Lord * Copyright (C) 1998 Eddie C. Dost diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/nvidia.c linux.21pre4-ac6/drivers/ide/pci/nvidia.c --- linux.21pre4/drivers/ide/pci/nvidia.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/nvidia.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,373 +0,0 @@ -/* - * linux/drivers/ide/nvidia.c Version 0.01 - * - * Copyright (C) 2002-2002 Andre Hedrick - * May be copied or modified under the terms of the GNU General Public License - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "ide_modes.h" -#include "nvidia.h" - -#if defined(DISPLAY_NFORCE_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include - -static u8 nforce_proc = 0; -static struct pci_dev *bmide_dev; - -static int nforce_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - u32 bibma = pci_resource_start(bmide_dev, 4); - u8 c0 = 0, c1 = 0; - - /* - * at that point bibma+0x2 et bibma+0xa are byte registers - * to investigate: - */ - c0 = inb((unsigned short)bibma + 0x02); - c1 = inb((unsigned short)bibma + 0x0a); - - p += sprintf(p, "\n " - "nVidia %04X Chipset.\n", bmide_dev->device); - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - p += sprintf(p, " %sabled " - " %sabled\n", - (c0&0x80) ? "dis" : " en", - (c1&0x80) ? "dis" : " en"); - p += sprintf(p, "--------------- drive0 --------- drive1 " - "-------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s " - " %s %s\n", - (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ", - (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " ); - p += sprintf(p, "UDMA\n"); - p += sprintf(p, "DMA\n"); - p += sprintf(p, "PIO\n"); - - return p-buffer; /* => must be less than 4k! */ -} -#endif /* defined(DISPLAY_NFORCE_TIMINGS) && defined(CONFIG_PROC_FS) */ - -static u8 nforce_ratemask (ide_drive_t *drive) -{ - u8 mode; - - switch(HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_NVIDIA_NFORCE_IDE: - case PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE: - mode = 3; - break; - default: - return 0; - } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/* - * Here is where all the hard work goes to program the chipset. - */ -static int nforce_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - static const u8 drive_pci[] = { 0x63, 0x62, 0x61, 0x60 }; - static const u8 drive_pci2[] = { 0x5b, 0x5a, 0x59, 0x58 }; - - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(nforce_ratemask(drive), xferspeed); - u8 ultra_timing = 0, dma_pio_timing = 0, pio_timing = 0; - - pci_read_config_byte(dev, drive_pci[drive->dn], &ultra_timing); - pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_pio_timing); - pci_read_config_byte(dev, 0x5c, &pio_timing); - - ultra_timing &= ~0xC7; - dma_pio_timing &= ~0xFF; - pio_timing &= ~(0x03 << drive->dn); - - switch(speed) { - case XFER_UDMA_7: - case XFER_UDMA_6: - speed = XFER_UDMA_5; - case XFER_UDMA_5: - ultra_timing |= 0x46; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_4: - ultra_timing |= 0x45; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_3: - ultra_timing |= 0x44; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_2: - ultra_timing |= 0x40; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_1: - ultra_timing |= 0x41; - dma_pio_timing |= 0x20; - break; - case XFER_UDMA_0: - ultra_timing |= 0x42; - dma_pio_timing |= 0x20; - break; - case XFER_MW_DMA_2: - dma_pio_timing |= 0x20; - break; - case XFER_MW_DMA_1: - dma_pio_timing |= 0x21; - break; - case XFER_MW_DMA_0: - dma_pio_timing |= 0x77; - break; - case XFER_SW_DMA_2: - dma_pio_timing |= 0x42; - break; - case XFER_SW_DMA_1: - dma_pio_timing |= 0x65; - break; - case XFER_SW_DMA_0: - dma_pio_timing |= 0xA8; - break; - case XFER_PIO_4: - dma_pio_timing |= 0x20; - break; - case XFER_PIO_3: - dma_pio_timing |= 0x22; - break; - case XFER_PIO_2: - dma_pio_timing |= 0x42; - break; - case XFER_PIO_1: - dma_pio_timing |= 0x65; - break; - case XFER_PIO_0: - default: - dma_pio_timing |= 0xA8; - break; - } - - pio_timing |= (0x03 << drive->dn); - - pci_write_config_byte(dev, drive_pci[drive->dn], ultra_timing); - pci_write_config_byte(dev, drive_pci2[drive->dn], dma_pio_timing); - pci_write_config_byte(dev, 0x5c, pio_timing); - - return (ide_config_drive_speed(drive, speed)); -} - -static void nforce_tune_drive (ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - (void) nforce_tune_chipset(drive, (XFER_PIO_0 + pio)); -} - -/* - * This allows the configuration of ide_pci chipset registers - * for cards that learn about the drive's UDMA, DMA, PIO capabilities - * after the drive is reported by the OS. - */ -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, nforce_ratemask(drive)); - - if (!(speed)) - return 0; - - (void) nforce_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int nforce_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - /* Consult the list of known "bad" drives */ - if (hwif->ide_dma_bad_drive(drive)) - goto fast_ata_pio; - if (id->field_valid & 4) { - if (id->dma_ultra & hwif->ultra_mask) { - /* Force if Capable UltraDMA */ - int dma = config_chipset_for_dma(drive); - if ((id->field_valid & 2) && !dma) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) { - /* Force if Capable regular DMA modes */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } - - } else if (hwif->ide_dma_good_drive(drive) && - (id->eide_dma_time < 150)) { - /* Consult the list of known "good" drives */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: -no_dma_set: - nforce_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - return hwif->ide_dma_on(drive); -} - -static unsigned int __init init_chipset_nforce (struct pci_dev *dev, const char *name) -{ -#if defined(DISPLAY_NFORCE_TIMINGS) && defined(CONFIG_PROC_FS) - if (!nforce_proc) { - nforce_proc = 1; - bmide_dev = dev; - ide_pci_register_host_proc(&nforce_procs[0]); - } -#endif /* DISPLAY_NFORCE_TIMINGS && CONFIG_PROC_FS */ - return 0; -} - -static unsigned int __init ata66_nforce (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - u8 cable_80_pin[2] = { 0, 0 }; - u8 ata66 = 0; - u8 tmpbyte; - - /* - * Ultra66 cable detection (from Host View) - * 7411, 7441, 0x52, bit0: primary, bit2: secondary 80 pin - */ - pci_read_config_byte(dev, 0x52, &tmpbyte); - - /* - * 0x52, bit0 is 1 => primary channel - * has 80-pin (from host view) - */ - if (tmpbyte & 0x01) cable_80_pin[0] = 1; - - /* - * 0x52, bit2 is 1 => secondary channel - * has 80-pin (from host view) - */ - if (tmpbyte & 0x04) cable_80_pin[1] = 1; - - switch(dev->device) { - case PCI_DEVICE_ID_NVIDIA_NFORCE_IDE: - case PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE: - ata66 = (hwif->channel) ? - cable_80_pin[1] : - cable_80_pin[0]; - default: - break; - } - return (unsigned int) ata66; -} - -static void __init init_hwif_nforce (ide_hwif_t *hwif) -{ - hwif->tuneproc = &nforce_tune_drive; - hwif->speedproc = &nforce_tune_chipset; - hwif->autodma = 0; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x3f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!(hwif->udma_four)) - hwif->udma_four = ata66_nforce(hwif); - hwif->ide_dma_check = &nforce_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -/* FIXME - not needed */ -static void __init init_dma_nforce (ide_hwif_t *hwif, unsigned long dmabase) -{ - ide_setup_dma(hwif, dmabase, 8); -} - -extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); - -static int __devinit nforce_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &nvidia_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); - MOD_INC_USE_COUNT; - return 0; -} - -static struct pci_device_id nforce_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { 0, }, -}; - -static struct pci_driver driver = { - .name = "nForce IDE", - .id_table = nforce_pci_tbl, - .probe = nforce_init_one, -}; - -static int nforce_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -static void nforce_ide_exit(void) -{ - ide_pci_unregister_driver(&driver); -} - -module_init(nforce_ide_init); -module_exit(nforce_ide_exit); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for nVidia nForce IDE"); -MODULE_LICENSE("GPL"); - -EXPORT_NO_SYMBOLS; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/nvidia.h linux.21pre4-ac6/drivers/ide/pci/nvidia.h --- linux.21pre4/drivers/ide/pci/nvidia.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/nvidia.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,65 +0,0 @@ -#ifndef NFORCE_H -#define NFORCE_H - -#include -#include -#include - -#define DISPLAY_NFORCE_TIMINGS - -#if defined(DISPLAY_NFORCE_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include - -static u8 nforce_proc; - -static int nforce_get_info(char *, char **, off_t, int); - -static ide_pci_host_proc_t nforce_procs[] __initdata = { - { - name: "nforce", - set: 1, - get_info: nforce_get_info, - parent: NULL, - }, -}; -#endif /* defined(DISPLAY_NFORCE_TIMINGS) && defined(CONFIG_PROC_FS) */ - -static unsigned int init_chipset_nforce(struct pci_dev *, const char *); -static void init_hwif_nforce(ide_hwif_t *); -static void init_dma_nforce(ide_hwif_t *, unsigned long); - -static ide_pci_device_t nvidia_chipsets[] __devinitdata = { - { - vendor: PCI_VENDOR_ID_NVIDIA, - device: PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, - name: "NFORCE", - init_chipset: init_chipset_nforce, - init_iops: NULL, - init_hwif: init_hwif_nforce, - init_dma: init_dma_nforce, - channels: 2, - autodma: AUTODMA, - enablebits: {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0, - }, - - { - vendor: PCI_VENDOR_ID_NVIDIA, - device: PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, - name: "NFORCE2", - init_chipset: init_chipset_nforce, - init_iops: NULL, - init_hwif: init_hwif_nforce, - init_dma: init_dma_nforce, - channels: 2, - autodma: AUTODMA, - enablebits: {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, - bootable: ON_BOARD, - extra: 0, - } -}; - - -#endif /* NFORCE_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/opti621.c linux.21pre4-ac6/drivers/ide/pci/opti621.c --- linux.21pre4/drivers/ide/pci/opti621.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/opti621.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/opti621.c Version 0.7 Sept 10, 2002 + * linux/drivers/ide/pci/opti621.c Version 0.7 Sept 10, 2002 * * Copyright (C) 1996-1998 Linus Torvalds & authors (see below) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/pdc202xx_new.c linux.21pre4-ac6/drivers/ide/pci/pdc202xx_new.c --- linux.21pre4/drivers/ide/pci/pdc202xx_new.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/pdc202xx_new.c 2003-02-11 01:40:48.000000000 +0000 @@ -224,7 +224,7 @@ decode_registers(REG_D, DP); #endif /* PDC202XX_DECODE_REGISTER_INFO */ #if PDC202XX_DEBUG_DRIVE_INFO - printk("%s: %s drive%d 0x%08x ", + printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", drive->name, ide_xfer_verbose(speed), drive->dn, drive_conf); pci_read_config_dword(dev, drive_pci, &drive_conf); @@ -321,7 +321,7 @@ case PCI_DEVICE_ID_PROMISE_20268: cable = pdcnew_new_cable_detect(hwif); #if PDC202_DEBUG_CABLE - printk("%s: %s-pin cable, %s-pin cable, %d\n", + printk(KERN_DEBUG "%s: %s-pin cable, %s-pin cable, %d\n", hwif->name, hwif->udma_four ? "80" : "40", cable ? "40" : "80", cable); #endif /* PDC202_DEBUG_CABLE */ @@ -347,15 +347,15 @@ if ((ultra_66) && (cable)) { #ifdef DEBUG - printk("ULTRA 66/100/133: %s channel of Ultra 66/100/133 " + printk(KERN_DEBUG "ULTRA 66/100/133: %s channel of Ultra 66/100/133 " "requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary"); - printk(" Switching to Ultra33 mode.\n"); + printk(KERN_DEBUG " Switching to Ultra33 mode.\n"); #endif /* DEBUG */ /* Primary : zero out second bit */ /* Secondary : zero out fourth bit */ - printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); - printk("%s reduced to Ultra33 mode.\n", drive->name); + printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); + printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); } if (drive->media != ide_disk) @@ -444,7 +444,7 @@ /* * Deleted this because it is redundant from the caller. */ - printk("PDC202XX: %s channel reset.\n", + printk(KERN_WARNING "PDC202XX: %s channel reset.\n", HWIF(drive)->channel ? "Secondary" : "Primary"); } @@ -459,7 +459,7 @@ hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f)); mdelay(2000); /* 2 seconds ?! */ - printk("PDC202XX: %s channel reset.\n", + printk(KERN_WARNING "PDC202XX: %s channel reset.\n", hwif->channel ? "Secondary" : "Primary"); } @@ -513,7 +513,7 @@ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled at 0x%08lx\n", + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } @@ -555,7 +555,7 @@ hwif->autodma = 1; hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; #if PDC202_DEBUG_CABLE - printk("%s: %s-pin cable\n", + printk(KERN_DEBUG "%s: %s-pin cable\n", hwif->name, hwif->udma_four ? "80" : "40"); #endif /* PDC202_DEBUG_CABLE */ } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/pdc202xx_old.c linux.21pre4-ac6/drivers/ide/pci/pdc202xx_old.c --- linux.21pre4/drivers/ide/pci/pdc202xx_old.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/pdc202xx_old.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pdc202xx.c Version 0.36 Sept 11, 2002 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 * * Copyright (C) 1998-2002 Andre Hedrick * @@ -323,7 +323,7 @@ decode_registers(REG_D, DP); #endif /* PDC202XX_DECODE_REGISTER_INFO */ #if PDC202XX_DEBUG_DRIVE_INFO - printk("%s: %s drive%d 0x%08x ", + printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", drive->name, ide_xfer_verbose(speed), drive->dn, drive_conf); pci_read_config_dword(dev, drive_pci, &drive_conf); @@ -379,7 +379,7 @@ case PCI_DEVICE_ID_PROMISE_20262: cable = pdc202xx_old_cable_detect(hwif); #if PDC202_DEBUG_CABLE - printk("%s: %s-pin cable, %s-pin cable, %d\n", + printk(KERN_DEBUG "%s: %s-pin cable, %s-pin cable, %d\n", hwif->name, hwif->udma_four ? "80" : "40", cable ? "40" : "80", cable); #endif /* PDC202_DEBUG_CABLE */ @@ -408,16 +408,16 @@ if ((ultra_66) && (cable)) { #ifdef DEBUG - printk("ULTRA 66/100/133: %s channel of Ultra 66/100/133 " + printk(KERN_DEBUG "ULTRA 66/100/133: %s channel of Ultra 66/100/133 " "requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary"); - printk(" Switching to Ultra33 mode.\n"); + printk(KERN_DEBUG " Switching to Ultra33 mode.\n"); #endif /* DEBUG */ /* Primary : zero out second bit */ /* Secondary : zero out fourth bit */ hwif->OUTB(CLKSPD & ~mask, (hwif->dma_master + 0x11)); - printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); - printk("%s reduced to Ultra33 mode.\n", drive->name); + printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); + printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); } else { if (ultra_66) { /* @@ -620,7 +620,7 @@ hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f)); mdelay(2000); /* 2 seconds ?! */ - printk("PDC202XX: %s channel reset.\n", + printk(KERN_WARNING "PDC202XX: %s channel reset.\n", hwif->channel ? "Secondary" : "Primary"); } @@ -699,7 +699,7 @@ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled at 0x%08lx\n", + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } @@ -780,7 +780,7 @@ hwif->autodma = 1; hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; #if PDC202_DEBUG_CABLE - printk("%s: %s-pin cable\n", + printk(KERN_DEBUG "%s: %s-pin cable\n", hwif->name, hwif->udma_four ? "80" : "40"); #endif /* PDC202_DEBUG_CABLE */ } @@ -797,7 +797,7 @@ udma_speed_flag = hwif->INB((dmabase|0x1f)); primary_mode = hwif->INB((dmabase|0x1a)); secondary_mode = hwif->INB((dmabase|0x1b)); - printk("%s: (U)DMA Burst Bit %sABLED " \ + printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \ "Primary %s Mode " \ "Secondary %s Mode.\n", hwif->cds->name, (udma_speed_flag & 1) ? "EN" : "DIS", @@ -806,7 +806,7 @@ #ifdef CONFIG_PDC202XX_BURST if (!(udma_speed_flag & 1)) { - printk("%s: FORCING BURST BIT 0x%02x->0x%02x ", + printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ", hwif->cds->name, udma_speed_flag, (udma_speed_flag|1)); hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f)); @@ -816,7 +816,7 @@ #endif /* CONFIG_PDC202XX_BURST */ #ifdef CONFIG_PDC202XX_MASTER if (!(primary_mode & 1)) { - printk("%s: FORCING PRIMARY MODE BIT " + printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT " "0x%02x -> 0x%02x ", hwif->cds->name, primary_mode, (primary_mode|1)); hwif->OUTB(primary_mode|1, (dmabase|0x1a)); @@ -825,7 +825,7 @@ } if (!(secondary_mode & 1)) { - printk("%s: FORCING SECONDARY MODE BIT " + printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT " "0x%02x -> 0x%02x ", hwif->cds->name, secondary_mode, (secondary_mode|1)); hwif->OUTB(secondary_mode|1, (dmabase|0x1b)); @@ -850,7 +850,7 @@ if (irq != irq2) { pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ - printk("%s: pci-config space interrupt " + printk(KERN_INFO "%s: pci-config space interrupt " "mirror fixed.\n", d->name); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/pdcadma.c linux.21pre4-ac6/drivers/ide/pci/pdcadma.c --- linux.21pre4/drivers/ide/pci/pdcadma.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/pdcadma.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pdcadma.c Version 0.05 Sept 10, 2002 + * linux/drivers/ide/pci/pdcadma.c Version 0.05 Sept 10, 2002 * * Copyright (C) 1999-2000 Andre Hedrick * May be copied or modified under the terms of the GNU General Public License diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/piix.c linux.21pre4-ac6/drivers/ide/pci/piix.c --- linux.21pre4/drivers/ide/pci/piix.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/piix.c 2003-02-21 15:43:35.000000000 +0000 @@ -1,8 +1,10 @@ /* - * linux/drivers/ide/piix.c Version 0.40 August 18, 2002 + * linux/drivers/ide/pci/piix.c Version 0.42 January 11, 2003 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick + * Copyright (C) 2003 Red Hat Inc + * * May be copied or modified under the terms of the GNU General Public License * * PIO mode setting function for Intel chipsets. @@ -51,6 +53,41 @@ * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, ®4a); * pci_read_config_word(HWIF(drive)->pci_dev, 0x54, ®54); * + * Documentation + * Publically available from Intel web site. Errata documentation + * is also publically available. As an aide to anyone hacking on this + * driver the list of errata that are relevant is below.going back to + * PIIX4. Older device documentation is now a bit tricky to find. + * + * Errata of note: + * + * Unfixable + * PIIX4 errata #9 - Only on ultra obscure hw + * ICH3 errata #13 - Not observed to affect real hw + * by Intel + * + * Things we must deal with + * PIIX4 errata #10 - BM IDE hang with non UDMA + * (must stop/start dma to recover) + * 440MX errata #15 - As PIIX4 errata #10 + * PIIX4 errata #15 - Must not read control registers + * during a PIO transfer + * 440MX errata #13 - As PIIX4 errata #15 + * ICH2 errata #21 - DMA mode 0 doesn't work right + * ICH0/1 errata #55 - As ICH2 errata #21 + * ICH2 spec c #9 - Extra operations needed to handle + * drive hotswap [NOT YET SUPPORTED] + * ICH2 spec c #20 - IDE PRD must not cross a 64K boundary + * and must be dword aligned + * ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3 + * + * Should have been BIOS fixed: + * 450NX: errata #19 - DMA hangs on old 450NX + * 450NX: errata #20 - DMA hangs on old 450NX + * 450NX: errata #25 - Corruption with DMA on old 450NX + * ICH3 errata #15 - IDE deadlock under high load + * (BIOS must set dev 31 fn 0 bit 23) + * ICH3 errata #18 - Don't use native mode */ #include @@ -77,6 +114,7 @@ #define PIIX_MAX_DEVS 5 static struct pci_dev *piix_devs[PIIX_MAX_DEVS]; static int n_piix_devs; +static int no_piix_dma = 0; /** * piix_get_info - fill in /proc for PIIX ide @@ -109,6 +147,7 @@ case PCI_DEVICE_ID_INTEL_82801CA_10: case PCI_DEVICE_ID_INTEL_82801CA_11: case PCI_DEVICE_ID_INTEL_82801DB_11: + case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_82801E_11: p += sprintf(p, "PIIX4 Ultra 100 "); break; @@ -242,6 +281,7 @@ case PCI_DEVICE_ID_INTEL_82801CA_11: case PCI_DEVICE_ID_INTEL_82801E_11: case PCI_DEVICE_ID_INTEL_82801DB_11: + case PCI_DEVICE_ID_INTEL_82801EB_11: mode = 3; break; /* UDMA 66 capable */ @@ -443,6 +483,33 @@ } /** + * piix_faulty_dma0 - check for DMA0 errata + * @hwif: IDE interface to check + * + * If an ICH/ICH0/ICH2 interface is is operating in multi-word + * DMA mode with 600nS cycle time the IDE PIO prefetch buffer will + * inadvertently provide an extra piece of secondary data to the primary + * device resulting in data corruption. + * + * With such a device this test function returns true. This allows + * our tuning code to follow Intel recommendations and use PIO on + * such devices. + */ + +static int piix_faulty_dma0(ide_hwif_t *hwif) +{ + switch(hwif->pci_dev->device) + { + case PCI_DEVICE_ID_INTEL_82801AA_1: /* ICH */ + case PCI_DEVICE_ID_INTEL_82801AB_1: /* ICH0 */ + case PCI_DEVICE_ID_INTEL_82801BA_8: /* ICH2 */ + case PCI_DEVICE_ID_INTEL_82801BA_9: /* ICH2 */ + return 1; + } + return 0; +} + +/** * piix_config_drive_for_dma - configure drive for DMA * @drive: IDE drive to configure * @@ -454,8 +521,15 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, piix_ratemask(drive)); - - if (!(speed)) { + + /* Some ICH devices cannot support DMA mode 0 */ + if(speed == XFER_MW_DMA_0 && piix_faulty_dma0(HWIF(drive))) + speed = 0; + + /* If no DMA speed was available or the chipset has DMA bugs + then disable DMA and use PIO */ + + if (!speed || no_piix_dma) { u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); speed = piix_dma_2_pio(XFER_PIO_0 + tspeed); } @@ -534,6 +608,7 @@ case PCI_DEVICE_ID_INTEL_82801CA_10: case PCI_DEVICE_ID_INTEL_82801CA_11: case PCI_DEVICE_ID_INTEL_82801DB_11: + case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_82801E_11: { unsigned int extra = 0; @@ -675,6 +750,37 @@ return 0; } +/** + * piix_check_450nx - Check for problem 450NX setup + * + * Check for the present of 450NX errata #19 and errata #25. If + * they are found, disable use of DMA IDE + */ + +static void __init piix_check_450nx(void) +{ + struct pci_dev *pdev = NULL; + u16 cfg; + u8 rev; + while((pdev=pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL) + { + /* Look for 450NX PXB. Check for problem configurations + A PCI quirk checks bit 6 already */ + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); + pci_read_config_word(pdev, 0x41, &cfg); + /* Only on the original revision: IDE DMA can hang */ + if(rev == 0x00) + no_piix_dma = 1; + /* On all revisions PXB bus lock must be disabled for IDE */ + else if(cfg & (1<<14)) + no_piix_dma = 2; + } + if(no_piix_dma) + printk(KERN_WARNING "piix: 450NX errata present, disabling IDE DMA.\n"); + if(no_piix_dma == 2) + printk(KERN_WARNING "piix: A BIOS update may resolve this.\n"); +} + static struct pci_device_id piix_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, @@ -691,7 +797,8 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, { 0, }, }; @@ -703,6 +810,7 @@ static int piix_ide_init(void) { + piix_check_450nx(); return ide_pci_register_driver(&driver); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/piix.h linux.21pre4-ac6/drivers/ide/pci/piix.h --- linux.21pre4/drivers/ide/pci/piix.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/piix.h 2003-02-21 16:32:35.000000000 +0000 @@ -251,6 +251,20 @@ .extra = 0, },{ /* 15 */ .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801EB_11, + .name = "ICH5", + .init_setup = init_setup_piix, + .init_chipset = init_chipset_piix, + .init_iops = NULL, + .init_hwif = init_hwif_piix, + .init_dma = init_dma_piix, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, + .bootable = ON_BOARD, + .extra = 0, + },{ /* 16 */ + .vendor = PCI_VENDOR_ID_INTEL, .device = PCI_DEVICE_ID_INTEL_82801E_11, .name = "C-ICH", .init_setup = init_setup_piix, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/rz1000.c linux.21pre4-ac6/drivers/ide/pci/rz1000.c --- linux.21pre4/drivers/ide/pci/rz1000.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/rz1000.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/rz1000.c Version 0.05 December 8, 1997 + * linux/drivers/ide/pci/rz1000.c Version 0.06 January 12, 2003 * * Copyright (C) 1995-1998 Linus Torvalds & author (see below) */ @@ -43,13 +43,13 @@ hwif->chipset = ide_rz1000; if (!pci_read_config_word (dev, 0x40, ®) && !pci_write_config_word(dev, 0x40, reg & 0xdfff)) { - printk("%s: disabled chipset read-ahead " + printk(KERN_INFO "%s: disabled chipset read-ahead " "(buggy RZ1000/RZ1001)\n", hwif->name); } else { hwif->serialized = 1; hwif->drives[0].no_unmask = 1; hwif->drives[1].no_unmask = 1; - printk("%s: serialized, disabled unmasking " + printk(KERN_INFO "%s: serialized, disabled unmasking " "(buggy RZ1000/RZ1001)\n", hwif->name); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/sc1200.c linux.21pre4-ac6/drivers/ide/pci/sc1200.c --- linux.21pre4/drivers/ide/pci/sc1200.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/sc1200.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,11 +1,14 @@ /* - * linux/drivers/ide/sc1200.c Version 0.9 24-Oct-2002 + * linux/drivers/ide/pci/sc1200.c Version 0.91 28-Jan-2003 * * Copyright (C) 2000-2002 Mark Lord * May be copied or modified under the terms of the GNU General Public License * * Development of this chipset driver was funded * by the nice folks at National Semiconductor. + * + * Documentation: + * Available from National Semiconductor */ #include @@ -427,8 +430,6 @@ static int sc1200_suspend (struct pci_dev *dev, u32 state) { - ide_hwif_t *hwif = NULL; - printk("SC1200: suspend(%u)\n", state); /* You don't need to iterate over disks -- sysfs should have done that for you already */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/serverworks.c linux.21pre4-ac6/drivers/ide/pci/serverworks.c --- linux.21pre4/drivers/ide/pci/serverworks.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/serverworks.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/serverworks.c Version 0.7 10 Sept 2002 + * linux/drivers/ide/pci/serverworks.c Version 0.7 10 Sept 2002 * * Copyright (C) 1998-2000 Michel Aubry * Copyright (C) 1998-2000 Andrzej Krzysztofowicz @@ -21,6 +21,9 @@ * * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) * + * Documentation: + * Available under NDA only. Errata info very hard to get. + * */ #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/siimage.c linux.21pre4-ac6/drivers/ide/pci/siimage.c --- linux.21pre4/drivers/ide/pci/siimage.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/siimage.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/siimage.c Version 1.01 Sept 11, 2002 + * linux/drivers/ide/pci/siimage.c Version 1.02 Jan 30, 2003 * * Copyright (C) 2001-2002 Andre Hedrick */ @@ -248,9 +248,9 @@ { u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); - config_chipset_for_pio(drive, (!(speed))); + config_chipset_for_pio(drive, !speed); - if ((!(speed))) + if (!speed) return 0; if (ide_set_xfer_rate(drive, speed)) @@ -267,7 +267,7 @@ ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { + if (id != NULL && (id->capability & 1) != 0 && drive->autodma) { if (!(hwif->atapi_dma)) goto fast_ata_pio; /* Consult the list of known "bad" drives */ @@ -317,10 +317,9 @@ return 1; /* return 1 if Device INTR asserted */ - if ((pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat)), - ((dma_altstat & 8) == 8)) + pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat); + if (dma_altstat & 8) return 0; //return 1; - return 0; } @@ -355,7 +354,7 @@ hwif->OUTL(sata_error, SATA_ERROR_REG); watchdog = (sata_error & 0x00680000) ? 1 : 0; #if 1 - printk("%s: sata_error = 0x%08x, " + printk(KERN_WARNING "%s: sata_error = 0x%08x, " "watchdog = %d, %s\n", drive->name, sata_error, watchdog, __FUNCTION__); @@ -426,7 +425,7 @@ ide_hwif_t *hwif = HWIF(drive); if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) { - printk("%s: reset phy dead, status=0x%08x\n", + printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", hwif->name, hwif->INL(SATA_STATUS_REG)); HWGROUP(drive)->poll_timeout = 0; #if 0 @@ -475,10 +474,10 @@ if (SATA_STATUS_REG) { u32 sata_stat = hwif->INL(SATA_STATUS_REG); - printk("%s: reset phy, status=0x%08x, %s\n", + printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n", hwif->name, sata_stat, __FUNCTION__); if (!(sata_stat)) { - printk("%s: reset phy dead, status=0x%08x\n", + printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", hwif->name, sata_stat); drive->failures++; } @@ -491,7 +490,7 @@ if (dev->device == PCI_DEVICE_ID_SII_3112) goto sata_skip; - printk("%s: BASE CLOCK ", name); + printk(KERN_INFO "%s: BASE CLOCK ", name); clocking &= ~0x0C; switch(clocking) { case 0x03: printk("DISABLED !\n"); break; @@ -514,7 +513,6 @@ #endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */ } -#ifdef CONFIG_TRY_MMIO_SIIMAGE static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) { unsigned long bar5 = pci_resource_start(dev, 5); @@ -533,78 +531,73 @@ addr = (unsigned long) ioaddr; if (dev->device == PCI_DEVICE_ID_SII_3112) { - sii_outl(0, DEVADDR(0x148)); - sii_outl(0, DEVADDR(0x1C8)); + writel(0, DEVADDR(0x148)); + writel(0, DEVADDR(0x1C8)); } - sii_outb(0, DEVADDR(0xB4)); - sii_outb(0, DEVADDR(0xF4)); - tmpbyte = sii_inb(DEVADDR(0x4A)); + writeb(0, DEVADDR(0xB4)); + writeb(0, DEVADDR(0xF4)); + tmpbyte = readb(DEVADDR(0x4A)); switch(tmpbyte) { case 0x01: - sii_outb(tmpbyte|0x10, DEVADDR(0x4A)); - tmpbyte = sii_inb(DEVADDR(0x4A)); + writeb(tmpbyte|0x10, DEVADDR(0x4A)); + tmpbyte = readb(DEVADDR(0x4A)); case 0x31: /* if clocking is disabled */ /* 133 clock attempt to force it on */ - sii_outb(tmpbyte & ~0x20, DEVADDR(0x4A)); - tmpbyte = sii_inb(DEVADDR(0x4A)); + writeb(tmpbyte & ~0x20, DEVADDR(0x4A)); + tmpbyte = readb(DEVADDR(0x4A)); case 0x11: case 0x21: break; default: tmpbyte &= ~0x30; tmpbyte |= 0x20; - sii_outb(tmpbyte, DEVADDR(0x4A)); + writeb(tmpbyte, DEVADDR(0x4A)); break; } - sii_outb(0x72, DEVADDR(0xA1)); - sii_outw(0x328A, DEVADDR(0xA2)); - sii_outl(0x62DD62DD, DEVADDR(0xA4)); - sii_outl(0x43924392, DEVADDR(0xA8)); - sii_outl(0x40094009, DEVADDR(0xAC)); - sii_outb(0x72, DEVADDR(0xE1)); - sii_outw(0x328A, DEVADDR(0xE2)); - sii_outl(0x62DD62DD, DEVADDR(0xE4)); - sii_outl(0x43924392, DEVADDR(0xE8)); - sii_outl(0x40094009, DEVADDR(0xEC)); + writeb(0x72, DEVADDR(0xA1)); + writew(0x328A, DEVADDR(0xA2)); + writel(0x62DD62DD, DEVADDR(0xA4)); + writel(0x43924392, DEVADDR(0xA8)); + writel(0x40094009, DEVADDR(0xAC)); + writeb(0x72, DEVADDR(0xE1)); + writew(0x328A, DEVADDR(0xE2)); + writel(0x62DD62DD, DEVADDR(0xE4)); + writel(0x43924392, DEVADDR(0xE8)); + writel(0x40094009, DEVADDR(0xEC)); if (dev->device == PCI_DEVICE_ID_SII_3112) { - sii_outl(0xFFFF0000, DEVADDR(0x108)); - sii_outl(0xFFFF0000, DEVADDR(0x188)); - sii_outl(0x00680000, DEVADDR(0x148)); - sii_outl(0x00680000, DEVADDR(0x1C8)); + writel(0xFFFF0000, DEVADDR(0x108)); + writel(0xFFFF0000, DEVADDR(0x188)); + writel(0x00680000, DEVADDR(0x148)); + writel(0x00680000, DEVADDR(0x1C8)); } - tmpbyte = sii_inb(DEVADDR(0x4A)); + tmpbyte = readb(DEVADDR(0x4A)); proc_reports_siimage(dev, (tmpbyte>>=4), name); return 1; } -#endif /* CONFIG_TRY_MMIO_SIIMAGE */ static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name) { u32 class_rev = 0; u8 tmpbyte = 0; -#ifdef CONFIG_TRY_MMIO_SIIMAGE u8 BA5_EN = 0; -#endif /* CONFIG_TRY_MMIO_SIIMAGE */ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); -#ifdef CONFIG_TRY_MMIO_SIIMAGE pci_read_config_byte(dev, 0x8A, &BA5_EN); if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) { if (setup_mmio_siimage(dev, name)) { return 0; } } -#endif /* CONFIG_TRY_MMIO_SIIMAGE */ pci_write_config_byte(dev, 0x80, 0x00); pci_write_config_byte(dev, 0x84, 0x00); @@ -658,17 +651,7 @@ // u16 i = 0; hw_regs_t hw; - hwif->OUTB = sii_outb; - hwif->OUTW = sii_outw; - hwif->OUTL = sii_outl; - hwif->OUTSW = sii_outsw; - hwif->OUTSL = sii_outsl; - hwif->INB = sii_inb; - hwif->INW = sii_inw; - hwif->INL = sii_inl; - hwif->INSW = sii_insw; - hwif->INSL = sii_insl; - + default_hwif_mmiops(hwif); memset(&hw, 0, sizeof(hw_regs_t)); #if 1 @@ -706,7 +689,7 @@ #endif #if 0 - printk("%s: ", hwif->name); + printk(KERN_DEBUG "%s: ", hwif->name); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i)); printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i)); @@ -726,7 +709,6 @@ hw.priv = (void *) addr; // hw.priv = pci_get_drvdata(hwif->pci_dev); hw.irq = hwif->pci_dev->irq; -// hw.iops = siimage_iops; memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); @@ -777,9 +759,6 @@ pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66); return (ata66 & 0x01) ? 1 : 0; } -#ifndef CONFIG_TRY_MMIO_SIIMAGE - if (hwif->mmio) BUG(); -#endif /* CONFIG_TRY_MMIO_SIIMAGE */ return (hwif->INB(SELADDR(0)) & 0x01) ? 1 : 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/siimage.h linux.21pre4-ac6/drivers/ide/pci/siimage.h --- linux.21pre4/drivers/ide/pci/siimage.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/siimage.h 2003-02-21 16:32:35.000000000 +0000 @@ -9,8 +9,6 @@ #define DISPLAY_SIIMAGE_TIMINGS -#define CONFIG_TRY_MMIO_SIIMAGE -//#undef CONFIG_TRY_MMIO_SIIMAGE #undef SIIMAGE_VIRTUAL_DMAPIO #undef SIIMAGE_BUFFERED_TASKFILE #undef SIIMAGE_LARGE_DMA @@ -36,56 +34,6 @@ #define DEVADDR(R) (((unsigned long) pci_get_drvdata(dev))|(R)) -inline u8 sii_inb (unsigned long port) -{ - return (u8) readb(port); -} - -inline u16 sii_inw (unsigned long port) -{ - return (u16) readw(port); -} - -inline void sii_insw (unsigned long port, void *addr, u32 count) -{ - __ide_mm_insw(port, addr, count); -} - -inline u32 sii_inl (unsigned long port) -{ - return (u32) readl(port); -} - -inline void sii_insl (unsigned long port, void *addr, u32 count) -{ - __ide_mm_insw(port, addr, (count)<<1); -} - -inline void sii_outb (u8 value, unsigned long port) -{ - writeb(value, port); -} - -inline void sii_outw (u16 value, unsigned long port) -{ - writew(value, port); -} - -inline void sii_outsw (unsigned long port, void *addr, u32 count) -{ - __ide_mm_outsw(port, addr, count); -} - -inline void sii_outl (u32 value, unsigned long port) -{ - writel(value, port); -} - -inline void sii_outsl (unsigned long port, void *addr, u32 count) -{ - __ide_mm_outsw(port, addr, (count)<<1); -} - #if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) #include #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/sis5513.c linux.21pre4-ac6/drivers/ide/pci/sis5513.c --- linux.21pre4/drivers/ide/pci/sis5513.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/sis5513.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/sis5513.c Version 0.14ac Sept 11, 2002 + * linux/drivers/ide/pci/sis5513.c Version 0.14ac Sept 11, 2002 * * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2002 Lionel Bouton , Maintainer @@ -18,6 +18,10 @@ * ATA100 tests and design on the SiS735/5513 chipset. * ATA16/33 support from specs * ATA133 support for SiS961/962 by L.C. Chang + * + * Documentation: + * SiS chipset documentation available under NDA to companies not + * individuals only. */ /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/sl82c105.c linux.21pre4-ac6/drivers/ide/pci/sl82c105.c --- linux.21pre4/drivers/ide/pci/sl82c105.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/sl82c105.c 2003-02-19 15:46:46.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/sl82c105.c + * linux/drivers/ide/pci/sl82c105.c * * SL82C105/Winbond 553 IDE driver * @@ -7,6 +7,10 @@ * * Drive tuning added from Rebel.com's kernel sources * -- Russell King (15/11/98) linux@arm.linux.org.uk + * + * Merge in Russell's HW workarounds, fix various problems + * with the timing registers setup. + * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org */ #include @@ -28,6 +32,24 @@ #include "ide_modes.h" #include "sl82c105.h" +#undef DEBUG + +#ifdef DEBUG +#define DBG(arg) printk arg +#else +#define DBG(fmt,...) +#endif +/* + * SL82C105 PCI config register 0x40 bits. + */ +#define CTRL_IDE_IRQB (1 << 30) +#define CTRL_IDE_IRQA (1 << 28) +#define CTRL_LEGIRQ (1 << 11) +#define CTRL_P1F16 (1 << 5) +#define CTRL_P1EN (1 << 4) +#define CTRL_P0F16 (1 << 1) +#define CTRL_P0EN (1 << 0) + /* * Convert a PIO mode and cycle time to the required on/off * times for the interface. This has protection against run-away @@ -57,7 +79,7 @@ /* * Configure the drive and chipset for PIO */ -static void config_for_pio(ide_drive_t *drive, int pio, int report) +static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -65,14 +87,20 @@ u16 drv_ctrl = 0x909; unsigned int xfer_mode, reg; + DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n", + drive->name, pio, report, chipset_only)); + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); pio = ide_get_best_pio_mode(drive, pio, 5, &p); xfer_mode = XFER_PIO_0 + pio; - if (ide_config_drive_speed(drive, xfer_mode) == 0) + if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) { drv_ctrl = get_timing_sl82c105(&p); + drive->pio_speed = xfer_mode; + } else + drive->pio_speed = XFER_PIO_0; if (drive->using_dma == 0) { /* @@ -96,15 +124,16 @@ { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u16 drv_ctrl = 0x909; unsigned int reg; + DBG(("config_for_dma(drive:%s)\n", drive->name)); + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) == 0) - drv_ctrl = 0x0240; + if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) + return 1; - pci_write_config_word(dev, reg, drv_ctrl); + pci_write_config_word(dev, reg, 0x0240); return 0; } @@ -117,6 +146,9 @@ static int sl82c105_check_drive (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); + + DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); + do { struct hd_driveid *id = drive->id; @@ -143,34 +175,188 @@ return hwif->ide_dma_off_quietly(drive); } +/* + * The SL82C105 holds off all IDE interrupts while in DMA mode until + * all DMA activity is completed. Sometimes this causes problems (eg, + * when the drive wants to report an error condition). + * + * 0x7e is a "chip testing" register. Bit 2 resets the DMA controller + * state machine. We need to kick this to work around various bugs. + */ +static inline void sl82c105_reset_host(struct pci_dev *dev) +{ + u16 val; + + pci_read_config_word(dev, 0x7e, &val); + pci_write_config_word(dev, 0x7e, val | (1 << 2)); + pci_write_config_word(dev, 0x7e, val & ~(1 << 2)); +} + +/* + * If we get an IRQ timeout, it might be that the DMA state machine + * got confused. Fix from Todd Inglett. Details from Winbond. + * + * This function is called when the IDE timer expires, the drive + * indicates that it is READY, and we were waiting for DMA to complete. + */ +static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; + unsigned long dma_base = hwif->dma_base; + + printk("sl82c105: lost IRQ: resetting host\n"); + + /* + * Check the raw interrupt from the drive. + */ + pci_read_config_dword(dev, 0x40, &val); + if (val & mask) + printk("sl82c105: drive was requesting IRQ, but host lost it\n"); + + /* + * Was DMA enabled? If so, disable it - we're resetting the + * host. The IDE layer will be handling the drive for us. + */ + val = hwif->INB(dma_base); + if (val & 1) { + outb(val & ~1, dma_base); + printk("sl82c105: DMA was enabled\n"); + } + + sl82c105_reset_host(dev); + + /* ide_dmaproc would return 1, so we do as well */ + return 1; +} + +/* + * ATAPI devices can cause the SL82C105 DMA state machine to go gaga. + * Winbond recommend that the DMA state machine is reset prior to + * setting the bus master DMA enable bit. + * + * The generic IDE core will have disabled the BMEN bit before this + * function is called. + */ +static int sl82c105_ide_dma_begin(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + +// DBG(("sl82c105_ide_dma_begin(drive:%s)\n", drive->name)); + + sl82c105_reset_host(dev); + return __ide_dma_begin(drive); +} + +static int sl82c105_ide_dma_timeout(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + + DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); + + sl82c105_reset_host(dev); + return __ide_dma_timeout(drive); +} + static int sl82c105_ide_dma_on (ide_drive_t *drive) { + DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); + if (config_for_dma(drive)) { - config_for_pio(drive, 4, 0); + config_for_pio(drive, 4, 0, 0); return HWIF(drive)->ide_dma_off_quietly(drive); } + printk(KERN_INFO "%s: DMA enabled\n", drive->name); return __ide_dma_on(drive); } static int sl82c105_ide_dma_off (ide_drive_t *drive) { - config_for_pio(drive, 4, 0); - return __ide_dma_off(drive); + u8 speed = XFER_PIO_0; + int rc; + + DBG(("sl82c105_ide_dma_off(drive:%s)\n", drive->name)); + + rc = __ide_dma_off(drive); + if (drive->pio_speed) + speed = drive->pio_speed - XFER_PIO_0; + config_for_pio(drive, speed, 0, 1); + drive->current_speed = drive->pio_speed; + + return rc; } static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) { - config_for_pio(drive, 4, 0); - return __ide_dma_off_quietly(drive); + u8 speed = XFER_PIO_0; + int rc; + + DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name)); + + rc = __ide_dma_off_quietly(drive); + if (drive->pio_speed) + speed = drive->pio_speed - XFER_PIO_0; + config_for_pio(drive, speed, 0, 1); + drive->current_speed = drive->pio_speed; + + return rc; +} + +/* + * Ok, that is nasty, but we must make sure the DMA timings + * won't be used for a PIO access. The solution here is + * to make sure the 16 bits mode is diabled on the channel + * when DMA is enabled, thus causing the chip to use PIO0 + * timings for those operations. + */ +static void sl82c105_selectproc(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 val, old, mask; + + //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); + + mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16; + old = val = *((u32 *)&hwif->hwif_data); + if (drive->using_dma) + val &= ~mask; + else + val |= mask; + if (old != val) { + pci_write_config_dword(dev, 0x40, val); + *((u32 *)&hwif->hwif_data) = val; + } } /* + * ATA reset will clear the 16 bits mode in the control + * register, we need to update our cache + */ +static void sl82c105_resetproc(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 val; + + DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); + + pci_read_config_dword(dev, 0x40, &val); + *((u32 *)&hwif->hwif_data) = val; +} + +/* * We only deal with PIO mode here - DMA mode 'using_dma' is not * initialised at the point that this function is called. */ static void tune_sl82c105(ide_drive_t *drive, u8 pio) { - config_for_pio(drive, pio, 1); + DBG(("tune_sl82c105(drive:%s)\n", drive->name)); + + config_for_pio(drive, pio, 1, 0); /* * We support 32-bit I/O on this interface, and it @@ -189,16 +375,20 @@ struct pci_dev *bridge; u8 rev; - bridge = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, NULL); - /* - * If we are part of a Winbond 553 + * The bridge should be part of the same device, but function 0. */ - if (!bridge || bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) + bridge = pci_find_slot(dev->bus->number, + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + if (!bridge) return -1; - if (bridge->bus != dev->bus || - PCI_SLOT(bridge->devfn) != PCI_SLOT(dev->devfn)) + /* + * Make sure it is a Winbond 553 and is an ISA bridge. + */ + if (bridge->vendor != PCI_VENDOR_ID_WINBOND || + bridge->device != PCI_DEVICE_ID_WINBOND_83C553 || + bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) return -1; /* @@ -211,16 +401,21 @@ /* * Enable the PCI device + * + * --BenH: It's arch fixup code that should enable channels that + * have not been enabled by firmware. I decided we can still enable + * channel 0 here at least, but channel 1 has to be enabled by + * firmware or arch code. We still set both to 16 bits mode. */ static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg) { - u8 ctrl_stat; + u32 val; - /* - * Enable the ports - */ - pci_read_config_byte(dev, 0x40, &ctrl_stat); - pci_write_config_byte(dev, 0x40, ctrl_stat | 0x33); + DBG(("init_chipset_sl82c105()\n")); + + pci_read_config_dword(dev, 0x40, &val); + val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; + pci_write_config_dword(dev, 0x40, val); return dev->irq; } @@ -230,6 +425,8 @@ unsigned int rev; u8 dma_state; + DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base)); + hwif->autodma = 0; if (!dma_base) @@ -238,8 +435,6 @@ dma_state = hwif->INB(dma_base + 2); rev = sl82c105_bridge_revision(hwif->pci_dev); if (rev <= 5) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", hwif->name, rev); dma_state &= ~0x60; @@ -259,8 +454,28 @@ static void __init init_hwif_sl82c105(ide_hwif_t *hwif) { - hwif->tuneproc = tune_sl82c105; + struct pci_dev *dev = hwif->pci_dev; + u32 val; + + DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); + hwif->tuneproc = tune_sl82c105; + hwif->selectproc = sl82c105_selectproc; + hwif->resetproc = sl82c105_resetproc; + + /* Default to PIO 0 for fallback unless tuned otherwise, + * we always autotune PIO, this is done before DMA is + * checked, so there is no risk of accidentally disabling + * DMA + */ + hwif->drives[0].pio_speed = XFER_PIO_0; + hwif->drives[0].autotune = 1; + hwif->drives[1].pio_speed = XFER_PIO_0; + hwif->drives[1].autotune = 1; + + pci_read_config_dword(dev, 0x40, &val); + *((u32 *)&hwif->hwif_data) = val; + if (!hwif->dma_base) return; @@ -273,6 +488,10 @@ hwif->ide_dma_on = &sl82c105_ide_dma_on; hwif->ide_dma_off = &sl82c105_ide_dma_off; hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->ide_dma_begin = &sl82c105_ide_dma_begin; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/slc90e66.c linux.21pre4-ac6/drivers/ide/pci/slc90e66.c --- linux.21pre4/drivers/ide/pci/slc90e66.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/slc90e66.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/slc90e66.c Version 0.11 September 11, 2002 + * linux/drivers/ide/pci/slc90e66.c Version 0.11 September 11, 2002 * * Copyright (C) 2000-2002 Andre Hedrick * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/triflex.c linux.21pre4-ac6/drivers/ide/pci/triflex.c --- linux.21pre4/drivers/ide/pci/triflex.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/triflex.c 2003-02-11 01:40:48.000000000 +0000 @@ -22,6 +22,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Loosely based on the piix & svwks drivers. + * + * Documentation: + * Not publically available. */ #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/trm290.c linux.21pre4-ac6/drivers/ide/pci/trm290.c --- linux.21pre4/drivers/ide/pci/trm290.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/trm290.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/trm290.c Version 1.02 Mar. 18, 2000 + * linux/drivers/ide/pci/trm290.c Version 1.02 Mar. 18, 2000 * * Copyright (c) 1997-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/pci/via82cxxx.c linux.21pre4-ac6/drivers/ide/pci/via82cxxx.c --- linux.21pre4/drivers/ide/pci/via82cxxx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/pci/via82cxxx.c 2003-02-11 01:40:48.000000000 +0000 @@ -1,16 +1,6 @@ /* - * $Id: via82cxxx.c,v 3.35-ac2 2002/09/111 Alan Exp $ * - * Copyright (c) 2000-2001 Vojtech Pavlik - * - * Based on the work of: - * Michel Aubry - * Jeff Garzik - * Andre Hedrick - */ - -/* - * Version 3.35 + * Version 3.36 * * VIA IDE driver for Linux. Supported southbridges: * @@ -24,6 +14,10 @@ * Michel Aubry * Jeff Garzik * Andre Hedrick + * + * Documentation: + * Obsolete device documentation publically available from via.com.tw + * Current device documentation available under NDA only */ /* @@ -67,6 +61,7 @@ #define VIA_SET_FIFO 0x040 /* Needs to have FIFO split set */ #define VIA_NO_UNMASK 0x080 /* Doesn't work with IRQ unmasking on */ #define VIA_BAD_ID 0x100 /* Has wrong vendor ID (0x1107) */ +#define VIA_BAD_AST 0x200 /* Don't touch Address Setup Timing */ /* * VIA SouthBridge chips. @@ -82,8 +77,8 @@ #ifdef FUTURE_BRIDGES { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 }, #endif - { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 }, - { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 }, + { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, @@ -152,7 +147,7 @@ via_print("----------VIA BusMastering IDE Configuration" "----------------"); - via_print("Driver Version: 3.35-ac"); + via_print("Driver Version: 3.36"); via_print("South Bridge: VIA %s", via_config->name); @@ -292,9 +287,11 @@ { u8 t; - pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); - t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); - pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); + if (~via_config->flags & VIA_BAD_AST) { + pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); + t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); + pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); + } pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)), ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ppc/mpc8xx.c linux.21pre4-ac6/drivers/ide/ppc/mpc8xx.c --- linux.21pre4/drivers/ide/ppc/mpc8xx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ppc/mpc8xx.c 2003-01-28 16:28:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-m8xx.c + * linux/drivers/ide/ppc/ide-m8xx.c * * Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de * Modified for direct IDE interface diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/ppc/pmac.c linux.21pre4-ac6/drivers/ide/ppc/pmac.c --- linux.21pre4/drivers/ide/ppc/pmac.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/ppc/pmac.c 2003-02-11 17:43:07.000000000 +0000 @@ -5,7 +5,7 @@ * These IDE interfaces are memory-mapped and have a DBDMA channel * for doing DMA. * - * Copyright (C) 1998-2001 Paul Mackerras & Ben. Herrenschmidt + * Copyright (C) 1998-2002 Paul Mackerras & Ben. Herrenschmidt * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -43,21 +43,22 @@ #include #endif #include "ide_modes.h" +#include "ide-timing.h" extern void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq); -#define IDE_PMAC_DEBUG - +#undef IDE_PMAC_DEBUG #define DMA_WAIT_TIMEOUT 500 typedef struct pmac_ide_hwif { ide_ioreg_t regbase; + unsigned long mapbase; int irq; int kind; int aapl_bus_id; + int cable_80; struct device_node* node; - u32 timings[2]; - int index; + u32 timings[4]; #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC /* Those fields are duplicating what is in hwif. We currently * can't use the hwif ones because of some assumptions that are @@ -82,7 +83,15 @@ controller_heathrow, /* Heathrow/Paddington */ controller_kl_ata3, /* KeyLargo ATA-3 */ controller_kl_ata4, /* KeyLargo ATA-4 */ - controller_kl_ata4_80 /* KeyLargo ATA-4 with 80 conductor cable */ + controller_un_ata6 /* UniNorth2 ATA-6 */ +}; + +static const char* model_name[] = { + "OHare ATA", /* OHare based */ + "Heathrow ATA", /* Heathrow/Paddington */ + "KeyLargo ATA-3", /* KeyLargo ATA-3 */ + "KeyLargo ATA-4", /* KeyLargo ATA-4 */ + "UniNorth ATA-6" /* UniNorth2 ATA-6 */ }; /* @@ -91,6 +100,11 @@ #define IDE_TIMING_CONFIG 0x200 #define IDE_INTERRUPT 0x300 +/* Kauai (U2) ATA has different register setup */ +#define IDE_KAUAI_PIO_CONFIG 0x200 +#define IDE_KAUAI_ULTRA_CONFIG 0x210 +#define IDE_KAUAI_POLL_CONFIG 0x220 + /* * Timing configuration register definitions */ @@ -101,6 +115,28 @@ #define IDE_SYSCLK_NS 30 /* 33Mhz cell */ #define IDE_SYSCLK_66_NS 15 /* 66Mhz cell */ +/* 100Mhz cell, found in Uninorth 2. I don't have much infos about + * this one yet, it appears as a pci device (106b/0033) on uninorth + * internal PCI bus and it's clock is controlled like gem or fw. It + * appears to be an evolution of keylargo ATA4 with a timing register + * extended to 2 32bits registers and a similar DBDMA channel. Other + * registers seem to exist but I can't tell much about them. + * + * So far, I'm using pre-calculated tables for this extracted from + * the values used by the MacOS X driver. + * + * The "PIO" register controls PIO and MDMA timings, the "ULTRA" + * register controls the UDMA timings. At least, it seems bit 0 + * of this one enables UDMA vs. MDMA, and bits 4..7 are the + * cycle time in units of 10ns. Bits 8..15 are used by I don't + * know their meaning yet + */ +#define TR_100_PIOREG_PIO_MASK 0xff000fff +#define TR_100_PIOREG_MDMA_MASK 0x00fff000 +#define TR_100_UDMAREG_UDMA_MASK 0x0000ffff +#define TR_100_UDMAREG_UDMA_EN 0x00000001 + + /* 66Mhz cell, found in KeyLargo. Can do ultra mode 0 to 2 on * 40 connector cable and to 4 on 80 connector one. * Clock unit is 15ns (66Mhz) @@ -115,8 +151,7 @@ * well, despite a comment that would lead to think it has a * min value of 45ns. * Apple also add 60ns to the write data setup (or cycle time ?) on - * reads. I can't explain that, I tried it and it broke everything - * here. + * reads. */ #define TR_66_UDMA_MASK 0xfff00000 #define TR_66_UDMA_EN 0x00100000 /* Enable Ultra mode for DMA */ @@ -220,12 +255,12 @@ { 0, 0, 0 } }; -/* Ultra DMA timings (rounded) */ +/* KeyLargo ATA-4 Ultra DMA timings (rounded) */ struct { int addrSetup; /* ??? */ int rdy2pause; int wrDataSetup; -} udma_timings[] __pmacdata = +} kl66_udma_timings[] __pmacdata = { { 0, 180, 120 }, /* Mode 0 */ { 0, 150, 90 }, /* 1 */ @@ -234,6 +269,63 @@ { 0, 90, 30 } /* 4 */ }; +/* UniNorth 2 ATA/100 timings */ +struct kauai_timing { + int cycle_time; + u32 timing_reg; +}; + +static struct kauai_timing kauai_pio_timings[] __pmacdata = +{ + { 930 , 0x08000fff }, + { 600 , 0x08000a92 }, + { 383 , 0x0800060f }, + { 360 , 0x08000492 }, + { 330 , 0x0800048f }, + { 300 , 0x080003cf }, + { 270 , 0x080003cc }, + { 240 , 0x0800038b }, + { 239 , 0x0800030c }, + { 180 , 0x05000249 }, + { 120 , 0x04000148 } +}; + +static struct kauai_timing kauai_mdma_timings[] __pmacdata = +{ + { 1260 , 0x00fff000 }, + { 480 , 0x00618000 }, + { 360 , 0x00492000 }, + { 270 , 0x0038e000 }, + { 240 , 0x0030c000 }, + { 210 , 0x002cb000 }, + { 180 , 0x00249000 }, + { 150 , 0x00209000 }, + { 120 , 0x00148000 }, + { 0 , 0 }, +}; + +static struct kauai_timing kauai_udma_timings[] __pmacdata = +{ + { 120 , 0x000070c0 }, + { 90 , 0x00005d80 }, + { 60 , 0x00004a60 }, + { 45 , 0x00003a50 }, + { 30 , 0x00002a30 }, + { 20 , 0x00002921 }, + { 0 , 0 }, +}; + +static inline u32 +kauai_lookup_timing(struct kauai_timing* table, int cycle_time) +{ + int i; + + for (i=0; table[i].cycle_time; i++) + if (cycle_time > table[i+1].cycle_time) + return table[i].timing_reg; + return 0; +} + /* allow up to 256 DBDMA commands per xfer */ #define MAX_DCMDS 256 @@ -242,14 +334,18 @@ * NOTE: There is at least one case I know of a disk that needs about 10sec * before anwering on the bus. I beleive we could add a kernel command * line arg to override this delay for such cases. + * + * NOTE2: This has to be fixed with a BSY wait loop. I'm working on adding + * that to the generic probe code. */ #define IDE_WAKEUP_DELAY_MS 2000 static void pmac_ide_setup_dma(struct device_node *np, int ix); -static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr); +static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq, int ddir); static int pmac_ide_tune_chipset(ide_drive_t *drive, u8 speed); static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio); static void pmac_ide_selectproc(ide_drive_t *drive); +static void pmac_ide_kauai_selectproc(ide_drive_t *drive); static int pmac_ide_dma_begin (ide_drive_t *drive); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ @@ -312,9 +408,54 @@ else writel(pmif->timings[0], (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); - (void)readl((unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); + io_flush(readl((unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG))); } +static void __pmac +pmac_ide_kauai_selectproc(ide_drive_t *drive) +{ + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; + + if (pmif == NULL) + return; + + if (drive->select.b.unit & 0x01) { + writel(pmif->timings[1], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG)); + writel(pmif->timings[3], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG)); + } else { + writel(pmif->timings[0], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG)); + writel(pmif->timings[2], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG)); + } + io_flush(readl((unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG))); +} + +static void __pmac +pmac_ide_do_update_timings(ide_drive_t *drive) +{ + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; + + if (pmif == NULL) + return; + + if (pmif->kind == controller_un_ata6) + pmac_ide_kauai_selectproc(drive); + else + pmac_ide_selectproc(drive); +} + +static void +pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port) +{ + u32 tmp; + + writeb(value, port); + tmp = readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG)); + io_flush(value); +} static int __pmac pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) @@ -328,7 +469,7 @@ SELECT_MASK(drive, 0); udelay(1); /* Get rid of pending error state */ - (void) hwif->INB(IDE_STATUS_REG); + io_flush(hwif->INB(IDE_STATUS_REG)); /* Timeout bumped for some powerbooks */ if (wait_for_ready(drive, 2000)) { /* Timeout bumped for some powerbooks */ @@ -403,21 +544,27 @@ if (pmif == NULL) return; + /* which drive is it ? */ + timings = &pmif->timings[drive->select.b.unit & 0x01]; + pio = ide_get_best_pio_mode(drive, pio, 4, &d); - accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time); - if (drive->select.b.unit & 0x01) - timings = &pmif->timings[1]; - else - timings = &pmif->timings[0]; - recTime = d.cycle_time - ide_pio_timings[pio].active_time - - ide_pio_timings[pio].setup_time; - recTime = max(recTime, 150U); - accessTime = ide_pio_timings[pio].active_time; - accessTime = max(accessTime, 150U); - if (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80) { + switch (pmif->kind) { + case controller_un_ata6: { + /* 100Mhz cell */ + u32 tr = kauai_lookup_timing(kauai_pio_timings, d.cycle_time); + if (tr == 0) + return; + *timings = ((*timings) & ~TR_100_PIOREG_PIO_MASK) | tr; + break; + } + case controller_kl_ata4: /* 66Mhz cell */ + recTime = d.cycle_time - ide_pio_timings[pio].active_time + - ide_pio_timings[pio].setup_time; + recTime = max(recTime, 150U); + accessTime = ide_pio_timings[pio].active_time; + accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); recTicks = SYSCLK_TICKS_66(recTime); @@ -425,9 +572,15 @@ *timings = ((*timings) & ~TR_66_PIO_MASK) | (accessTicks << TR_66_PIO_ACCESS_SHIFT) | (recTicks << TR_66_PIO_RECOVERY_SHIFT); - } else { + break; + default: { /* 33Mhz cell */ int ebit = 0; + recTime = d.cycle_time - ide_pio_timings[pio].active_time + - ide_pio_timings[pio].setup_time; + recTime = max(recTime, 150U); + accessTime = ide_pio_timings[pio].active_time; + accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 4U); @@ -443,6 +596,8 @@ (recTicks << TR_33_PIO_RECOVERY_SHIFT); if (ebit) *timings |= TR_33_PIO_E; + break; + } } #ifdef IDE_PMAC_DEBUG @@ -451,18 +606,21 @@ #endif if (drive->select.all == HWIF(drive)->INB(IDE_SELECT_REG)) - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); } #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC static int __pmac -set_timings_udma(u32 *timings, u8 speed) +set_timings_udma_ata4(u32 *timings, u8 speed) { unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks; - rdyToPauseTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].rdy2pause); - wrDataSetupTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].wrDataSetup); - addrTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].addrSetup); + if (speed > XFER_UDMA_4) + return 1; + + rdyToPauseTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].rdy2pause); + wrDataSetupTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].wrDataSetup); + addrTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].addrSetup); *timings = ((*timings) & ~(TR_66_UDMA_MASK | TR_66_MDMA_MASK)) | (wrDataSetupTicks << TR_66_UDMA_WRDATASETUP_SHIFT) | @@ -478,11 +636,28 @@ } static int __pmac -set_timings_mdma(int intf_type, u32 *timings, u8 speed, int drive_cycle_time) +set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed) +{ + struct ide_timing *t = ide_timing_find_mode(speed); + u32 tr; + + if (speed > XFER_UDMA_5 || t == NULL) + return 1; + tr = kauai_lookup_timing(kauai_udma_timings, (int)t->udma); + if (tr == 0) + return 1; + *ultra_timings = ((*ultra_timings) & ~TR_100_UDMAREG_UDMA_MASK) | tr; + *ultra_timings = (*ultra_timings) | TR_100_UDMAREG_UDMA_EN; + + return 0; +} + +static int __pmac +set_timings_mdma(int intf_type, u32 *timings, u32 *timings2, u8 speed, int drive_cycle_time) { int cycleTime, accessTime, recTime; unsigned accessTicks, recTicks; - struct mdma_timings_t* tm; + struct mdma_timings_t* tm = NULL; int i; /* Get default cycle time for mode */ @@ -491,7 +666,7 @@ case 1: cycleTime = 150; break; case 2: cycleTime = 120; break; default: - return -1; + return 1; } /* Adjust for drive */ if (drive_cycle_time && drive_cycle_time > cycleTime) @@ -501,8 +676,9 @@ cycleTime = 150; /* Get the proper timing array for this controller */ switch(intf_type) { + case controller_un_ata6: + break; case controller_kl_ata4: - case controller_kl_ata4_80: tm = mdma_timings_66; break; case controller_kl_ata3: @@ -512,24 +688,36 @@ tm = mdma_timings_33; break; } - /* Lookup matching access & recovery times */ - i = -1; - for (;;) { - if (tm[i+1].cycleTime < cycleTime) - break; - i++; - } - if (i < 0) - return -1; - cycleTime = tm[i].cycleTime; - accessTime = tm[i].accessTime; - recTime = tm[i].recoveryTime; + if (tm != NULL) { + /* Lookup matching access & recovery times */ + i = -1; + for (;;) { + if (tm[i+1].cycleTime < cycleTime) + break; + i++; + } + if (i < 0) + return 1; + cycleTime = tm[i].cycleTime; + accessTime = tm[i].accessTime; + recTime = tm[i].recoveryTime; #ifdef IDE_PMAC_DEBUG - printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n", - cycleTime, accessTime, recTime); -#endif - if (intf_type == controller_kl_ata4 || intf_type == controller_kl_ata4_80) { + printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n", + cycleTime, accessTime, recTime); +#endif + } + switch(intf_type) { + case controller_un_ata6: { + /* 100Mhz cell */ + u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime); + if (tr == 0) + return 1; + *timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr; + *timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN; + } + break; + case controller_kl_ata4: /* 66Mhz cell */ accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); @@ -541,7 +729,8 @@ *timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) | (accessTicks << TR_66_MDMA_ACCESS_SHIFT) | (recTicks << TR_66_MDMA_RECOVERY_SHIFT); - } else if (intf_type == controller_kl_ata3) { + break; + case controller_kl_ata3: /* 33Mhz cell on KeyLargo */ accessTicks = SYSCLK_TICKS(accessTime); accessTicks = max(accessTicks, 1U); @@ -553,7 +742,8 @@ *timings = ((*timings) & ~TR_33_MDMA_MASK) | (accessTicks << TR_33_MDMA_ACCESS_SHIFT) | (recTicks << TR_33_MDMA_RECOVERY_SHIFT); - } else { + break; + default: { /* 33Mhz cell on others */ int halfTick = 0; int origAccessTime = accessTime; @@ -578,6 +768,7 @@ (recTicks << TR_33_MDMA_RECOVERY_SHIFT); if (halfTick) *timings |= TR_33_MDMA_HALFTICK; + } } #ifdef IDE_PMAC_DEBUG printk(KERN_ERR "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n", @@ -591,36 +782,42 @@ * our, normal mdma function is supposed to be more precise */ static int __pmac -pmac_ide_tune_chipset (ide_drive_t *drive, u8 speed) +pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) { int unit = (drive->select.b.unit & 0x01); int ret = 0; pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; - u32 *timings; - + u32 *timings, *timings2; + if (pmif == NULL) return 1; - + timings = &pmif->timings[unit]; + timings2 = &pmif->timings[unit+2]; switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + case XFER_UDMA_5: + if (pmif->kind != controller_un_ata6) + return 1; case XFER_UDMA_4: case XFER_UDMA_3: - if (pmif->kind != controller_kl_ata4_80) + if (HWIF(drive)->udma_four == 0) return 1; case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: - if (pmif->kind != controller_kl_ata4 && - pmif->kind != controller_kl_ata4_80) - return 1; - ret = set_timings_udma(timings, speed); + if (pmif->kind == controller_kl_ata4) + ret = set_timings_udma_ata4(timings, speed); + else if (pmif->kind == controller_un_ata6) + ret = set_timings_udma_ata6(timings, timings2, speed); + else + ret = 1; break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: - ret = set_timings_mdma(pmif->kind, timings, speed, 0); + ret = set_timings_mdma(pmif->kind, timings, timings2, speed, 0); break; case XFER_SW_DMA_2: case XFER_SW_DMA_1: @@ -644,7 +841,7 @@ if (ret) return ret; - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); drive->current_speed = speed; return 0; @@ -653,11 +850,14 @@ static void __pmac sanitize_timings(pmac_ide_hwif_t *pmif) { - unsigned value; + unsigned int value, value2 = 0; switch(pmif->kind) { + case controller_un_ata6: + value = 0x08618a92; + value2 = 0x00002921; + break; case controller_kl_ata4: - case controller_kl_ata4_80: value = 0x0008438c; break; case controller_kl_ata3: @@ -670,6 +870,7 @@ break; } pmif->timings[0] = pmif->timings[1] = value; + pmif->timings[2] = pmif->timings[3] = value2; } ide_ioreg_t __pmac @@ -689,6 +890,17 @@ return -1; } +struct device_node* +pmac_ide_get_of_node(int index) +{ + /* Don't access the pmac_ide array on non-pmac */ + if (pmac_ide_count == 0) + return NULL; + if (pmac_ide[index].regbase == 0) + return NULL; + return pmac_ide[index].node; +} + int __pmac pmac_ide_get_irq(ide_ioreg_t base) { @@ -731,7 +943,7 @@ int i; struct device_node *atas; struct device_node *p, **pp, *removables, **rp; - unsigned long base; + unsigned long base, regbase; int irq, big_delay; ide_hwif_t *hwif; @@ -772,29 +984,89 @@ /* * If this node is not under a mac-io or dbdma node, - * leave it to the generic PCI driver. + * leave it to the generic PCI driver. Except for U2's + * Kauai ATA */ - for (tp = np->parent; tp != 0; tp = tp->parent) - if (tp->type && (strcmp(tp->type, "mac-io") == 0 - || strcmp(tp->type, "dbdma") == 0)) - break; - if (tp == 0) - continue; + if (!device_is_compatible(np, "kauai-ata")) { + for (tp = np->parent; tp != 0; tp = tp->parent) + if (tp->type && (strcmp(tp->type, "mac-io") == 0 + || strcmp(tp->type, "dbdma") == 0)) + break; + if (tp == 0) + continue; - if (np->n_addrs == 0) { - printk(KERN_WARNING "ide: no address for device %s\n", - np->full_name); - continue; - } + if (np->n_addrs == 0) { + printk(KERN_WARNING "ide-pmac: no address for device %s\n", + np->full_name); + continue; + } + /* We need to find the pci_dev of the mac-io holding the + * IDE interface + */ + if (pci_device_from_OF_node(tp, &pbus, &pid) == 0) + pdev = pci_find_slot(pbus, pid); - /* We need to find the pci_dev of the mac-io holding the - * IDE interface - */ - if (pci_device_from_OF_node(tp, &pbus, &pid) == 0) - pdev = pci_find_slot(pbus, pid); - if (pdev == NULL) - printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n", - np->full_name); + if (pdev == NULL) + printk(KERN_WARNING "ide-pmac: no PCI host for device %s, DMA disabled\n", + np->full_name); + /* + * Some older OFs have bogus sizes, causing request_OF_resource + * to fail. We fix them up here + */ + if (np->addrs[0].size > 0x1000) + np->addrs[0].size = 0x1000; + if (np->n_addrs > 1 && np->addrs[1].size > 0x100) + np->addrs[1].size = 0x100; + + if (request_OF_resource(np, 0, " (mac-io IDE IO)") == NULL) { + printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name); + continue; + } + + base = (unsigned long) ioremap(np->addrs[0].address, 0x400); + regbase = base; + + /* XXX This is bogus. Should be fixed in the registry by checking + the kind of host interrupt controller, a bit like gatwick + fixes in irq.c + */ + if (np->n_intrs == 0) { + printk(KERN_WARNING "ide-pmac: no intrs for device %s, using 13\n", + np->full_name); + irq = 13; + } else { + irq = np->intrs[0].line; + } + } else { + unsigned long rbase, rlen; + + if (pci_device_from_OF_node(np, &pbus, &pid) == 0) + pdev = pci_find_slot(pbus, pid); + if (pdev == NULL) { + printk(KERN_WARNING "ide-pmac: no PCI host for device %s, skipping\n", + np->full_name); + continue; + } + if (pci_enable_device(pdev)) { + printk(KERN_WARNING "ide-pmac: Can't enable PCI device for %s, skipping\n", + np->full_name); + continue; + } + pci_set_master(pdev); + + if (pci_request_regions(pdev, "U2 IDE")) { + printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources\n"); + continue; + } + + rbase = pci_resource_start(pdev, 0); + rlen = pci_resource_len(pdev, 0); + + base = (unsigned long) ioremap(rbase, rlen); + regbase = base + 0x2000; + + irq = pdev->irq; + } /* * If this slot is taken (e.g. by ide-pci.c) try the next one. @@ -806,38 +1078,15 @@ break; pmif = &pmac_ide[i]; - /* - * Some older OFs have bogus sizes, causing request_OF_resource - * to fail. We fix them up here - */ - if (np->addrs[0].size > 0x1000) - np->addrs[0].size = 0x1000; - if (np->n_addrs > 1 && np->addrs[1].size > 0x100) - np->addrs[1].size = 0x100; - - if (request_OF_resource(np, 0, " (mac-io IDE IO)") == NULL) { - printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name); - continue; - } - - base = (unsigned long) ioremap(np->addrs[0].address, 0x400); - - /* XXX This is bogus. Should be fixed in the registry by checking - the kind of host interrupt controller, a bit like gatwick - fixes in irq.c - */ - if (np->n_intrs == 0) { - printk(KERN_WARNING "ide: no intrs for device %s, using 13\n", - np->full_name); - irq = 13; - } else { - irq = np->intrs[0].line; - } - pmif->regbase = base; + pmif->mapbase = base; + pmif->regbase = regbase; pmif->irq = irq; pmif->node = np; - pmif->index = i; - if (device_is_compatible(np, "keylargo-ata")) { + pmif->cable_80 = 0; + if (device_is_compatible(np, "kauai-ata")) { + pmif->kind = controller_un_ata6; + pci_set_drvdata(pdev, pmif); + } else if (device_is_compatible(np, "keylargo-ata")) { if (strcmp(np->name, "ata-4") == 0) pmif->kind = controller_kl_ata4; else @@ -850,10 +1099,11 @@ bidp = (int *)get_property(np, "AAPL,bus-id", NULL); pmif->aapl_bus_id = bidp ? *bidp : 0; - if (pmif->kind == controller_kl_ata4) { + /* Get cable type from device-tree */ + if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6) { char* cable = get_property(np, "cable-type", NULL); if (cable && !strncmp(cable, "80-", 3)) - pmif->kind = controller_kl_ata4_80; + pmif->cable_80 = 1; } /* Make sure we have sane timings */ @@ -862,7 +1112,7 @@ if (np->parent && np->parent->name && strcasecmp(np->parent->name, "media-bay") == 0) { #ifdef CONFIG_PMAC_PBOOK - media_bay_set_ide_infos(np->parent,base,irq,i); + media_bay_set_ide_infos(np->parent,regbase,irq,i); #endif /* CONFIG_PMAC_PBOOK */ in_bay = 1; if (!bidp) @@ -875,8 +1125,6 @@ ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1); } else { /* This is necessary to enable IDE when net-booting */ - printk(KERN_INFO "pmac_ide: enabling IDE bus ID %d\n", - pmif->aapl_bus_id); ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); mdelay(10); @@ -887,6 +1135,7 @@ hwif = &ide_hwifs[i]; /* Setup MMIO ops */ default_hwif_mmiops(hwif); + hwif->OUTBSYNC = pmac_outbsync; /* Tell common code _not_ to mess with resources */ hwif->mmio = 2; hwif->hwif_data = pmif; @@ -894,33 +1143,58 @@ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->chipset = ide_pmac; hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay; - hwif->udma_four = (pmif->kind == controller_kl_ata4_80); + hwif->udma_four = pmif->cable_80; hwif->pci_dev = pdev; hwif->drives[0].unmask = 1; hwif->drives[1].unmask = 1; hwif->tuneproc = pmac_ide_tuneproc; - hwif->selectproc = pmac_ide_selectproc; + if (pmif->kind == controller_un_ata6) + hwif->selectproc = pmac_ide_kauai_selectproc; + else + hwif->selectproc = pmac_ide_selectproc; hwif->speedproc = pmac_ide_tune_chipset; + + printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s\n", + i, model_name[pmif->kind], pmif->aapl_bus_id, + in_bay ? " (mediabay)" : ""); + #ifdef CONFIG_PMAC_PBOOK - if (in_bay && check_media_bay_by_base(base, MB_CD) == 0) + if (in_bay && check_media_bay_by_base(regbase, MB_CD) == 0) hwif->noprobe = 0; #endif /* CONFIG_PMAC_PBOOK */ #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC - if (np->n_addrs >= 2) { + if (np->n_addrs >= 2 || pmif->kind == controller_un_ata6) { /* has a DBDMA controller channel */ pmac_ide_setup_dma(np, i); } hwif->atapi_dma = 1; - hwif->ultra_mask = 0x1f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - + switch(pmif->kind) { + case controller_un_ata6: + hwif->ultra_mask = pmif->cable_80 ? 0x3f : 0x07; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; + break; + case controller_kl_ata4: + hwif->ultra_mask = pmif->cable_80 ? 0x1f : 0x07; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; + break; + default: + hwif->ultra_mask = 0x00; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; + break; + } #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ ++i; } pmac_ide_count = i; + + if (pmac_ide_count == 0) + return; + if (big_delay) mdelay(IDE_WAKEUP_DELAY_MS); @@ -931,41 +1205,66 @@ #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC -static int +static int __pmac pmac_ide_build_sglist(ide_hwif_t *hwif, struct request *rq, int data_dir) { pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data; struct buffer_head *bh; struct scatterlist *sg = pmif->sg_table; + unsigned long lastdataend = ~0UL; int nents = 0; if (hwif->sg_dma_active) BUG(); + pmif->sg_dma_direction = data_dir; + bh = rq->bh; do { - unsigned char *virt_addr = bh->b_data; - unsigned int size = bh->b_size; + int contig = 0; + + if (bh->b_page) { + if (bh_phys(bh) == lastdataend) + contig = 1; + } else { + if ((unsigned long) bh->b_data == lastdataend) + contig = 1; + } + + if (contig) { + sg[nents - 1].length += bh->b_size; + lastdataend += bh->b_size; + continue; + } if (nents >= MAX_DCMDS) return 0; - while ((bh = bh->b_reqnext) != NULL) { - if ((virt_addr + size) != (unsigned char *) bh->b_data) - break; - size += bh->b_size; - } memset(&sg[nents], 0, sizeof(*sg)); - sg[nents].address = virt_addr; - sg[nents].length = size; + + if (bh->b_page) { + sg[nents].page = bh->b_page; + sg[nents].offset = bh_offset(bh); + lastdataend = bh_phys(bh) + bh->b_size; + } else { + if ((unsigned long) bh->b_data < PAGE_SIZE) + BUG(); + + sg[nents].address = bh->b_data; + lastdataend = (unsigned long) bh->b_data + bh->b_size; + } + + sg[nents].length = bh->b_size; nents++; - } while (bh != NULL); + } while ((bh = bh->b_reqnext) != NULL); + + if(nents == 0) + BUG(); - pmif->sg_dma_direction = data_dir; return pci_map_sg(hwif->pci_dev, sg, nents, data_dir); } -static int +static int __pmac pmac_ide_raw_build_sglist(ide_hwif_t *hwif, struct request *rq) { pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data; @@ -1000,17 +1299,15 @@ * pmac_ide_build_dmatable builds the DBDMA command list * for a transfer and sets the DBDMA channel to point to it. */ -static int -pmac_ide_build_dmatable(ide_drive_t *drive, int wr) +static int __pmac +pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq, int ddir) { struct dbdma_cmd *table; int i, count = 0; - struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; volatile struct dbdma_regs *dma = pmif->dma_regs; struct scatterlist *sg; - int data_dir; /* DMA table is already aligned */ table = (struct dbdma_cmd *) pmif->dma_table_cpu; @@ -1020,16 +1317,11 @@ while (readl(&dma->status) & RUN) udelay(1); - if (wr) - data_dir = PCI_DMA_TODEVICE; - else - data_dir = PCI_DMA_FROMDEVICE; - /* Build sglist */ if (rq->cmd == IDE_DRIVE_TASKFILE) pmif->sg_nents = i = pmac_ide_raw_build_sglist(hwif, rq); else - pmif->sg_nents = i = pmac_ide_build_sglist(hwif, rq, data_dir); + pmif->sg_nents = i = pmac_ide_build_sglist(hwif, rq, ddir); if (!i) return 0; @@ -1048,9 +1340,10 @@ if (++count >= MAX_DCMDS) { printk(KERN_WARNING "%s: DMA table too small\n", drive->name); - return 0; /* revert to PIO for this request */ + goto use_pio_instead; } - st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE); + st_le16(&table->command, + (ddir == PCI_DMA_TODEVICE) ? OUTPUT_MORE: INPUT_MORE); st_le16(&table->req_count, tc); st_le32(&table->phy_addr, cur_addr); table->cmd_dep = 0; @@ -1065,21 +1358,29 @@ } /* convert the last command to an input/output last command */ - if (count) - st_le16(&table[-1].command, wr? OUTPUT_LAST: INPUT_LAST); - else - printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name); + if (count) { + st_le16(&table[-1].command, + (ddir == PCI_DMA_TODEVICE) ? OUTPUT_LAST: INPUT_LAST); + /* add the stop command to the end of the list */ + memset(table, 0, sizeof(struct dbdma_cmd)); + st_le16(&table->command, DBDMA_STOP); + mb(); + writel(pmif->dma_table_dma, &dma->cmdptr); + return 1; + } - /* add the stop command to the end of the list */ - memset(table, 0, sizeof(struct dbdma_cmd)); - st_le16(&table->command, DBDMA_STOP); - mb(); - writel(pmif->dma_table_dma, &dma->cmdptr); - return 1; + printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name); + use_pio_instead: + pci_unmap_sg(hwif->pci_dev, + pmif->sg_table, + pmif->sg_nents, + pmif->sg_dma_direction); + hwif->sg_dma_active = 0; + return 0; /* revert to PIO for this request */ } /* Teardown mappings after DMA has completed. */ -static void +static void __pmac pmac_ide_destroy_dmatable (ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; @@ -1090,67 +1391,25 @@ if (nents) { pci_unmap_sg(dev, sg, nents, pmif->sg_dma_direction); pmif->sg_nents = 0; + HWIF(drive)->sg_dma_active = 0; } } -static __inline__ unsigned char -dma_bits_to_command(unsigned char bits) -{ - if(bits & 0x04) - return XFER_MW_DMA_2; - if(bits & 0x02) - return XFER_MW_DMA_1; - if(bits & 0x01) - return XFER_MW_DMA_0; - return 0; -} - -static __inline__ unsigned char -udma_bits_to_command(unsigned char bits, int high_speed) -{ - if (high_speed) { - if(bits & 0x10) - return XFER_UDMA_4; - if(bits & 0x08) - return XFER_UDMA_3; - } - if(bits & 0x04) - return XFER_UDMA_2; - if(bits & 0x02) - return XFER_UDMA_1; - if(bits & 0x01) - return XFER_UDMA_0; - return 0; -} - /* Calculate MultiWord DMA timings */ static int __pmac -pmac_ide_mdma_enable(ide_drive_t *drive) +pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) { - u8 bits = drive->id->dma_mword & 0x07; - u8 feature = dma_bits_to_command(bits); - u32 *timings; + ide_hwif_t *hwif = HWIF(drive); + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; int drive_cycle_time; struct hd_driveid *id = drive->id; - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; + u32 *timings, *timings2; + u32 timing_local[2]; int ret; - /* Set feature on drive */ - printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf); - ret = pmac_ide_do_setfeature(drive, feature); - if (ret) { - printk(KERN_WARNING "%s: Failed !\n", drive->name); - return 0; - } - - if (!drive->init_speed) - drive->init_speed = feature; - /* which drive is it ? */ - if (drive->select.b.unit & 0x01) - timings = &pmif->timings[1]; - else - timings = &pmif->timings[0]; + timings = &pmif->timings[drive->select.b.unit & 0x01]; + timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; /* Check if drive provide explicit cycle time */ if ((id->field_valid & 2) && (id->eide_dma_time)) @@ -1158,54 +1417,95 @@ else drive_cycle_time = 0; + /* Copy timings to local image */ + timing_local[0] = *timings; + timing_local[1] = *timings2; + /* Calculate controller timings */ - set_timings_mdma(pmif->kind, timings, feature, drive_cycle_time); + ret = set_timings_mdma( pmif->kind, + &timing_local[0], + &timing_local[1], + mode, + drive_cycle_time); + if (ret) + return 0; + + /* Set feature on drive */ + printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, mode & 0xf); + ret = pmac_ide_do_setfeature(drive, mode); + if (ret) { + printk(KERN_WARNING "%s: Failed !\n", drive->name); + return 0; + } + + /* Apply timings to controller */ + *timings = timing_local[0]; + *timings2 = timing_local[1]; + + /* Set speed info in drive */ + drive->current_speed = mode; + if (!drive->init_speed) + drive->init_speed = mode; - drive->current_speed = feature; return 1; } /* Calculate Ultra DMA timings */ static int __pmac -pmac_ide_udma_enable(ide_drive_t *drive, int high_speed) +pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) { - u8 bits = drive->id->dma_ultra & 0x1f; - u8 feature = udma_bits_to_command(bits, high_speed); - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; - u32 *timings; + ide_hwif_t *hwif = HWIF(drive); + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; + u32 *timings, *timings2; + u32 timing_local[2]; int ret; + + /* which drive is it ? */ + timings = &pmif->timings[drive->select.b.unit & 0x01]; + timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; + /* Copy timings to local image */ + timing_local[0] = *timings; + timing_local[1] = *timings2; + + /* Calculate timings for interface */ + if (pmif->kind == controller_un_ata6) + ret = set_timings_udma_ata6( &timing_local[0], + &timing_local[1], + mode); + else + ret = set_timings_udma_ata4(&timing_local[0], mode); + if (ret) + return 0; + /* Set feature on drive */ - printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf); - ret = pmac_ide_do_setfeature(drive, feature); + printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, mode & 0x0f); + ret = pmac_ide_do_setfeature(drive, mode); if (ret) { printk(KERN_WARNING "%s: Failed !\n", drive->name); return 0; } - if (!drive->init_speed) - drive->init_speed = feature; - - /* which drive is it ? */ - if (drive->select.b.unit & 0x01) - timings = &pmif->timings[1]; - else - timings = &pmif->timings[0]; + /* Apply timings to controller */ + *timings = timing_local[0]; + *timings2 = timing_local[1]; - set_timings_udma(timings, feature); + /* Set speed info in drive */ + drive->current_speed = mode; + if (!drive->init_speed) + drive->init_speed = mode; - drive->current_speed = feature; return 1; } +static __pmac int pmac_ide_dma_check(ide_drive_t *drive) { - int ata4, udma; struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; int enable = 1; - + int map; drive->using_dma = 0; if (pmif == NULL) @@ -1218,29 +1518,32 @@ enable = 0; if (HWIF(drive)->ide_dma_bad_drive(drive)) enable = 0; - udma = 0; - ata4 = (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80); - - if(enable) { - if (ata4 && (drive->media == ide_disk) && - (id->field_valid & 0x0004) && (id->dma_ultra & 0x1f)) { - /* UltraDMA modes. */ - drive->using_dma = pmac_ide_udma_enable(drive, - pmif->kind == controller_kl_ata4_80); - } - if (!drive->using_dma && (id->dma_mword & 0x0007)) { - /* Normal MultiWord DMA modes. */ - drive->using_dma = pmac_ide_mdma_enable(drive); + + if (enable) { + short mode; + + map = XFER_MWDMA; + if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6) { + map |= XFER_UDMA; + if (pmif->cable_80) { + map |= XFER_UDMA_66; + if (pmif->kind == controller_un_ata6) + map |= XFER_UDMA_100; + } } + mode = ide_find_best_mode(drive, map); + if (mode & XFER_UDMA) + drive->using_dma = pmac_ide_udma_enable(drive, mode); + else if (mode & XFER_MWDMA) + drive->using_dma = pmac_ide_mdma_enable(drive, mode); hwif->OUTB(0, IDE_CONTROL_REG); /* Apply settings to controller */ - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); } return 0; } -static int +static int __pmac pmac_ide_dma_read (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); @@ -1255,23 +1558,26 @@ if (pmif == NULL) return 1; - ata4 = (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80); + ata4 = (pmif->kind == controller_kl_ata4); - if (!pmac_ide_build_dmatable(drive, 0)) + if (!pmac_ide_build_dmatable(drive, rq, PCI_DMA_FROMDEVICE)) + /* try PIO instead of DMA */ return 1; + /* Apple adds 60ns to wrDataSetup on reads */ if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { writel(pmif->timings[unit]+0x00800000UL, (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); - (void)readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG)); + io_flush(readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG))); } - drive->waiting_for_dma = 1; + + drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; + /* paranoia check */ if (HWGROUP(drive)->handler != NULL) /* paranoia check */ BUG(); - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); + ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* * FIX ME to use only ACB ide_task_t args Struct */ @@ -1293,7 +1599,7 @@ return pmac_ide_dma_begin(drive); } -static int +static int __pmac pmac_ide_dma_write (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); @@ -1308,23 +1614,27 @@ if (pmif == NULL) return 1; - ata4 = (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80); + ata4 = (pmif->kind == controller_kl_ata4); - if (!pmac_ide_build_dmatable(drive, 1)) + if (!pmac_ide_build_dmatable(drive, rq, PCI_DMA_TODEVICE)) + /* try PIO instead of DMA */ return 1; + /* Apple adds 60ns to wrDataSetup on reads */ if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { writel(pmif->timings[unit], (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); - (void)readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG)); + io_flush(readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG))); } + drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; + + /* paranoia check */ if (HWGROUP(drive)->handler != NULL) /* paranoia check */ BUG(); - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); + ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* * FIX ME to use only ACB ide_task_t args Struct */ @@ -1346,13 +1656,13 @@ return pmac_ide_dma_begin(drive); } -static int +static int __pmac pmac_ide_dma_count (ide_drive_t *drive) { return HWIF(drive)->ide_dma_begin(drive); } -static int +static int __pmac pmac_ide_dma_begin (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1364,11 +1674,11 @@ writel((RUN << 16) | RUN, &dma->control); /* Make sure it gets to the controller right now */ - (void)readl(&dma->control); + io_flush(readl(&dma->control)); return 0; } -static int +static int __pmac pmac_ide_dma_end (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1387,7 +1697,7 @@ return (dstat & (RUN|DEAD|ACTIVE)) != RUN; } -static int +static int __pmac pmac_ide_dma_test_irq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1427,33 +1737,33 @@ return 1; if (!drive->waiting_for_dma) printk(KERN_WARNING "ide%d, ide_dma_test_irq \ - called while not waiting\n", pmif->index); + called while not waiting\n", HWIF(drive)->index); /* If dbdma didn't execute the STOP command yet, the * active bit is still set */ drive->waiting_for_dma++; if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { printk(KERN_WARNING "ide%d, timeout waiting \ - for dbdma command stop\n", pmif->index); + for dbdma command stop\n", HWIF(drive)->index); return 1; } udelay(1); return 0; } -static int +static int __pmac pmac_ide_dma_host_off (ide_drive_t *drive) { return 0; } -static int +static int __pmac pmac_ide_dma_host_on (ide_drive_t *drive) { return 0; } -static int +static int __pmac pmac_ide_dma_lostirq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1474,9 +1784,13 @@ { struct pmac_ide_hwif *pmif = &pmac_ide[ix]; - if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) { - printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name); - return; + if (device_is_compatible(np, "kauai-ata")) { + pmif->dma_regs = (volatile struct dbdma_regs*)(pmif->mapbase + 0x1000); + } else { + if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) { + printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name); + return; + } } pmif->dma_regs = @@ -1535,7 +1849,7 @@ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ static void __pmac -idepmac_sleep_device(ide_drive_t *drive, unsigned base) +idepmac_sleep_device(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); int j; @@ -1546,19 +1860,21 @@ switch (drive->media) { case ide_disk: /* Spin down the drive */ - hwif->OUTB(drive->select.all, base+0x60); - (void) hwif->INB(base+0x60); + SELECT_DRIVE(drive); + SELECT_MASK(drive, 0); + hwif->OUTB(drive->select.all, IDE_SELECT_REG); + io_flush(hwif->INB(IDE_SELECT_REG)); udelay(100); - hwif->OUTB(0x0, base+0x30); - hwif->OUTB(0x0, base+0x20); - hwif->OUTB(0x0, base+0x40); - hwif->OUTB(0x0, base+0x50); - hwif->OUTB(0xe0, base+0x70); - hwif->OUTB(0x2, base+0x160); + hwif->OUTB(0x00, IDE_SECTOR_REG); + hwif->OUTB(0x00, IDE_NSECTOR_REG); + hwif->OUTB(0x00, IDE_LCYL_REG); + hwif->OUTB(0x00, IDE_HCYL_REG); + hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG); + hwif->OUTB(WIN_STANDBYNOW1, IDE_COMMAND_REG); for (j = 0; j < 10; j++) { u8 status; mdelay(100); - status = hwif->INB(base+0x70); + status = hwif->INB(IDE_STATUS_REG); if (!(status & BUSY_STAT) && (status & DRQ_STAT)) break; } @@ -1637,8 +1953,8 @@ } } -static void -idepmac_sleep_drive(ide_drive_t *drive, unsigned long base) +static void __pmac +idepmac_sleep_drive(ide_drive_t *drive) { int unlock = 0; @@ -1651,13 +1967,13 @@ /* Lock HW group */ HWGROUP(drive)->busy = 1; /* Stop the device */ - idepmac_sleep_device(drive, base); + idepmac_sleep_device(drive); } if (unlock) spin_unlock_irq(&io_request_lock); } -static void +static void __pmac idepmac_wake_drive(ide_drive_t *drive, unsigned long base) { ide_hwif_t *hwif = HWIF(drive); @@ -1665,7 +1981,7 @@ int j; /* Reset timings */ - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); mdelay(10); /* Wait up to 20 seconds for the drive to be ready */ @@ -1716,7 +2032,7 @@ for (dn=0; dndrives[dn].present) continue; - idepmac_sleep_drive(&hwif->drives[dn], base); + idepmac_sleep_drive(&hwif->drives[dn]); } /* Disable irq during sleep */ disable_irq(pmac_ide[i].irq); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/raid/pdcraid.c linux.21pre4-ac6/drivers/ide/raid/pdcraid.c --- linux.21pre4/drivers/ide/raid/pdcraid.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/raid/pdcraid.c 2003-01-09 19:43:30.000000000 +0000 @@ -159,48 +159,11 @@ } -unsigned long partition_map_normal(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) +static unsigned long partition_map_normal(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) { return block + partition_off; } -unsigned long partition_map_linux(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) -{ - unsigned long newblock; - - newblock = stride - (partition_off%stride); if (newblock == stride) newblock = 0; - newblock += block; - newblock = newblock % partition_size; - newblock += partition_off; - - return newblock; -} - -static int funky_remap[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - -unsigned long partition_map_linux_raid0_4disk(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) -{ - unsigned long newblock,temp,temp2; - - newblock = stride - (partition_off%stride); if (newblock == stride) newblock = 0; - - if (block < (partition_size / (8*stride))*8*stride ) { - temp = block % stride; - temp2 = block / stride; - temp2 = ((temp2>>3)<<3)|(funky_remap[temp2&7]); - block = temp2*stride+temp; - } - - - newblock += block; - newblock = newblock % partition_size; - newblock += partition_off; - - return newblock; -} - - - static int pdcraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { unsigned long rsect; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/raid/silraid.c linux.21pre4-ac6/drivers/ide/raid/silraid.c --- linux.21pre4/drivers/ide/raid/silraid.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/raid/silraid.c 2003-01-09 19:43:30.000000000 +0000 @@ -157,7 +157,7 @@ } -unsigned long partition_map_normal(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) +static unsigned long partition_map_normal(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride) { return block + partition_off; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ide/setup-pci.c linux.21pre4-ac6/drivers/ide/setup-pci.c --- linux.21pre4/drivers/ide/setup-pci.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ide/setup-pci.c 2003-02-11 01:28:54.000000000 +0000 @@ -572,7 +572,7 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d, u8 noisy) { u32 port, at_least_one_hwif_enabled = 0, autodma = 0; - int pciirq = 0; + unsigned int pciirq = 0; int tried_config = 0; int drive0_tune, drive1_tune; ata_index_t index; @@ -612,10 +612,8 @@ pciirq = 0; } else { if (d->init_chipset) - { - if(d->init_chipset(dev, d->name) < 0) - return index; - } + d->init_chipset(dev, d->name); + if (noisy) #ifdef __sparc__ printk(KERN_INFO "%s: 100%% native mode on irq %s\n", @@ -626,9 +624,6 @@ #endif } - if(pciirq < 0) /* Error not an IRQ */ - return index; - /* * Set up the IDE ports */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ieee1394/dv1394.h linux.21pre4-ac6/drivers/ieee1394/dv1394.h --- linux.21pre4/drivers/ieee1394/dv1394.h 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/ieee1394/dv1394.h 2003-02-06 16:04:53.000000000 +0000 @@ -175,7 +175,7 @@ where copy_DV_frame() reads or writes on the dv1394 file descriptor (read/write mode) or copies data to/from the mmap ringbuffer and then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new - frames are availble (mmap mode). + frames are available (mmap mode). reset_dv1394() is called in the event of a buffer underflow/overflow or a halt in the DV stream (e.g. due to a 1394 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ieee1394/pcilynx.c linux.21pre4-ac6/drivers/ieee1394/pcilynx.c --- linux.21pre4/drivers/ieee1394/pcilynx.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ieee1394/pcilynx.c 2003-01-06 15:38:25.000000000 +0000 @@ -891,21 +891,13 @@ ssize_t retval; void *membase; - if (*offset != off) /* Check for EOF before we trust wrap */ - return 0; - - /* FIXME: Signed wrap is undefined in C - wants fixing up */ - if (off + count > off) - return 0; - - if ((off + count) > PCILYNX_MAX_MEMORY + 1) { - count = PCILYNX_MAX_MEMORY + 1 - off; + if ((off + count) > PCILYNX_MAX_MEMORY+1) { + count = PCILYNX_MAX_MEMORY+1 - off; } - if (count == 0) { - return 0; + if (count == 0 || off > PCILYNX_MAX_MEMORY) { + return -ENOSPC; } - switch (md->type) { case rom: membase = md->lynx->local_rom; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/ieee1394/sbp2.c linux.21pre4-ac6/drivers/ieee1394/sbp2.c --- linux.21pre4/drivers/ieee1394/sbp2.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/ieee1394/sbp2.c 2003-01-09 20:16:57.000000000 +0000 @@ -1511,7 +1511,7 @@ * physical dma in hardware). Mostly just here for debugging... */ static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data, - u64 addr, unsigned int length) + u64 addr, unsigned int length, u16 flags) { /* @@ -1527,7 +1527,7 @@ * physical dma in hardware). Mostly just here for debugging... */ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data, - u64 addr, unsigned int length) + u64 addr, unsigned int length, u16 flags) { /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/input/joydev.c linux.21pre4-ac6/drivers/input/joydev.c --- linux.21pre4/drivers/input/joydev.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/input/joydev.c 2003-02-06 22:33:27.000000000 +0000 @@ -388,7 +388,7 @@ case JSIOCSBTNMAP: if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC))) return -EFAULT; - for (i = 0; i < joydev->nkey; i++); { + for (i = 0; i < joydev->nkey; i++) { if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/input/keybdev.c linux.21pre4-ac6/drivers/input/keybdev.c --- linux.21pre4/drivers/input/keybdev.c 2003-01-29 16:27:04.000000000 +0000 +++ linux.21pre4-ac6/drivers/input/keybdev.c 2003-01-06 15:38:26.000000000 +0000 @@ -201,6 +201,7 @@ input_open_device(handle); // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number); + kbd_refresh_leds(); return handle; } @@ -222,6 +223,7 @@ { input_register_handler(&keybdev_handler); kbd_ledfunc = keybdev_ledfunc; + kbd_refresh_leds(); if (jp_kbd_109) { x86_keycodes[0xb5] = 0x73; /* backslash, underscore */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/input/mousedev.c linux.21pre4-ac6/drivers/input/mousedev.c --- linux.21pre4/drivers/input/mousedev.c 2003-01-29 16:27:04.000000000 +0000 +++ linux.21pre4-ac6/drivers/input/mousedev.c 2003-02-24 00:01:50.000000000 +0000 @@ -409,10 +409,13 @@ int minor = 0; if (!test_bit(EV_KEY, dev->evbit) || - (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit))) + (!test_bit(BTN_LEFT, dev->keybit) && + !test_bit(BTN_MIDDLE, dev->keybit) && + !test_bit(BTN_TOUCH, dev->keybit))) return NULL; if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) && + (!test_bit(EV_REL, dev->evbit) || !test_bit(REL_WHEEL, dev->relbit)) && (!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit))) return NULL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/isdn/hisax/st5481.h linux.21pre4-ac6/drivers/isdn/hisax/st5481.h --- linux.21pre4/drivers/isdn/hisax/st5481.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/isdn/hisax/st5481.h 2003-02-07 15:49:47.000000000 +0000 @@ -218,6 +218,19 @@ #define L1_EVENT_COUNT (EV_TIMER3 + 1) +#if (__GNUC__ > 2) + +#define ERR(format, arg...) \ +printk(KERN_ERR __FILE__ ": %s: " format "\n" , __FUNCTION__ , ## arg) + +#define WARN(format, arg...) \ +printk(KERN_WARNING __FILE__ ": %s: " format "\n" , __FUNCTION__ , ## arg) + +#define INFO(format, arg...) \ +printk(KERN_INFO __FILE__ ": %s: " format "\n" , __FUNCTION__ , ## arg) + +#else + #define ERR(format, arg...) \ printk(KERN_ERR __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg) @@ -227,6 +240,8 @@ #define INFO(format, arg...) \ printk(KERN_INFO __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg) +#endif + #include "isdnhdlc.h" #include "fsm.h" #include "hisax_if.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/isdn/hysdn/hysdn_boot.c linux.21pre4-ac6/drivers/isdn/hysdn/hysdn_boot.c --- linux.21pre4/drivers/isdn/hysdn/hysdn_boot.c 2003-01-29 16:26:56.000000000 +0000 +++ linux.21pre4-ac6/drivers/isdn/hysdn/hysdn_boot.c 2003-02-06 22:41:58.000000000 +0000 @@ -143,7 +143,7 @@ (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA", datlen, boot->pof_recoffset); - if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0)) + if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0) return (boot->last_error); /* error writing data */ if (boot->pof_recoffset + datlen >= boot->pof_reclen) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/Config.in linux.21pre4-ac6/drivers/md/Config.in --- linux.21pre4/drivers/md/Config.in 2003-01-29 16:27:04.000000000 +0000 +++ linux.21pre4-ac6/drivers/md/Config.in 2003-01-06 17:11:06.000000000 +0000 @@ -14,5 +14,8 @@ dep_tristate ' Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Device-mapper support (EXPERIMENTAL)' CONFIG_BLK_DEV_DM $CONFIG_MD +fi endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm.c linux.21pre4-ac6/drivers/md/dm.c --- linux.21pre4/drivers/md/dm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,1158 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include +#include + +/* we only need this for the lv_bmap struct definition, not happy */ +#include + +#define DEFAULT_READ_AHEAD 64 + +static const char *_name = DM_NAME; + +static int major = 0; +static int _major = 0; + +struct io_hook { + struct mapped_device *md; + struct target *target; + int rw; + + void (*end_io) (struct buffer_head * bh, int uptodate); + void *context; +}; + +static kmem_cache_t *_io_hook_cache; + +static struct mapped_device *_devs[MAX_DEVICES]; +static struct rw_semaphore _dev_locks[MAX_DEVICES]; + +/* + * This lock is only held by dm_create and dm_set_name to avoid + * race conditions where someone else may create a device with + * the same name. + */ +static spinlock_t _create_lock = SPIN_LOCK_UNLOCKED; + +/* block device arrays */ +static int _block_size[MAX_DEVICES]; +static int _blksize_size[MAX_DEVICES]; +static int _hardsect_size[MAX_DEVICES]; + +static devfs_handle_t _dev_dir; + +static int request(request_queue_t * q, int rw, struct buffer_head *bh); +static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb); + +/* + * Protect the mapped_devices referenced from _dev[] + */ +struct mapped_device *dm_get_r(int minor) +{ + struct mapped_device *md; + + if (minor >= MAX_DEVICES) + return NULL; + + down_read(_dev_locks + minor); + md = _devs[minor]; + if (!md) + up_read(_dev_locks + minor); + return md; +} + +struct mapped_device *dm_get_w(int minor) +{ + struct mapped_device *md; + + if (minor >= MAX_DEVICES) + return NULL; + + down_write(_dev_locks + minor); + md = _devs[minor]; + if (!md) + up_write(_dev_locks + minor); + return md; +} + +static int namecmp(struct mapped_device *md, const char *name, int nametype) +{ + switch (nametype) { + case DM_LOOKUP_BY_NAME: + return strcmp(md->name, name); + break; + + case DM_LOOKUP_BY_UUID: + if (!md->uuid) + return -1; /* never equal */ + + return strcmp(md->uuid, name); + break; + + default: + DMWARN("Unknown comparison type in namecmp: %d", nametype); + BUG(); + } + + return -1; +} + +/* + * The interface (eg, ioctl) will probably access the devices + * through these slow 'by name' locks, this needs improving at + * some point if people start playing with *large* numbers of dm + * devices. + */ +struct mapped_device *dm_get_name_r(const char *name, int nametype) +{ + int i; + struct mapped_device *md; + + for (i = 0; i < MAX_DEVICES; i++) { + md = dm_get_r(i); + if (md) { + if (!namecmp(md, name, nametype)) + return md; + + dm_put_r(md); + } + } + + return NULL; +} + +struct mapped_device *dm_get_name_w(const char *name, int nametype) +{ + int i; + struct mapped_device *md; + + /* + * To avoid getting write locks on all the devices we try + * and promote a read lock to a write lock, this can + * fail, in which case we just start again. + */ + + restart: + for (i = 0; i < MAX_DEVICES; i++) { + md = dm_get_r(i); + if (!md) + continue; + + if (namecmp(md, name, nametype)) { + dm_put_r(md); + continue; + } + + /* found it */ + dm_put_r(md); + + md = dm_get_w(i); + if (!md) + goto restart; + + if (namecmp(md, name, nametype)) { + dm_put_w(md); + goto restart; + } + + return md; + } + + return NULL; +} + +void dm_put_r(struct mapped_device *md) +{ + int minor = MINOR(md->dev); + + if (minor >= MAX_DEVICES) + return; + + up_read(_dev_locks + minor); +} + +void dm_put_w(struct mapped_device *md) +{ + int minor = MINOR(md->dev); + + if (minor >= MAX_DEVICES) + return; + + up_write(_dev_locks + minor); +} + +/* + * Setup and tear down the driver + */ +static __init void init_locks(void) +{ + int i; + + for (i = 0; i < MAX_DEVICES; i++) + init_rwsem(_dev_locks + i); +} + +static __init int local_init(void) +{ + int r; + + init_locks(); + + /* allocate a slab for the io-hooks */ + if (!_io_hook_cache && + !(_io_hook_cache = kmem_cache_create("dm io hooks", + sizeof(struct io_hook), + 0, 0, NULL, NULL))) + return -ENOMEM; + + _major = major; + r = devfs_register_blkdev(_major, _name, &dm_blk_dops); + if (r < 0) { + DMERR("register_blkdev failed"); + kmem_cache_destroy(_io_hook_cache); + return r; + } + + if (!_major) + _major = r; + + /* set up the arrays */ + read_ahead[_major] = DEFAULT_READ_AHEAD; + blk_size[_major] = _block_size; + blksize_size[_major] = _blksize_size; + hardsect_size[_major] = _hardsect_size; + + blk_queue_make_request(BLK_DEFAULT_QUEUE(_major), request); + + _dev_dir = devfs_mk_dir(0, DM_DIR, NULL); + + return 0; +} + +static void local_exit(void) +{ + if (kmem_cache_destroy(_io_hook_cache)) + DMWARN("io_hooks still allocated during unregistration"); + _io_hook_cache = NULL; + + if (devfs_unregister_blkdev(_major, _name) < 0) + DMERR("devfs_unregister_blkdev failed"); + + read_ahead[_major] = 0; + blk_size[_major] = NULL; + blksize_size[_major] = NULL; + hardsect_size[_major] = NULL; + _major = 0; + + DMINFO("cleaned up"); +} + +/* + * We have a lot of init/exit functions, so it seems easier to + * store them in an array. The disposable macro 'xx' + * expands a prefix into a pair of function names. + */ +static struct { + int (*init)(void); + void (*exit)(void); + +} _inits[] = { +#define xx(n) {n ## _init, n ## _exit}, + xx(local) + xx(dm_target) + xx(dm_linear) + xx(dm_stripe) + xx(dm_snapshot) + xx(dm_interface) +#undef xx +}; + +static int __init dm_init(void) +{ + const int count = sizeof(_inits) / sizeof(*_inits); + + int r, i; + + for (i = 0; i < count; i++) { + r = _inits[i].init(); + if (r) + goto bad; + } + + return 0; + + bad: + while (i--) + _inits[i].exit(); + + return r; +} + +static void __exit dm_exit(void) +{ + int i = sizeof(_inits) / sizeof(*_inits); + + dm_destroy_all(); + while (i--) + _inits[i].exit(); +} + +/* + * Block device functions + */ +static int dm_blk_open(struct inode *inode, struct file *file) +{ + struct mapped_device *md; + + md = dm_get_w(MINOR(inode->i_rdev)); + if (!md) + return -ENXIO; + + md->use_count++; + dm_put_w(md); + + return 0; +} + +static int dm_blk_close(struct inode *inode, struct file *file) +{ + struct mapped_device *md; + + md = dm_get_w(MINOR(inode->i_rdev)); + if (!md) + return -ENXIO; + + if (md->use_count < 1) + DMWARN("incorrect reference count found in mapped_device"); + + md->use_count--; + dm_put_w(md); + + return 0; +} + +/* In 512-byte units */ +#define VOLUME_SIZE(minor) (_block_size[(minor)] << 1) + +static int dm_blk_ioctl(struct inode *inode, struct file *file, + uint command, unsigned long a) +{ + int minor = MINOR(inode->i_rdev); + long size; + + if (minor >= MAX_DEVICES) + return -ENXIO; + + switch (command) { + case BLKROSET: + case BLKROGET: + case BLKRASET: + case BLKRAGET: + case BLKFLSBUF: + case BLKSSZGET: + //case BLKRRPART: /* Re-read partition tables */ + //case BLKPG: + case BLKELVGET: + case BLKELVSET: + case BLKBSZGET: + case BLKBSZSET: + return blk_ioctl(inode->i_rdev, command, a); + break; + + case BLKGETSIZE: + size = VOLUME_SIZE(minor); + if (copy_to_user((void *) a, &size, sizeof(long))) + return -EFAULT; + break; + + case BLKGETSIZE64: + size = VOLUME_SIZE(minor); + if (put_user((u64) ((u64) size) << 9, (u64 *) a)) + return -EFAULT; + break; + + case BLKRRPART: + return -ENOTTY; + + case LV_BMAP: + return dm_user_bmap(inode, (struct lv_bmap *) a); + + default: + DMWARN("unknown block ioctl 0x%x", command); + return -ENOTTY; + } + + return 0; +} + +static inline struct io_hook *alloc_io_hook(void) +{ + return kmem_cache_alloc(_io_hook_cache, GFP_NOIO); +} + +static inline void free_io_hook(struct io_hook *ih) +{ + kmem_cache_free(_io_hook_cache, ih); +} + +/* + * FIXME: We need to decide if deferred_io's need + * their own slab, I say no for now since they are + * only used when the device is suspended. + */ +static inline struct deferred_io *alloc_deferred(void) +{ + return kmalloc(sizeof(struct deferred_io), GFP_NOIO); +} + +static inline void free_deferred(struct deferred_io *di) +{ + kfree(di); +} + +/* + * Call a target's optional error function if an I/O failed. + */ +static inline int call_err_fn(struct io_hook *ih, struct buffer_head *bh) +{ + dm_err_fn err = ih->target->type->err; + + if (err) + return err(bh, ih->rw, ih->target->private); + + return 0; +} + +/* + * bh->b_end_io routine that decrements the pending count + * and then calls the original bh->b_end_io fn. + */ +static void dec_pending(struct buffer_head *bh, int uptodate) +{ + struct io_hook *ih = bh->b_private; + + if (!uptodate && call_err_fn(ih, bh)) + return; + + if (atomic_dec_and_test(&ih->md->pending)) + /* nudge anyone waiting on suspend queue */ + wake_up(&ih->md->wait); + + bh->b_end_io = ih->end_io; + bh->b_private = ih->context; + free_io_hook(ih); + + bh->b_end_io(bh, uptodate); +} + +/* + * Add the bh to the list of deferred io. + */ +static int queue_io(struct buffer_head *bh, int rw) +{ + struct deferred_io *di = alloc_deferred(); + struct mapped_device *md; + + if (!di) + return -ENOMEM; + + md = dm_get_w(MINOR(bh->b_rdev)); + if (!md) { + free_deferred(di); + return -ENXIO; + } + + if (!md->suspended) { + dm_put_w(md); + free_deferred(di); + return 1; + } + + di->bh = bh; + di->rw = rw; + di->next = md->deferred; + md->deferred = di; + + dm_put_w(md); + + return 0; /* deferred successfully */ +} + +/* + * Do the bh mapping for a given leaf + */ +static inline int __map_buffer(struct mapped_device *md, + struct buffer_head *bh, int rw, int leaf) +{ + int r; + dm_map_fn fn; + void *context; + struct io_hook *ih = NULL; + struct target *ti = md->map->targets + leaf; + + fn = ti->type->map; + context = ti->private; + + ih = alloc_io_hook(); + + if (!ih) + return -1; + + ih->md = md; + ih->rw = rw; + ih->target = ti; + ih->end_io = bh->b_end_io; + ih->context = bh->b_private; + + r = fn(bh, rw, context); + + if (r > 0) { + /* hook the end io request fn */ + atomic_inc(&md->pending); + bh->b_end_io = dec_pending; + bh->b_private = ih; + + } else if (r == 0) + /* we don't need to hook */ + free_io_hook(ih); + + else if (r < 0) { + free_io_hook(ih); + return -1; + } + + return r; +} + +/* + * Search the btree for the correct target. + */ +static inline int __find_node(struct dm_table *t, struct buffer_head *bh) +{ + int l, n = 0, k = 0; + offset_t *node; + + for (l = 0; l < t->depth; l++) { + n = get_child(n, k); + node = get_node(t, l, n); + + for (k = 0; k < KEYS_PER_NODE; k++) + if (node[k] >= bh->b_rsector) + break; + } + + return (KEYS_PER_NODE * n) + k; +} + +static int request(request_queue_t * q, int rw, struct buffer_head *bh) +{ + struct mapped_device *md; + int r, minor = MINOR(bh->b_rdev); + unsigned int block_size = _blksize_size[minor]; + + md = dm_get_r(minor); + if (!md) { + buffer_IO_error(bh); + return 0; + } + + /* + * Sanity checks. + */ + if (bh->b_size > block_size) + DMERR("request is larger than block size " + "b_size (%d), block size (%d)", + bh->b_size, block_size); + + if (bh->b_rsector & ((bh->b_size >> 9) - 1)) + DMERR("misaligned block requested logical " + "sector (%lu), b_size (%d)", + bh->b_rsector, bh->b_size); + + /* + * If we're suspended we have to queue + * this io for later. + */ + while (md->suspended) { + dm_put_r(md); + + if (rw == READA) + goto bad_no_lock; + + r = queue_io(bh, rw); + + if (r < 0) + goto bad_no_lock; + + else if (r == 0) + return 0; /* deferred successfully */ + + /* + * We're in a while loop, because someone could suspend + * before we get to the following read lock. + */ + md = dm_get_r(minor); + if (!md) { + buffer_IO_error(bh); + return 0; + } + } + + if ((r = __map_buffer(md, bh, rw, __find_node(md->map, bh))) < 0) + goto bad; + + dm_put_r(md); + return r; + + bad: + dm_put_r(md); + + bad_no_lock: + buffer_IO_error(bh); + return 0; +} + +static int check_dev_size(int minor, unsigned long block) +{ + /* FIXME: check this */ + unsigned long max_sector = (_block_size[minor] << 1) + 1; + unsigned long sector = (block + 1) * (_blksize_size[minor] >> 9); + + return (sector > max_sector) ? 0 : 1; +} + +/* + * Creates a dummy buffer head and maps it (for lilo). + */ +static int do_bmap(kdev_t dev, unsigned long block, + kdev_t * r_dev, unsigned long *r_block) +{ + struct mapped_device *md; + struct buffer_head bh; + int minor = MINOR(dev), r; + struct target *t; + + md = dm_get_r(minor); + if (!md) + return -ENXIO; + + if (md->suspended) { + dm_put_r(md); + return -EPERM; + } + + if (!check_dev_size(minor, block)) { + dm_put_r(md); + return -EINVAL; + } + + /* setup dummy bh */ + memset(&bh, 0, sizeof(bh)); + bh.b_blocknr = block; + bh.b_dev = bh.b_rdev = dev; + bh.b_size = _blksize_size[minor]; + bh.b_rsector = block * (bh.b_size >> 9); + + /* find target */ + t = md->map->targets + __find_node(md->map, &bh); + + /* do the mapping */ + r = t->type->map(&bh, READ, t->private); + + *r_dev = bh.b_rdev; + *r_block = bh.b_rsector / (bh.b_size >> 9); + + dm_put_r(md); + return r; +} + +/* + * Marshals arguments and results between user and kernel space. + */ +static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb) +{ + unsigned long block, r_block; + kdev_t r_dev; + int r; + + if (get_user(block, &lvb->lv_block)) + return -EFAULT; + + if ((r = do_bmap(inode->i_rdev, block, &r_dev, &r_block))) + return r; + + if (put_user(kdev_t_to_nr(r_dev), &lvb->lv_dev) || + put_user(r_block, &lvb->lv_block)) + return -EFAULT; + + return 0; +} + +/* + * See if the device with a specific minor # is free. The write + * lock is held when it returns successfully. + */ +static inline int specific_dev(int minor, struct mapped_device *md) +{ + if (minor >= MAX_DEVICES) { + DMWARN("request for a mapped_device beyond MAX_DEVICES (%d)", + MAX_DEVICES); + return -1; + } + + down_write(_dev_locks + minor); + if (_devs[minor]) { + /* in use */ + up_write(_dev_locks + minor); + return -1; + } + + return minor; +} + +/* + * Find the first free device. Again the write lock is held on + * success. + */ +static int any_old_dev(struct mapped_device *md) +{ + int i; + + for (i = 0; i < MAX_DEVICES; i++) + if (specific_dev(i, md) != -1) + return i; + + return -1; +} + +/* + * Allocate and initialise a blank device. + * Caller must ensure uuid is null-terminated. + * Device is returned with a write lock held. + */ +static struct mapped_device *alloc_dev(const char *name, const char *uuid, + int minor) +{ + struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); + int len; + + if (!md) { + DMWARN("unable to allocate device, out of memory."); + return NULL; + } + + memset(md, 0, sizeof(*md)); + + /* + * This grabs the write lock if it succeeds. + */ + minor = (minor < 0) ? any_old_dev(md) : specific_dev(minor, md); + if (minor < 0) { + kfree(md); + return NULL; + } + + md->dev = MKDEV(_major, minor); + md->suspended = 0; + + strncpy(md->name, name, sizeof(md->name) - 1); + md->name[sizeof(md->name) - 1] = '\0'; + + /* + * Copy in the uuid. + */ + if (uuid && *uuid) { + len = strlen(uuid) + 1; + if (!(md->uuid = kmalloc(len, GFP_KERNEL))) { + DMWARN("unable to allocate uuid - out of memory."); + kfree(md); + return NULL; + } + strcpy(md->uuid, uuid); + } + + init_waitqueue_head(&md->wait); + return md; +} + +static int __register_device(struct mapped_device *md) +{ + md->devfs_entry = + devfs_register(_dev_dir, md->name, DEVFS_FL_CURRENT_OWNER, + MAJOR(md->dev), MINOR(md->dev), + S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, + &dm_blk_dops, NULL); + + return 0; +} + +static int __unregister_device(struct mapped_device *md) +{ + devfs_unregister(md->devfs_entry); + return 0; +} + +/* + * The hardsect size for a mapped device is the largest hardsect size + * from the devices it maps onto. + */ +static int __find_hardsect_size(struct list_head *devices) +{ + int result = 512, size; + struct list_head *tmp; + + list_for_each(tmp, devices) { + struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + size = get_hardsect_size(dd->dev); + if (size > result) + result = size; + } + + return result; +} + +/* + * Bind a table to the device. + */ +static int __bind(struct mapped_device *md, struct dm_table *t) +{ + int minor = MINOR(md->dev); + + md->map = t; + + if (!t->num_targets) { + _block_size[minor] = 0; + _blksize_size[minor] = BLOCK_SIZE; + _hardsect_size[minor] = 0; + return 0; + } + + /* in k */ + _block_size[minor] = (t->highs[t->num_targets - 1] + 1) >> 1; + + _blksize_size[minor] = BLOCK_SIZE; + _hardsect_size[minor] = __find_hardsect_size(&t->devices); + register_disk(NULL, md->dev, 1, &dm_blk_dops, _block_size[minor]); + + return 0; +} + +static void __unbind(struct mapped_device *md) +{ + int minor = MINOR(md->dev); + + dm_table_destroy(md->map); + md->map = NULL; + + _block_size[minor] = 0; + _blksize_size[minor] = 0; + _hardsect_size[minor] = 0; +} + +static int check_name(const char *name) +{ + struct mapped_device *md; + + if (strchr(name, '/') || strlen(name) > DM_NAME_LEN) { + DMWARN("invalid device name"); + return -1; + } + + md = dm_get_name_r(name, DM_LOOKUP_BY_NAME); + if (md) { + dm_put_r(md); + DMWARN("device name already in use"); + return -1; + } + + return 0; +} + +static int check_uuid(const char *uuid) +{ + struct mapped_device *md; + + if (uuid) { + md = dm_get_name_r(uuid, DM_LOOKUP_BY_UUID); + if (md) { + dm_put_r(md); + DMWARN("device uuid already in use"); + return -1; + } + } + + return 0; +} + +/* + * Constructor for a new device. + */ +int dm_create(const char *name, const char *uuid, int minor, int ro, + struct dm_table *table) +{ + int r; + struct mapped_device *md; + + spin_lock(&_create_lock); + if (check_name(name) || check_uuid(uuid)) { + spin_unlock(&_create_lock); + return -EINVAL; + } + + md = alloc_dev(name, uuid, minor); + if (!md) { + spin_unlock(&_create_lock); + return -ENXIO; + } + minor = MINOR(md->dev); + _devs[minor] = md; + + r = __register_device(md); + if (r) + goto err; + + r = __bind(md, table); + if (r) + goto err; + + dm_set_ro(md, ro); + + spin_unlock(&_create_lock); + dm_put_w(md); + return 0; + + err: + _devs[minor] = NULL; + if (md->uuid) + kfree(md->uuid); + + dm_put_w(md); + kfree(md); + spin_unlock(&_create_lock); + return r; +} + +/* + * Renames the device. No lock held. + */ +int dm_set_name(const char *name, int nametype, const char *newname) +{ + int r; + struct mapped_device *md; + + spin_lock(&_create_lock); + if (check_name(newname) < 0) { + spin_unlock(&_create_lock); + return -EINVAL; + } + + md = dm_get_name_w(name, nametype); + if (!md) { + spin_unlock(&_create_lock); + return -ENXIO; + } + + r = __unregister_device(md); + if (r) + goto out; + + strcpy(md->name, newname); + r = __register_device(md); + + out: + dm_put_w(md); + spin_unlock(&_create_lock); + return r; +} + +/* + * Destructor for the device. You cannot destroy an open + * device. Write lock must be held before calling. + * Caller must dm_put_w(md) then kfree(md) if call was successful. + */ +int dm_destroy(struct mapped_device *md) +{ + int minor, r; + + if (md->use_count) + return -EPERM; + + r = __unregister_device(md); + if (r) + return r; + + minor = MINOR(md->dev); + _devs[minor] = NULL; + __unbind(md); + + if (md->uuid) + kfree(md->uuid); + + return 0; +} + +/* + * Destroy all devices - except open ones + */ +void dm_destroy_all(void) +{ + int i, some_destroyed, r; + struct mapped_device *md; + + do { + some_destroyed = 0; + for (i = 0; i < MAX_DEVICES; i++) { + md = dm_get_w(i); + if (!md) + continue; + + r = dm_destroy(md); + dm_put_w(md); + + if (!r) { + kfree(md); + some_destroyed = 1; + } + } + } while (some_destroyed); +} + +/* + * Sets or clears the read-only flag for the device. Write lock + * must be held. + */ +void dm_set_ro(struct mapped_device *md, int ro) +{ + md->read_only = ro; + set_device_ro(md->dev, ro); +} + +/* + * Requeue the deferred buffer_heads by calling generic_make_request. + */ +static void flush_deferred_io(struct deferred_io *c) +{ + struct deferred_io *n; + + while (c) { + n = c->next; + generic_make_request(c->rw, c->bh); + free_deferred(c); + c = n; + } +} + +/* + * Swap in a new table (destroying old one). Write lock must be + * held. + */ +int dm_swap_table(struct mapped_device *md, struct dm_table *table) +{ + int r; + + /* device must be suspended */ + if (!md->suspended) + return -EPERM; + + __unbind(md); + + r = __bind(md, table); + if (r) + return r; + + return 0; +} + +/* + * We need to be able to change a mapping table under a mounted + * filesystem. for example we might want to move some data in + * the background. Before the table can be swapped with + * dm_bind_table, dm_suspend must be called to flush any in + * flight buffer_heads and ensure that any further io gets + * deferred. Write lock must be held. + */ +int dm_suspend(struct mapped_device *md) +{ + int minor = MINOR(md->dev); + DECLARE_WAITQUEUE(wait, current); + + if (md->suspended) + return -EINVAL; + + md->suspended = 1; + dm_put_w(md); + + /* wait for all the pending io to flush */ + add_wait_queue(&md->wait, &wait); + current->state = TASK_UNINTERRUPTIBLE; + do { + md = dm_get_w(minor); + if (!md) { + /* Caller expects to free this lock. Yuck. */ + down_write(_dev_locks + minor); + return -ENXIO; + } + + if (!atomic_read(&md->pending)) + break; + + dm_put_w(md); + schedule(); + + } while (1); + + current->state = TASK_RUNNING; + remove_wait_queue(&md->wait, &wait); + + return 0; +} + +int dm_resume(struct mapped_device *md) +{ + int minor = MINOR(md->dev); + struct deferred_io *def; + + if (!md->suspended || !md->map->num_targets) + return -EINVAL; + + md->suspended = 0; + def = md->deferred; + md->deferred = NULL; + + dm_put_w(md); + flush_deferred_io(def); + run_task_queue(&tq_disk); + + if (!dm_get_w(minor)) { + /* FIXME: yuck */ + down_write(_dev_locks + minor); + return -ENXIO; + } + + return 0; +} + +struct block_device_operations dm_blk_dops = { + open: dm_blk_open, + release: dm_blk_close, + ioctl: dm_blk_ioctl, + owner: THIS_MODULE +}; + +/* + * module hooks + */ +module_init(dm_init); +module_exit(dm_exit); + +MODULE_PARM(major, "i"); +MODULE_PARM_DESC(major, "The major number of the device mapper"); +MODULE_DESCRIPTION(DM_NAME " driver"); +MODULE_AUTHOR("Joe Thornber "); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-exception-store.c linux.21pre4-ac6/drivers/md/dm-exception-store.c --- linux.21pre4/drivers/md/dm-exception-store.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-exception-store.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,724 @@ +/* + * dm-snapshot.c + * + * Copyright (C) 2001-2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm-snapshot.h" +#include "kcopyd.h" +#include +#include + +#define SECTOR_SIZE 512 +#define SECTOR_SHIFT 9 + +/*----------------------------------------------------------------- + * Persistent snapshots, by persistent we mean that the snapshot + * will survive a reboot. + *---------------------------------------------------------------*/ + +/* + * We need to store a record of which parts of the origin have + * been copied to the snapshot device. The snapshot code + * requires that we copy exception chunks to chunk aligned areas + * of the COW store. It makes sense therefore, to store the + * metadata in chunk size blocks. + * + * There is no backward or forward compatibility implemented, + * snapshots with different disk versions than the kernel will + * not be usable. It is expected that "lvcreate" will blank out + * the start of a fresh COW device before calling the snapshot + * constructor. + * + * The first chunk of the COW device just contains the header. + * After this there is a chunk filled with exception metadata, + * followed by as many exception chunks as can fit in the + * metadata areas. + * + * All on disk structures are in little-endian format. The end + * of the exceptions info is indicated by an exception with a + * new_chunk of 0, which is invalid since it would point to the + * header chunk. + */ + +/* + * Magic for persistent snapshots: "SnAp" - Feeble isn't it. + */ +#define SNAP_MAGIC 0x70416e53 + +/* + * The on-disk version of the metadata. + */ +#define SNAPSHOT_DISK_VERSION 1 + +struct disk_header { + uint32_t magic; + + /* + * Is this snapshot valid. There is no way of recovering + * an invalid snapshot. + */ + int valid; + + /* + * Simple, incrementing version. no backward + * compatibility. + */ + uint32_t version; + + /* In sectors */ + uint32_t chunk_size; +}; + +struct disk_exception { + uint64_t old_chunk; + uint64_t new_chunk; +}; + +struct commit_callback { + void (*callback)(void *, int success); + void *context; +}; + +/* + * The top level structure for a persistent exception store. + */ +struct pstore { + struct dm_snapshot *snap; /* up pointer to my snapshot */ + int version; + int valid; + uint32_t chunk_size; + uint32_t exceptions_per_area; + + /* + * Now that we have an asynchronous kcopyd there is no + * need for large chunk sizes, so it wont hurt to have a + * whole chunks worth of metadata in memory at once. + */ + void *area; + struct kiobuf *iobuf; + + /* + * Used to keep track of which metadata area the data in + * 'chunk' refers to. + */ + uint32_t current_area; + + /* + * The next free chunk for an exception. + */ + uint32_t next_free; + + /* + * The index of next free exception in the current + * metadata area. + */ + uint32_t current_committed; + + atomic_t pending_count; + uint32_t callback_count; + struct commit_callback *callbacks; +}; + +/* + * For performance reasons we want to defer writing a committed + * exceptions metadata to disk so that we can amortise away this + * exensive operation. + * + * For the initial version of this code we will remain with + * synchronous io. There are some deadlock issues with async + * that I haven't yet worked out. + */ +static int do_io(int rw, struct kcopyd_region *where, struct kiobuf *iobuf) +{ + int i, sectors_per_block, nr_blocks, start; + int blocksize = get_hardsect_size(where->dev); + int status; + + sectors_per_block = blocksize / SECTOR_SIZE; + + nr_blocks = where->count / sectors_per_block; + start = where->sector / sectors_per_block; + + for (i = 0; i < nr_blocks; i++) + iobuf->blocks[i] = start++; + + iobuf->length = where->count << 9; + iobuf->locked = 1; + + status = brw_kiovec(rw, 1, &iobuf, where->dev, iobuf->blocks, + blocksize); + if (status != (where->count << 9)) + return -EIO; + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION ( 2, 4, 19) +/* + * FIXME: Remove once 2.4.19 has been released. + */ +struct page *vmalloc_to_page(void *vmalloc_addr) +{ + unsigned long addr = (unsigned long) vmalloc_addr; + struct page *page = NULL; + pmd_t *pmd; + pte_t *pte; + pgd_t *pgd; + + pgd = pgd_offset_k(addr); + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, addr); + if (!pmd_none(*pmd)) { + pte = pte_offset(pmd, addr); + if (pte_present(*pte)) { + page = pte_page(*pte); + } + } + } + return page; +} +#endif + +static int allocate_iobuf(struct pstore *ps) +{ + size_t i, r = -ENOMEM, len, nr_pages; + struct page *page; + + len = ps->chunk_size << SECTOR_SHIFT; + + /* + * Allocate the chunk_size block of memory that will hold + * a single metadata area. + */ + ps->area = vmalloc(len); + if (!ps->area) + return r; + + if (alloc_kiovec(1, &ps->iobuf)) + goto bad; + + nr_pages = ps->chunk_size / (PAGE_SIZE / SECTOR_SIZE); + r = expand_kiobuf(ps->iobuf, nr_pages); + if (r) + goto bad; + + /* + * We lock the pages for ps->area into memory since they'll be + * doing a lot of io. + */ + for (i = 0; i < nr_pages; i++) { + page = vmalloc_to_page(ps->area + (i * PAGE_SIZE)); + LockPage(page); + ps->iobuf->maplist[i] = page; + ps->iobuf->nr_pages++; + } + + ps->iobuf->nr_pages = nr_pages; + ps->iobuf->offset = 0; + + return 0; + + bad: + if (ps->iobuf) + free_kiovec(1, &ps->iobuf); + + if (ps->area) + vfree(ps->area); + ps->iobuf = NULL; + return r; +} + +static void free_iobuf(struct pstore *ps) +{ + int i; + + for (i = 0; i < ps->iobuf->nr_pages; i++) + UnlockPage(ps->iobuf->maplist[i]); + ps->iobuf->locked = 0; + + free_kiovec(1, &ps->iobuf); + vfree(ps->area); +} + +/* + * Read or write a chunk aligned and sized block of data from a device. + */ +static int chunk_io(struct pstore *ps, uint32_t chunk, int rw) +{ + int r; + struct kcopyd_region where; + + where.dev = ps->snap->cow->dev; + where.sector = ps->chunk_size * chunk; + where.count = ps->chunk_size; + + r = do_io(rw, &where, ps->iobuf); + if (r) + return r; + + return 0; +} + +/* + * Read or write a metadata area. Remembering to skip the first + * chunk which holds the header. + */ +static int area_io(struct pstore *ps, uint32_t area, int rw) +{ + int r; + uint32_t chunk; + + /* convert a metadata area index to a chunk index */ + chunk = 1 + ((ps->exceptions_per_area + 1) * area); + + r = chunk_io(ps, chunk, rw); + if (r) + return r; + + ps->current_area = area; + return 0; +} + +static int zero_area(struct pstore *ps, uint32_t area) +{ + memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); + return area_io(ps, area, WRITE); +} + +static int read_header(struct pstore *ps, int *new_snapshot) +{ + int r; + struct disk_header *dh; + + r = chunk_io(ps, 0, READ); + if (r) + return r; + + dh = (struct disk_header *) ps->area; + + if (dh->magic == 0) { + *new_snapshot = 1; + + } else if (dh->magic == SNAP_MAGIC) { + *new_snapshot = 0; + ps->valid = dh->valid; + ps->version = dh->version; + ps->chunk_size = dh->chunk_size; + + } else { + DMWARN("Invalid/corrupt snapshot"); + r = -ENXIO; + } + + return r; +} + +static int write_header(struct pstore *ps) +{ + struct disk_header *dh; + + memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); + + dh = (struct disk_header *) ps->area; + dh->magic = SNAP_MAGIC; + dh->valid = ps->valid; + dh->version = ps->version; + dh->chunk_size = ps->chunk_size; + + return chunk_io(ps, 0, WRITE); +} + +/* + * Access functions for the disk exceptions, these do the endian conversions. + */ +static struct disk_exception *get_exception(struct pstore *ps, uint32_t index) +{ + if (index >= ps->exceptions_per_area) + return NULL; + + return ((struct disk_exception *) ps->area) + index; +} + +static int read_exception(struct pstore *ps, + uint32_t index, struct disk_exception *result) +{ + struct disk_exception *e; + + e = get_exception(ps, index); + if (!e) + return -EINVAL; + + /* copy it */ + result->old_chunk = le64_to_cpu(e->old_chunk); + result->new_chunk = le64_to_cpu(e->new_chunk); + + return 0; +} + +static int write_exception(struct pstore *ps, + uint32_t index, struct disk_exception *de) +{ + struct disk_exception *e; + + e = get_exception(ps, index); + if (!e) + return -EINVAL; + + /* copy it */ + e->old_chunk = cpu_to_le64(de->old_chunk); + e->new_chunk = cpu_to_le64(de->new_chunk); + + return 0; +} + +/* + * Registers the exceptions that are present in the current area. + * 'full' is filled in to indicate if the area has been + * filled. + */ +static int insert_exceptions(struct pstore *ps, int *full) +{ + int i, r; + struct disk_exception de; + + /* presume the area is full */ + *full = 1; + + for (i = 0; i < ps->exceptions_per_area; i++) { + r = read_exception(ps, i, &de); + + if (r) + return r; + + /* + * If the new_chunk is pointing at the start of + * the COW device, where the first metadata area + * is we know that we've hit the end of the + * exceptions. Therefore the area is not full. + */ + if (de.new_chunk == 0LL) { + ps->current_committed = i; + *full = 0; + break; + } + + /* + * Keep track of the start of the free chunks. + */ + if (ps->next_free <= de.new_chunk) + ps->next_free = de.new_chunk + 1; + + /* + * Otherwise we add the exception to the snapshot. + */ + r = dm_add_exception(ps->snap, de.old_chunk, de.new_chunk); + if (r) + return r; + } + + return 0; +} + +static int read_exceptions(struct pstore *ps) +{ + uint32_t area; + int r, full = 1; + + /* + * Keeping reading chunks and inserting exceptions until + * we find a partially full area. + */ + for (area = 0; full; area++) { + r = area_io(ps, area, READ); + if (r) + return r; + + r = insert_exceptions(ps, &full); + if (r) + return r; + + area++; + } + + return 0; +} + +static inline struct pstore *get_info(struct exception_store *store) +{ + return (struct pstore *) store->context; +} + +static int persistent_percentfull(struct exception_store *store) +{ + struct pstore *ps = get_info(store); + return (ps->next_free * store->snap->chunk_size * 100) / + get_dev_size(store->snap->cow->dev); +} + +static void persistent_destroy(struct exception_store *store) +{ + struct pstore *ps = get_info(store); + + vfree(ps->callbacks); + free_iobuf(ps); + kfree(ps); +} + +static int persistent_prepare(struct exception_store *store, + struct exception *e) +{ + struct pstore *ps = get_info(store); + uint32_t stride; + offset_t size = get_dev_size(store->snap->cow->dev); + + /* Is there enough room ? */ + if (size <= (ps->next_free * store->snap->chunk_size)) + return -ENOSPC; + + e->new_chunk = ps->next_free; + + /* + * Move onto the next free pending, making sure to take + * into account the location of the metadata chunks. + */ + stride = (ps->exceptions_per_area + 1); + if (!(++ps->next_free % stride)) + ps->next_free++; + + atomic_inc(&ps->pending_count); + return 0; +} + +static void persistent_commit(struct exception_store *store, + struct exception *e, + void (*callback) (void *, int success), + void *callback_context) +{ + int r, i; + struct pstore *ps = get_info(store); + struct disk_exception de; + struct commit_callback *cb; + + de.old_chunk = e->old_chunk; + de.new_chunk = e->new_chunk; + write_exception(ps, ps->current_committed++, &de); + + /* + * Add the callback to the back of the array. This code + * is the only place where the callback array is + * manipulated, and we know that it will never be called + * multiple times concurrently. + */ + cb = ps->callbacks + ps->callback_count++; + cb->callback = callback; + cb->context = callback_context; + + /* + * If there are no more exceptions in flight, or we have + * filled this metadata area we commit the exceptions to + * disk. + */ + if (atomic_dec_and_test(&ps->pending_count) || + (ps->current_committed == ps->exceptions_per_area)) { + r = area_io(ps, ps->current_area, WRITE); + if (r) + ps->valid = 0; + + for (i = 0; i < ps->callback_count; i++) { + cb = ps->callbacks + i; + cb->callback(cb->context, r == 0 ? 1 : 0); + } + + ps->callback_count = 0; + } + + /* + * Have we completely filled the current area ? + */ + if (ps->current_committed == ps->exceptions_per_area) { + ps->current_committed = 0; + r = zero_area(ps, ps->current_area + 1); + if (r) + ps->valid = 0; + } +} + +static void persistent_drop(struct exception_store *store) +{ + struct pstore *ps = get_info(store); + + ps->valid = 0; + if (write_header(ps)) + DMWARN("write header failed"); +} + +int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) +{ + int r, new_snapshot; + struct pstore *ps; + + /* allocate the pstore */ + ps = kmalloc(sizeof(*ps), GFP_KERNEL); + if (!ps) + return -ENOMEM; + + ps->snap = store->snap; + ps->valid = 1; + ps->version = SNAPSHOT_DISK_VERSION; + ps->chunk_size = chunk_size; + ps->exceptions_per_area = (chunk_size << SECTOR_SHIFT) / + sizeof(struct disk_exception); + ps->next_free = 2; /* skipping the header and first area */ + ps->current_committed = 0; + + r = allocate_iobuf(ps); + if (r) + goto bad; + + /* + * Allocate space for all the callbacks. + */ + ps->callback_count = 0; + atomic_set(&ps->pending_count, 0); + ps->callbacks = vcalloc(ps->exceptions_per_area, + sizeof(*ps->callbacks)); + + if (!ps->callbacks) + goto bad; + + /* + * Read the snapshot header. + */ + r = read_header(ps, &new_snapshot); + if (r) + goto bad; + + /* + * Do we need to setup a new snapshot ? + */ + if (new_snapshot) { + r = write_header(ps); + if (r) { + DMWARN("write_header failed"); + goto bad; + } + + r = zero_area(ps, 0); + if (r) { + DMWARN("zero_area(0) failed"); + goto bad; + } + + } else { + /* + * Sanity checks. + */ + if (ps->chunk_size != chunk_size) { + DMWARN("chunk size for existing snapshot different " + "from that requested"); + r = -EINVAL; + goto bad; + } + + if (ps->version != SNAPSHOT_DISK_VERSION) { + DMWARN("unable to handle snapshot disk version %d", + ps->version); + r = -EINVAL; + goto bad; + } + + /* + * Read the metadata. + */ + r = read_exceptions(ps); + if (r) + goto bad; + } + + store->destroy = persistent_destroy; + store->prepare_exception = persistent_prepare; + store->commit_exception = persistent_commit; + store->drop_snapshot = persistent_drop; + store->percent_full = persistent_percentfull; + store->context = ps; + + return r; + + bad: + if (ps) { + if (ps->callbacks) + vfree(ps->callbacks); + + if (ps->iobuf) + free_iobuf(ps); + + kfree(ps); + } + return r; +} + +/*----------------------------------------------------------------- + * Implementation of the store for non-persistent snapshots. + *---------------------------------------------------------------*/ +struct transient_c { + offset_t next_free; +}; + +void transient_destroy(struct exception_store *store) +{ + kfree(store->context); +} + +int transient_prepare(struct exception_store *store, struct exception *e) +{ + struct transient_c *tc = (struct transient_c *) store->context; + offset_t size = get_dev_size(store->snap->cow->dev); + + if (size < (tc->next_free + store->snap->chunk_size)) + return -1; + + e->new_chunk = sector_to_chunk(store->snap, tc->next_free); + tc->next_free += store->snap->chunk_size; + + return 0; +} + +void transient_commit(struct exception_store *store, + struct exception *e, + void (*callback) (void *, int success), + void *callback_context) +{ + /* Just succeed */ + callback(callback_context, 1); +} + +static int transient_percentfull(struct exception_store *store) +{ + struct transient_c *tc = (struct transient_c *) store->context; + return (tc->next_free * 100) / get_dev_size(store->snap->cow->dev); +} + +int dm_create_transient(struct exception_store *store, + struct dm_snapshot *s, int blocksize, void **error) +{ + struct transient_c *tc; + + memset(store, 0, sizeof(*store)); + store->destroy = transient_destroy; + store->prepare_exception = transient_prepare; + store->commit_exception = transient_commit; + store->percent_full = transient_percentfull; + store->snap = s; + + tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); + if (!tc) + return -ENOMEM; + + tc->next_free = 0; + store->context = tc; + + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm.h linux.21pre4-ac6/drivers/md/dm.h --- linux.21pre4/drivers/md/dm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,241 @@ +/* + * Internal header file for device mapper + * + * Copyright (C) 2001 Sistina Software + * + * This file is released under the LGPL. + */ + +#ifndef DM_INTERNAL_H +#define DM_INTERNAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DM_NAME "device-mapper" /* Name for messaging */ +#define DM_DRIVER_EMAIL "lvm-devel@lists.sistina.com" +#define MAX_DEPTH 16 +#define NODE_SIZE L1_CACHE_BYTES +#define KEYS_PER_NODE (NODE_SIZE / sizeof(offset_t)) +#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) +#define MAX_ARGS 32 +#define MAX_DEVICES 256 + +/* + * List of devices that a metadevice uses and should open/close. + */ +struct dm_dev { + atomic_t count; + struct list_head list; + + int mode; + + kdev_t dev; + struct block_device *bd; +}; + +/* + * I/O that had to be deferred while we were suspended + */ +struct deferred_io { + int rw; + struct buffer_head *bh; + struct deferred_io *next; +}; + +/* + * Btree leaf - this does the actual mapping + */ +struct target { + struct target_type *type; + void *private; +}; + +/* + * The btree + */ +struct dm_table { + /* btree table */ + int depth; + int counts[MAX_DEPTH]; /* in nodes */ + offset_t *index[MAX_DEPTH]; + + int num_targets; + int num_allocated; + offset_t *highs; + struct target *targets; + + /* + * Indicates the rw permissions for the new logical + * device. This should be a combination of FMODE_READ + * and FMODE_WRITE. + */ + int mode; + + /* a list of devices used by this table */ + struct list_head devices; + + /* + * A waitqueue for processes waiting for something + * interesting to happen to this table. + */ + wait_queue_head_t eventq; +}; + +/* + * The actual device struct + */ +struct mapped_device { + kdev_t dev; + char name[DM_NAME_LEN]; + char *uuid; + + int use_count; + int suspended; + int read_only; + + /* a list of io's that arrived while we were suspended */ + atomic_t pending; + wait_queue_head_t wait; + struct deferred_io *deferred; + + struct dm_table *map; + + /* used by dm-fs.c */ + devfs_handle_t devfs_entry; +}; + +extern struct block_device_operations dm_blk_dops; + +/* dm-target.c */ +int dm_target_init(void); +struct target_type *dm_get_target_type(const char *name); +void dm_put_target_type(struct target_type *t); +void dm_target_exit(void); + +/* + * Destructively splits argument list to pass to ctr. + */ +int split_args(int max, int *argc, char **argv, char *input); + +/* dm.c */ +struct mapped_device *dm_get_r(int minor); +struct mapped_device *dm_get_w(int minor); + +/* + * There are two ways to lookup a device. + */ +enum { + DM_LOOKUP_BY_NAME, + DM_LOOKUP_BY_UUID +}; + +struct mapped_device *dm_get_name_r(const char *name, int nametype); +struct mapped_device *dm_get_name_w(const char *name, int nametype); + +void dm_put_r(struct mapped_device *md); +void dm_put_w(struct mapped_device *md); + +/* + * Call with no lock. + */ +int dm_create(const char *name, const char *uuid, int minor, int ro, + struct dm_table *table); +int dm_set_name(const char *name, int nametype, const char *newname); +void dm_destroy_all(void); + +/* + * You must have the write lock before calling the remaining md + * methods. + */ +int dm_destroy(struct mapped_device *md); +void dm_set_ro(struct mapped_device *md, int ro); + +/* + * The device must be suspended before calling this method. + */ +int dm_swap_table(struct mapped_device *md, struct dm_table *t); + +/* + * A device can still be used while suspended, but I/O is deferred. + */ +int dm_suspend(struct mapped_device *md); +int dm_resume(struct mapped_device *md); + +/* dm-table.c */ +int dm_table_create(struct dm_table **result, int mode); +void dm_table_destroy(struct dm_table *t); + +int dm_table_add_target(struct dm_table *t, offset_t highs, + struct target_type *type, void *private); +int dm_table_complete(struct dm_table *t); + +/* + * Event handling + */ +void dm_table_event(struct dm_table *t); + +#define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x) +#define DMERR(f, x...) printk(KERN_ERR DM_NAME ": " f "\n" , ## x) +#define DMINFO(f, x...) printk(KERN_INFO DM_NAME ": " f "\n" , ## x) + +/* + * Calculate the index of the child node of the n'th node k'th key. + */ +static inline int get_child(int n, int k) +{ + return (n * CHILDREN_PER_NODE) + k; +} + +/* + * Return the n'th node of level l from table t. + */ +static inline offset_t *get_node(struct dm_table *t, int l, int n) +{ + return t->index[l] + (n * KEYS_PER_NODE); +} + +static inline int array_too_big(unsigned long fixed, unsigned long obj, + unsigned long num) +{ + return (num > (ULONG_MAX - fixed) / obj); +} + + +/* + * Targets + */ +int dm_linear_init(void); +void dm_linear_exit(void); + +int dm_stripe_init(void); +void dm_stripe_exit(void); + +int dm_snapshot_init(void); +void dm_snapshot_exit(void); + + +/* + * Init functions for the user interface to device-mapper. At + * the moment an ioctl interface on a special char device is + * used. A filesystem based interface would be a nicer way to + * go. + */ +int __init dm_interface_init(void); +void dm_interface_exit(void); + + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-ioctl.c linux.21pre4-ac6/drivers/md/dm-ioctl.c --- linux.21pre4/drivers/md/dm-ioctl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-ioctl.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,830 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include +#include +#include +#include + +/*----------------------------------------------------------------- + * Implementation of the ioctl commands + *---------------------------------------------------------------*/ + +/* + * All the ioctl commands get dispatched to functions with this + * prototype. + */ +typedef int (*ioctl_fn)(struct dm_ioctl *param, struct dm_ioctl *user); + +/* + * This is really a debug only call. + */ +static int remove_all(struct dm_ioctl *param, struct dm_ioctl *user) +{ + dm_destroy_all(); + return 0; +} + +/* + * Check a string doesn't overrun the chunk of + * memory we copied from userland. + */ +static int valid_str(char *str, void *begin, void *end) +{ + while (((void *) str >= begin) && ((void *) str < end)) + if (!*str++) + return 0; + + return -EINVAL; +} + +static int next_target(struct dm_target_spec *last, uint32_t next, + void *begin, void *end, + struct dm_target_spec **spec, char **params) +{ + *spec = (struct dm_target_spec *) + ((unsigned char *) last + next); + *params = (char *) (*spec + 1); + + if (*spec < (last + 1) || ((void *) *spec > end)) + return -EINVAL; + + return valid_str(*params, begin, end); +} + +/* + * Checks to see if there's a gap in the table. + * Returns true iff there is a gap. + */ +static int gap(struct dm_table *table, struct dm_target_spec *spec) +{ + if (!table->num_targets) + return (spec->sector_start > 0) ? 1 : 0; + + if (spec->sector_start != table->highs[table->num_targets - 1] + 1) + return 1; + + return 0; +} + +static int populate_table(struct dm_table *table, struct dm_ioctl *args) +{ + int i = 0, r, first = 1, argc; + struct dm_target_spec *spec; + char *params, *argv[MAX_ARGS]; + struct target_type *ttype; + void *context, *begin, *end; + offset_t highs = 0; + + if (!args->target_count) { + DMWARN("populate_table: no targets specified"); + return -EINVAL; + } + + begin = (void *) args; + end = begin + args->data_size; + +#define PARSE_ERROR(msg) {DMWARN(msg); return -EINVAL;} + + for (i = 0; i < args->target_count; i++) { + + if (first) + r = next_target((struct dm_target_spec *) args, + args->data_start, + begin, end, &spec, ¶ms); + else + r = next_target(spec, spec->next, begin, end, + &spec, ¶ms); + + if (r) + PARSE_ERROR("unable to find target"); + + /* Look up the target type */ + ttype = dm_get_target_type(spec->target_type); + if (!ttype) + PARSE_ERROR("unable to find target type"); + + if (gap(table, spec)) + PARSE_ERROR("gap in target ranges"); + + /* Split up the parameter list */ + if (split_args(MAX_ARGS, &argc, argv, params) < 0) + PARSE_ERROR("Too many arguments"); + + /* Build the target */ + if (ttype->ctr(table, spec->sector_start, spec->length, + argc, argv, &context)) { + DMWARN("%s: target constructor failed", + (char *) context); + return -EINVAL; + } + + /* Add the target to the table */ + highs = spec->sector_start + (spec->length - 1); + if (dm_table_add_target(table, highs, ttype, context)) + PARSE_ERROR("internal error adding target to table"); + + first = 0; + } + +#undef PARSE_ERROR + + r = dm_table_complete(table); + return r; +} + +/* + * Round up the ptr to the next 'align' boundary. Obviously + * 'align' must be a power of 2. + */ +static inline void *align_ptr(void *ptr, unsigned int align) +{ + align--; + return (void *) (((unsigned long) (ptr + align)) & ~align); +} + +/* + * Copies a dm_ioctl and an optional additional payload to + * userland. + */ +static int results_to_user(struct dm_ioctl *user, struct dm_ioctl *param, + void *data, uint32_t len) +{ + int r; + void *ptr = NULL; + + if (data) { + ptr = align_ptr(user + 1, sizeof(unsigned long)); + param->data_start = ptr - (void *) user; + } + + /* + * The version number has already been filled in, so we + * just copy later fields. + */ + r = copy_to_user(&user->data_size, ¶m->data_size, + sizeof(*param) - sizeof(param->version)); + if (r) + return -EFAULT; + + if (data) { + if (param->data_start + len > param->data_size) + return -ENOSPC; + + if (copy_to_user(ptr, data, len)) + r = -EFAULT; + } + + return r; +} + +/* + * Fills in a dm_ioctl structure, ready for sending back to + * userland. + */ +static void __info(struct mapped_device *md, struct dm_ioctl *param) +{ + param->flags = DM_EXISTS_FLAG; + if (md->suspended) + param->flags |= DM_SUSPEND_FLAG; + if (md->read_only) + param->flags |= DM_READONLY_FLAG; + + strncpy(param->name, md->name, sizeof(param->name)); + + if (md->uuid) + strncpy(param->uuid, md->uuid, sizeof(param->uuid) - 1); + else + param->uuid[0] = '\0'; + + param->open_count = md->use_count; + param->dev = kdev_t_to_nr(md->dev); + param->target_count = md->map->num_targets; +} + +/* + * Always use UUID for lookups if it's present, otherwise use name. + */ +static inline char *lookup_name(struct dm_ioctl *param) +{ + return (*param->uuid) ? param->uuid : param->name; +} + +static inline int lookup_type(struct dm_ioctl *param) +{ + return (*param->uuid) ? DM_LOOKUP_BY_UUID : DM_LOOKUP_BY_NAME; +} + +#define ALIGNMENT sizeof(int) +static void *_align(void *ptr, unsigned int a) +{ + register unsigned long align = --a; + + return (void *) (((unsigned long) ptr + align) & ~align); +} + +/* + * Copies device info back to user space, used by + * the create and info ioctls. + */ +static int info(struct dm_ioctl *param, struct dm_ioctl *user) +{ + struct mapped_device *md; + + param->flags = 0; + + md = dm_get_name_r(lookup_name(param), lookup_type(param)); + if (!md) + /* + * Device not found - returns cleared exists flag. + */ + goto out; + + __info(md, param); + dm_put_r(md); + + out: + return results_to_user(user, param, NULL, 0); +} + +static inline int get_mode(struct dm_ioctl *param) +{ + int mode = FMODE_READ | FMODE_WRITE; + + if (param->flags & DM_READONLY_FLAG) + mode = FMODE_READ; + + return mode; +} + +static int create(struct dm_ioctl *param, struct dm_ioctl *user) +{ + int r, ro; + struct dm_table *t; + int minor; + + r = dm_table_create(&t, get_mode(param)); + if (r) + return r; + + r = populate_table(t, param); + if (r) { + dm_table_destroy(t); + return r; + } + + minor = (param->flags & DM_PERSISTENT_DEV_FLAG) ? + MINOR(to_kdev_t(param->dev)) : -1; + + ro = (param->flags & DM_READONLY_FLAG) ? 1 : 0; + + r = dm_create(param->name, param->uuid, minor, ro, t); + if (r) { + dm_table_destroy(t); + return r; + } + + r = info(param, user); + return r; +} + + + +/* + * Build up the status struct for each target + */ +static int __status(struct mapped_device *md, struct dm_ioctl *param, + char *outbuf, int *len) +{ + int i; + struct dm_target_spec *spec; + uint64_t sector = 0LL; + char *outptr; + status_type_t type; + + if (param->flags & DM_STATUS_TABLE_FLAG) + type = STATUSTYPE_TABLE; + else + type = STATUSTYPE_INFO; + + outptr = outbuf; + + /* Get all the target info */ + for (i = 0; i < md->map->num_targets; i++) { + struct target_type *tt = md->map->targets[i].type; + offset_t high = md->map->highs[i]; + + if (outptr - outbuf + + sizeof(struct dm_target_spec) > param->data_size) + return -ENOMEM; + + spec = (struct dm_target_spec *) outptr; + + spec->status = 0; + spec->sector_start = sector; + spec->length = high - sector + 1; + strncpy(spec->target_type, tt->name, sizeof(spec->target_type)); + + outptr += sizeof(struct dm_target_spec); + + /* Get the status/table string from the target driver */ + if (tt->status) + tt->status(type, outptr, + outbuf + param->data_size - outptr, + md->map->targets[i].private); + else + outptr[0] = '\0'; + + outptr += strlen(outptr) + 1; + _align(outptr, ALIGNMENT); + + sector = high + 1; + + spec->next = outptr - outbuf; + } + + param->target_count = md->map->num_targets; + *len = outptr - outbuf; + + return 0; +} + +/* + * Return the status of a device as a text string for each + * target. + */ +static int get_status(struct dm_ioctl *param, struct dm_ioctl *user) +{ + struct mapped_device *md; + int len = 0; + int ret; + char *outbuf = NULL; + + md = dm_get_name_r(lookup_name(param), lookup_type(param)); + if (!md) + /* + * Device not found - returns cleared exists flag. + */ + goto out; + + /* We haven't a clue how long the resultant data will be so + just allocate as much as userland has allowed us and make sure + we don't overun it */ + outbuf = kmalloc(param->data_size, GFP_KERNEL); + if (!outbuf) + goto out; + /* + * Get the status of all targets + */ + __status(md, param, outbuf, &len); + + /* + * Setup the basic dm_ioctl structure. + */ + __info(md, param); + + out: + if (md) + dm_put_r(md); + + ret = results_to_user(user, param, outbuf, len); + + if (outbuf) + kfree(outbuf); + + return ret; +} + +/* + * Wait for a device to report an event + */ +static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user) +{ + struct mapped_device *md; + DECLARE_WAITQUEUE(wq, current); + + md = dm_get_name_r(lookup_name(param), lookup_type(param)); + if (!md) + /* + * Device not found - returns cleared exists flag. + */ + goto out; + /* + * Setup the basic dm_ioctl structure. + */ + __info(md, param); + + /* + * Wait for a notification event + */ + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&md->map->eventq, &wq); + + dm_put_r(md); + + schedule(); + set_current_state(TASK_RUNNING); + + out: + return results_to_user(user, param, NULL, 0); +} + +/* + * Retrieves a list of devices used by a particular dm device. + */ +static int dep(struct dm_ioctl *param, struct dm_ioctl *user) +{ + int count, r; + struct mapped_device *md; + struct list_head *tmp; + size_t len = 0; + struct dm_target_deps *deps = NULL; + + md = dm_get_name_r(lookup_name(param), lookup_type(param)); + if (!md) + goto out; + + /* + * Setup the basic dm_ioctl structure. + */ + __info(md, param); + + /* + * Count the devices. + */ + count = 0; + list_for_each(tmp, &md->map->devices) + count++; + + /* + * Allocate a kernel space version of the dm_target_status + * struct. + */ + if (array_too_big(sizeof(*deps), sizeof(*deps->dev), count)) { + dm_put_r(md); + return -ENOMEM; + } + + len = sizeof(*deps) + (sizeof(*deps->dev) * count); + deps = kmalloc(len, GFP_KERNEL); + if (!deps) { + dm_put_r(md); + return -ENOMEM; + } + + /* + * Fill in the devices. + */ + deps->count = count; + count = 0; + list_for_each(tmp, &md->map->devices) { + struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + deps->dev[count++] = kdev_t_to_nr(dd->dev); + } + dm_put_r(md); + + out: + r = results_to_user(user, param, deps, len); + + kfree(deps); + return r; +} + +static int remove(struct dm_ioctl *param, struct dm_ioctl *user) +{ + int r; + struct mapped_device *md; + + md = dm_get_name_w(lookup_name(param), lookup_type(param)); + if (!md) + return -ENXIO; + + r = dm_destroy(md); + dm_put_w(md); + if (!r) + kfree(md); + + return r; +} + +static int suspend(struct dm_ioctl *param, struct dm_ioctl *user) +{ + int r; + struct mapped_device *md; + + md = dm_get_name_w(lookup_name(param), lookup_type(param)); + if (!md) + return -ENXIO; + + r = (param->flags & DM_SUSPEND_FLAG) ? dm_suspend(md) : dm_resume(md); + dm_put_w(md); + + return r; +} + +static int reload(struct dm_ioctl *param, struct dm_ioctl *user) +{ + int r; + struct mapped_device *md; + struct dm_table *t; + + r = dm_table_create(&t, get_mode(param)); + if (r) + return r; + + r = populate_table(t, param); + if (r) { + dm_table_destroy(t); + return r; + } + + md = dm_get_name_w(lookup_name(param), lookup_type(param)); + if (!md) { + dm_table_destroy(t); + return -ENXIO; + } + + r = dm_swap_table(md, t); + if (r) { + dm_put_w(md); + dm_table_destroy(t); + return r; + } + + dm_set_ro(md, (param->flags & DM_READONLY_FLAG) ? 1 : 0); + dm_put_w(md); + + r = info(param, user); + return r; +} + +static int rename(struct dm_ioctl *param, struct dm_ioctl *user) +{ + char *newname = (char *) param + param->data_start; + + if (valid_str(newname, (void *) param, + (void *) param + param->data_size) || + dm_set_name(lookup_name(param), lookup_type(param), newname)) { + DMWARN("Invalid new logical volume name supplied."); + return -EINVAL; + } + + return 0; +} + + +/*----------------------------------------------------------------- + * Implementation of open/close/ioctl on the special char + * device. + *---------------------------------------------------------------*/ +static int ctl_open(struct inode *inode, struct file *file) +{ + /* only root can open this */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + MOD_INC_USE_COUNT; + + return 0; +} + +static int ctl_close(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +static ioctl_fn lookup_ioctl(unsigned int cmd) +{ + static struct { + int cmd; + ioctl_fn fn; + } _ioctls[] = { + {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ + {DM_REMOVE_ALL_CMD, remove_all}, + {DM_DEV_CREATE_CMD, create}, + {DM_DEV_REMOVE_CMD, remove}, + {DM_DEV_RELOAD_CMD, reload}, + {DM_DEV_RENAME_CMD, rename}, + {DM_DEV_SUSPEND_CMD, suspend}, + {DM_DEV_DEPS_CMD, dep}, + {DM_DEV_STATUS_CMD, info}, + {DM_TARGET_STATUS_CMD, get_status}, + {DM_TARGET_WAIT_CMD, wait_device_event}, + }; + static int nelts = sizeof(_ioctls) / sizeof(*_ioctls); + + return (cmd >= nelts) ? NULL : _ioctls[cmd].fn; +} + +/* + * As well as checking the version compatibility this always + * copies the kernel interface version out. + */ +static int check_version(int cmd, struct dm_ioctl *user) +{ + uint32_t version[3]; + int r = 0; + + if (copy_from_user(version, user->version, sizeof(version))) + return -EFAULT; + + if ((DM_VERSION_MAJOR != version[0]) || + (DM_VERSION_MINOR < version[1])) { + DMWARN("ioctl interface mismatch: " + "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)", + DM_VERSION_MAJOR, DM_VERSION_MINOR, + DM_VERSION_PATCHLEVEL, + version[0], version[1], version[2], cmd); + r = -EINVAL; + } + + /* + * Fill in the kernel version. + */ + version[0] = DM_VERSION_MAJOR; + version[1] = DM_VERSION_MINOR; + version[2] = DM_VERSION_PATCHLEVEL; + if (copy_to_user(user->version, version, sizeof(version))) + return -EFAULT; + + return r; +} + +static void free_params(struct dm_ioctl *param) +{ + vfree(param); +} + +static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param) +{ + struct dm_ioctl tmp, *dmi; + + if (copy_from_user(&tmp, user, sizeof(tmp))) + return -EFAULT; + + if (tmp.data_size < sizeof(tmp) || tmp.data_size > 65536) + return -EINVAL; + + dmi = (struct dm_ioctl *) vmalloc(tmp.data_size); + if (!dmi) + return -ENOMEM; + + if (copy_from_user(dmi, user, tmp.data_size)) { + vfree(dmi); + return -EFAULT; + } + + *param = dmi; + return 0; +} + +static int validate_params(uint cmd, struct dm_ioctl *param) +{ + /* Ignores parameters */ + if (cmd == DM_REMOVE_ALL_CMD) + return 0; + + /* Unless creating, either name of uuid but not both */ + if (cmd != DM_DEV_CREATE_CMD) { + if ((!*param->uuid && !*param->name) || + (*param->uuid && *param->name)) { + DMWARN("one of name or uuid must be supplied"); + return -EINVAL; + } + } + + /* Ensure strings are terminated */ + param->name[DM_NAME_LEN - 1] = '\0'; + param->uuid[DM_UUID_LEN - 1] = '\0'; + + return 0; +} + +static int ctl_ioctl(struct inode *inode, struct file *file, + uint command, ulong u) +{ + + int r = 0, cmd; + struct dm_ioctl *param; + struct dm_ioctl *user = (struct dm_ioctl *) u; + ioctl_fn fn = NULL; + + if (_IOC_TYPE(command) != DM_IOCTL) + return -ENOTTY; + + cmd = _IOC_NR(command); + + /* + * Check the interface version passed in. This also + * writes out the kernel's interface version. + */ + r = check_version(cmd, user); + if (r) + return r; + + /* + * Nothing more to do for the version command. + */ + if (cmd == DM_VERSION_CMD) + return 0; + + fn = lookup_ioctl(cmd); + if (!fn) { + DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); + return -ENOTTY; + } + + /* + * Copy the parameters into kernel space. + */ + r = copy_params(user, ¶m); + if (r) + return r; + + r = validate_params(cmd, param); + if (r) { + free_params(param); + return r; + } + + r = fn(param, user); + free_params(param); + return r; +} + +static struct file_operations _ctl_fops = { + open: ctl_open, + release: ctl_close, + ioctl: ctl_ioctl, + owner: THIS_MODULE, +}; + +static devfs_handle_t _ctl_handle; + +static struct miscdevice _dm_misc = { + minor: MISC_DYNAMIC_MINOR, + name: DM_NAME, + fops: &_ctl_fops +}; + +static int __init dm_devfs_init(void) { + int r; + char rname[64]; + + r = devfs_generate_path(_dm_misc.devfs_handle, rname + 3, + sizeof rname - 3); + if (r == -ENOSYS) + return 0; /* devfs not present */ + + if (r < 0) { + DMERR("devfs_generate_path failed for control device"); + return r; + } + + strncpy(rname + r, "../", 3); + r = devfs_mk_symlink(NULL, DM_DIR "/control", + DEVFS_FL_DEFAULT, rname + r, &_ctl_handle, NULL); + if (r) { + DMERR("devfs_mk_symlink failed for control device"); + return r; + } + devfs_auto_unregister(_dm_misc.devfs_handle, _ctl_handle); + + return 0; +} + +/* Create misc character device and link to DM_DIR/control */ +int __init dm_interface_init(void) +{ + int r; + + r = misc_register(&_dm_misc); + if (r) { + DMERR("misc_register failed for control device"); + return r; + } + + r = dm_devfs_init(); + if (r) { + misc_deregister(&_dm_misc); + return r; + } + + DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR, + DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA, + DM_DRIVER_EMAIL); + + return 0; +} + +void dm_interface_exit(void) +{ + if (misc_deregister(&_dm_misc) < 0) + DMERR("misc_deregister failed for control device"); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-linear.c linux.21pre4-ac6/drivers/md/dm-linear.c --- linux.21pre4/drivers/md/dm-linear.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-linear.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include +#include +#include + +/* + * Linear: maps a linear range of a device. + */ +struct linear_c { + long delta; /* FIXME: we need a signed offset type */ + long start; /* For display only */ + struct dm_dev *dev; +}; + +/* + * Construct a linear mapping: + */ +static int linear_ctr(struct dm_table *t, offset_t b, offset_t l, + int argc, char **argv, void **context) +{ + struct linear_c *lc; + unsigned long start; /* FIXME: unsigned long long */ + char *end; + + if (argc != 2) { + *context = "dm-linear: Not enough arguments"; + return -EINVAL; + } + + lc = kmalloc(sizeof(*lc), GFP_KERNEL); + if (lc == NULL) { + *context = "dm-linear: Cannot allocate linear context"; + return -ENOMEM; + } + + start = simple_strtoul(argv[1], &end, 10); + if (*end) { + *context = "dm-linear: Invalid device sector"; + goto bad; + } + + if (dm_table_get_device(t, argv[0], start, l, t->mode, &lc->dev)) { + *context = "dm-linear: Device lookup failed"; + goto bad; + } + + lc->delta = (int) start - (int) b; + lc->start = start; + *context = lc; + return 0; + + bad: + kfree(lc); + return -EINVAL; +} + +static void linear_dtr(struct dm_table *t, void *c) +{ + struct linear_c *lc = (struct linear_c *) c; + + dm_table_put_device(t, lc->dev); + kfree(c); +} + +static int linear_map(struct buffer_head *bh, int rw, void *context) +{ + struct linear_c *lc = (struct linear_c *) context; + + bh->b_rdev = lc->dev->dev; + bh->b_rsector = bh->b_rsector + lc->delta; + + return 1; +} + +static int linear_status(status_type_t type, char *result, int maxlen, + void *context) +{ + struct linear_c *lc = (struct linear_c *) context; + + switch (type) { + case STATUSTYPE_INFO: + result[0] = '\0'; + break; + + case STATUSTYPE_TABLE: + snprintf(result, maxlen, "%s %ld", kdevname(lc->dev->dev), + lc->start); + break; + } + return 0; +} + +static struct target_type linear_target = { + name: "linear", + module: THIS_MODULE, + ctr: linear_ctr, + dtr: linear_dtr, + map: linear_map, + status: linear_status, +}; + +int __init dm_linear_init(void) +{ + int r = dm_register_target(&linear_target); + + if (r < 0) + DMERR("linear: register failed %d", r); + + return r; +} + +void dm_linear_exit(void) +{ + int r = dm_unregister_target(&linear_target); + + if (r < 0) + DMERR("linear: unregister failed %d", r); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-snapshot.c linux.21pre4-ac6/drivers/md/dm-snapshot.c --- linux.21pre4/drivers/md/dm-snapshot.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-snapshot.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,1169 @@ +/* + * dm-snapshot.c + * + * Copyright (C) 2001-2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm-snapshot.h" +#include "kcopyd.h" + +/* + * FIXME: Remove this before release. + */ +#if 0 +#define DMDEBUG(x...) DMWARN( ## x) +#else +#define DMDEBUG(x...) +#endif + +/* + * The percentage increment we will wake up users at + */ +#define WAKE_UP_PERCENT 5 + +/* + * Hard sector size used all over the kernel + */ +#define SECTOR_SIZE 512 + +/* + * kcopyd priority of snapshot operations + */ +#define SNAPSHOT_COPY_PRIORITY 2 + +struct pending_exception { + struct exception e; + + /* + * Origin buffers waiting for this to complete are held + * in a list (using b_reqnext). + */ + struct buffer_head *origin_bhs; + struct buffer_head *snapshot_bhs; + + /* + * Other pending_exceptions that are processing this + * chunk. When this list is empty, we know we can + * complete the origins. + */ + struct list_head siblings; + + /* Pointer back to snapshot context */ + struct dm_snapshot *snap; + + /* + * 1 indicates the exception has already been sent to + * kcopyd. + */ + int started; +}; + +/* + * Hash table mapping origin volumes to lists of snapshots and + * a lock to protect it + */ +static kmem_cache_t *exception_cache; +static kmem_cache_t *pending_cache; +static mempool_t *pending_pool; + +/* + * One of these per registered origin, held in the snapshot_origins hash + */ +struct origin { + /* The origin device */ + kdev_t dev; + + struct list_head hash_list; + + /* List of snapshots for this origin */ + struct list_head snapshots; +}; + +/* + * Size of the hash table for origin volumes. If we make this + * the size of the minors list then it should be nearly perfect + */ +#define ORIGIN_HASH_SIZE 256 +#define ORIGIN_MASK 0xFF +static struct list_head *_origins; +static struct rw_semaphore _origins_lock; + +static int init_origin_hash(void) +{ + int i; + + _origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), + GFP_KERNEL); + if (!_origins) { + DMERR("Device mapper: Snapshot: unable to allocate memory"); + return -ENOMEM; + } + + for (i = 0; i < ORIGIN_HASH_SIZE; i++) + INIT_LIST_HEAD(_origins + i); + init_rwsem(&_origins_lock); + + return 0; +} + +static void exit_origin_hash(void) +{ + kfree(_origins); +} + +static inline unsigned int origin_hash(kdev_t dev) +{ + return MINOR(dev) & ORIGIN_MASK; +} + +static struct origin *__lookup_origin(kdev_t origin) +{ + struct list_head *slist; + struct list_head *ol; + struct origin *o; + + ol = &_origins[origin_hash(origin)]; + list_for_each(slist, ol) { + o = list_entry(slist, struct origin, hash_list); + + if (o->dev == origin) + return o; + } + + return NULL; +} + +static void __insert_origin(struct origin *o) +{ + struct list_head *sl = &_origins[origin_hash(o->dev)]; + list_add_tail(&o->hash_list, sl); +} + +/* + * Make a note of the snapshot and its origin so we can look it + * up when the origin has a write on it. + */ +static int register_snapshot(struct dm_snapshot *snap) +{ + struct origin *o; + kdev_t dev = snap->origin->dev; + + down_write(&_origins_lock); + o = __lookup_origin(dev); + + if (!o) { + /* New origin */ + o = kmalloc(sizeof(*o), GFP_KERNEL); + if (!o) { + up_write(&_origins_lock); + return -ENOMEM; + } + + /* Initialise the struct */ + INIT_LIST_HEAD(&o->snapshots); + o->dev = dev; + + __insert_origin(o); + } + + list_add_tail(&snap->list, &o->snapshots); + + up_write(&_origins_lock); + return 0; +} + +static void unregister_snapshot(struct dm_snapshot *s) +{ + struct origin *o; + + down_write(&_origins_lock); + o = __lookup_origin(s->origin->dev); + + list_del(&s->list); + if (list_empty(&o->snapshots)) { + list_del(&o->hash_list); + kfree(o); + } + + up_write(&_origins_lock); +} + +/* + * Implementation of the exception hash tables. + */ +static int init_exception_table(struct exception_table *et, uint32_t size) +{ + int i; + + et->hash_mask = size - 1; + et->table = vcalloc(size, sizeof(struct list_head)); + if (!et->table) + return -ENOMEM; + + for (i = 0; i < size; i++) + INIT_LIST_HEAD(et->table + i); + + return 0; +} + +static void exit_exception_table(struct exception_table *et, kmem_cache_t *mem) +{ + struct list_head *slot, *entry, *temp; + struct exception *ex; + int i, size; + + size = et->hash_mask + 1; + for (i = 0; i < size; i++) { + slot = et->table + i; + + list_for_each_safe(entry, temp, slot) { + ex = list_entry(entry, struct exception, hash_list); + kmem_cache_free(mem, ex); + } + } + + vfree(et->table); +} + +/* + * FIXME: check how this hash fn is performing. + */ +static inline uint32_t exception_hash(struct exception_table *et, chunk_t chunk) +{ + return chunk & et->hash_mask; +} + +static void insert_exception(struct exception_table *eh, struct exception *e) +{ + struct list_head *l = &eh->table[exception_hash(eh, e->old_chunk)]; + list_add(&e->hash_list, l); +} + +static inline void remove_exception(struct exception *e) +{ + list_del(&e->hash_list); +} + +/* + * Return the exception data for a sector, or NULL if not + * remapped. + */ +static struct exception *lookup_exception(struct exception_table *et, + chunk_t chunk) +{ + struct list_head *slot, *el; + struct exception *e; + + slot = &et->table[exception_hash(et, chunk)]; + list_for_each(el, slot) { + e = list_entry(el, struct exception, hash_list); + if (e->old_chunk == chunk) + return e; + } + + return NULL; +} + +static inline struct exception *alloc_exception(void) +{ + struct exception *e; + + e = kmem_cache_alloc(exception_cache, GFP_NOIO); + if (!e) + e = kmem_cache_alloc(exception_cache, GFP_ATOMIC); + + return e; +} + +static inline void free_exception(struct exception *e) +{ + kmem_cache_free(exception_cache, e); +} + +static inline struct pending_exception *alloc_pending_exception(void) +{ + return mempool_alloc(pending_pool, GFP_NOIO); +} + +static inline void free_pending_exception(struct pending_exception *pe) +{ + mempool_free(pe, pending_pool); +} + +int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new) +{ + struct exception *e; + + e = alloc_exception(); + if (!e) + return -ENOMEM; + + e->old_chunk = old; + e->new_chunk = new; + insert_exception(&s->complete, e); + return 0; +} + +/* + * Hard coded magic. + */ +static int calc_max_buckets(void) +{ + unsigned long mem; + + mem = num_physpages << PAGE_SHIFT; + mem /= 50; + mem /= sizeof(struct list_head); + + return mem; +} + +/* + * Rounds a number down to a power of 2. + */ +static inline uint32_t round_down(uint32_t n) +{ + while (n & (n - 1)) + n &= (n - 1); + return n; +} + +/* + * Allocate room for a suitable hash table. + */ +static int init_hash_tables(struct dm_snapshot *s) +{ + offset_t hash_size, cow_dev_size, origin_dev_size, max_buckets; + + /* + * Calculate based on the size of the original volume or + * the COW volume... + */ + cow_dev_size = get_dev_size(s->cow->dev); + origin_dev_size = get_dev_size(s->origin->dev); + max_buckets = calc_max_buckets(); + + hash_size = min(origin_dev_size, cow_dev_size) / s->chunk_size; + hash_size = min(hash_size, max_buckets); + + /* Round it down to a power of 2 */ + hash_size = round_down(hash_size); + if (init_exception_table(&s->complete, hash_size)) + return -ENOMEM; + + /* + * Allocate hash table for in-flight exceptions + * Make this smaller than the real hash table + */ + hash_size >>= 3; + if (!hash_size) + hash_size = 64; + + if (init_exception_table(&s->pending, hash_size)) { + exit_exception_table(&s->complete, exception_cache); + return -ENOMEM; + } + + return 0; +} + +/* + * Round a number up to the nearest 'size' boundary. size must + * be a power of 2. + */ +static inline ulong round_up(ulong n, ulong size) +{ + size--; + return (n + size) & ~size; +} + +/* + * Construct a snapshot mapping:

+ */ +static int snapshot_ctr(struct dm_table *t, offset_t b, offset_t l, + int argc, char **argv, void **context) +{ + struct dm_snapshot *s; + unsigned long chunk_size; + int r = -EINVAL; + char *persistent; + char *origin_path; + char *cow_path; + char *value; + int blocksize; + + if (argc < 4) { + *context = "dm-snapshot: requires exactly 4 arguments"; + r = -EINVAL; + goto bad; + } + + origin_path = argv[0]; + cow_path = argv[1]; + persistent = argv[2]; + + if ((*persistent & 0x5f) != 'P' && (*persistent & 0x5f) != 'N') { + *context = "Persistent flag is not P or N"; + r = -EINVAL; + goto bad; + } + + chunk_size = simple_strtoul(argv[3], &value, 10); + if (chunk_size == 0 || value == NULL) { + *context = "Invalid chunk size"; + r = -EINVAL; + goto bad; + } + + s = kmalloc(sizeof(*s), GFP_KERNEL); + if (s == NULL) { + *context = "Cannot allocate snapshot context private structure"; + r = -ENOMEM; + goto bad; + } + + r = dm_table_get_device(t, origin_path, 0, 0, FMODE_READ, &s->origin); + if (r) { + *context = "Cannot get origin device"; + goto bad_free; + } + + r = dm_table_get_device(t, cow_path, 0, 0, + FMODE_READ | FMODE_WRITE, &s->cow); + if (r) { + dm_table_put_device(t, s->origin); + *context = "Cannot get COW device"; + goto bad_free; + } + + /* + * Chunk size must be multiple of page size. Silently + * round up if it's not. + */ + chunk_size = round_up(chunk_size, PAGE_SIZE / SECTOR_SIZE); + + /* Validate the chunk size against the device block size */ + blocksize = get_hardsect_size(s->cow->dev); + if (chunk_size % (blocksize / SECTOR_SIZE)) { + *context = "Chunk size is not a multiple of device blocksize"; + r = -EINVAL; + goto bad_putdev; + } + + /* Check the sizes are small enough to fit in one kiovec */ + if (chunk_size > KIO_MAX_SECTORS) { + *context = "Chunk size is too big"; + r = -EINVAL; + goto bad_putdev; + } + + /* Check chunk_size is a power of 2 */ + if (chunk_size & (chunk_size - 1)) { + *context = "Chunk size is not a power of 2"; + r = -EINVAL; + goto bad_putdev; + } + + s->chunk_size = chunk_size; + s->chunk_mask = chunk_size - 1; + s->type = *persistent; + for (s->chunk_shift = 0; chunk_size; + s->chunk_shift++, chunk_size >>= 1) + ; + s->chunk_shift--; + + s->valid = 1; + s->last_percent = 0; + s->table = t; + init_rwsem(&s->lock); + + /* Allocate hash table for COW data */ + if (init_hash_tables(s)) { + *context = "Unable to allocate hash table space"; + r = -ENOMEM; + goto bad_putdev; + } + + /* + * Check the persistent flag - done here because we need the iobuf + * to check the LV header + */ + s->store.snap = s; + + if ((*persistent & 0x5f) == 'P') + r = dm_create_persistent(&s->store, s->chunk_size); + else + r = dm_create_transient(&s->store, s, blocksize, context); + + if (r) { + *context = "Couldn't create exception store"; + r = -EINVAL; + goto bad_free1; + } + + /* Flush IO to the origin device */ +#if LVM_VFS_ENHANCEMENT + fsync_dev_lockfs(s->origin->dev); +#else + fsync_dev(s->origin->dev); +#endif + + /* Add snapshot to the list of snapshots for this origin */ + if (register_snapshot(s)) { + r = -EINVAL; + *context = "Cannot register snapshot origin"; + goto bad_free2; + } +#if LVM_VFS_ENHANCEMENT + unlockfs(s->origin->dev); +#endif + kcopyd_inc_client_count(); + + *context = s; + return 0; + + bad_free2: + s->store.destroy(&s->store); + + bad_free1: + exit_exception_table(&s->pending, pending_cache); + exit_exception_table(&s->complete, exception_cache); + + bad_putdev: + dm_table_put_device(t, s->cow); + dm_table_put_device(t, s->origin); + + bad_free: + kfree(s); + + bad: + return r; +} + +static void snapshot_dtr(struct dm_table *t, void *context) +{ + struct dm_snapshot *s = (struct dm_snapshot *) context; + + dm_table_event(s->table); + + unregister_snapshot(s); + + exit_exception_table(&s->pending, pending_cache); + exit_exception_table(&s->complete, exception_cache); + + /* Deallocate memory used */ + s->store.destroy(&s->store); + + dm_table_put_device(t, s->origin); + dm_table_put_device(t, s->cow); + kfree(s); + + kcopyd_dec_client_count(); +} + +/* + * We hold lists of buffer_heads, using the b_reqnext field. + */ +static void queue_buffer(struct buffer_head **queue, struct buffer_head *bh) +{ + bh->b_reqnext = *queue; + *queue = bh; +} + +/* + * Flush a list of buffers. + */ +static void flush_buffers(struct buffer_head *bh) +{ + struct buffer_head *n; + + DMDEBUG("begin flush"); + while (bh) { + n = bh->b_reqnext; + bh->b_reqnext = NULL; + DMDEBUG("flushing %p", bh); + generic_make_request(WRITE, bh); + bh = n; + } + + run_task_queue(&tq_disk); +} + +/* + * Error a list of buffers. + */ +static void error_buffers(struct buffer_head *bh) +{ + struct buffer_head *n; + + while (bh) { + n = bh->b_reqnext; + bh->b_reqnext = NULL; + buffer_IO_error(bh); + bh = n; + } +} + +static void pending_complete(struct pending_exception *pe, int success) +{ + struct exception *e; + struct dm_snapshot *s = pe->snap; + + if (success) { + e = alloc_exception(); + if (!e) { + printk("Unable to allocate exception."); + down_write(&s->lock); + s->store.drop_snapshot(&s->store); + s->valid = 0; + up_write(&s->lock); + return; + } + + /* + * Add a proper exception, and remove the + * inflight exception from the list. + */ + down_write(&s->lock); + + memcpy(e, &pe->e, sizeof(*e)); + insert_exception(&s->complete, e); + remove_exception(&pe->e); + + /* Submit any pending write BHs */ + up_write(&s->lock); + + flush_buffers(pe->snapshot_bhs); + DMDEBUG("Exception completed successfully."); + + /* Notify any interested parties */ + if (s->store.percent_full) { + int pc = s->store.percent_full(&s->store); + + if (pc >= s->last_percent + WAKE_UP_PERCENT) { + dm_table_event(s->table); + s->last_percent = pc - pc % WAKE_UP_PERCENT; + } + } + + } else { + /* Read/write error - snapshot is unusable */ + DMERR("Error reading/writing snapshot"); + + down_write(&s->lock); + s->store.drop_snapshot(&s->store); + s->valid = 0; + remove_exception(&pe->e); + up_write(&s->lock); + + error_buffers(pe->snapshot_bhs); + + dm_table_event(s->table); + DMDEBUG("Exception failed."); + } + + if (list_empty(&pe->siblings)) + flush_buffers(pe->origin_bhs); + else + list_del(&pe->siblings); + + free_pending_exception(pe); +} + +static void commit_callback(void *context, int success) +{ + struct pending_exception *pe = (struct pending_exception *) context; + pending_complete(pe, success); +} + +/* + * Called when the copy I/O has finished. kcopyd actually runs + * this code so don't block. + */ +static void copy_callback(int err, void *context) +{ + struct pending_exception *pe = (struct pending_exception *) context; + struct dm_snapshot *s = pe->snap; + + if (err) + pending_complete(pe, 0); + + else + /* Update the metadata if we are persistent */ + s->store.commit_exception(&s->store, &pe->e, commit_callback, + pe); +} + +/* + * Dispatches the copy operation to kcopyd. + */ +static inline void start_copy(struct pending_exception *pe) +{ + struct dm_snapshot *s = pe->snap; + struct kcopyd_region src, dest; + + src.dev = s->origin->dev; + src.sector = chunk_to_sector(s, pe->e.old_chunk); + src.count = s->chunk_size; + + dest.dev = s->cow->dev; + dest.sector = chunk_to_sector(s, pe->e.new_chunk); + dest.count = s->chunk_size; + + if (!pe->started) { + /* Hand over to kcopyd */ + kcopyd_copy(&src, &dest, copy_callback, pe); + pe->started = 1; + } +} + +/* + * Looks to see if this snapshot already has a pending exception + * for this chunk, otherwise it allocates a new one and inserts + * it into the pending table. + */ +static struct pending_exception *find_pending_exception(struct dm_snapshot *s, + struct buffer_head *bh) +{ + struct exception *e; + struct pending_exception *pe; + chunk_t chunk = sector_to_chunk(s, bh->b_rsector); + + /* + * Is there a pending exception for this already ? + */ + e = lookup_exception(&s->pending, chunk); + if (e) { + /* cast the exception to a pending exception */ + pe = list_entry(e, struct pending_exception, e); + + } else { + /* Create a new pending exception */ + pe = alloc_pending_exception(); + if (!pe) { + DMWARN("Couldn't allocate pending exception."); + return NULL; + } + + pe->e.old_chunk = chunk; + pe->origin_bhs = pe->snapshot_bhs = NULL; + INIT_LIST_HEAD(&pe->siblings); + pe->snap = s; + pe->started = 0; + + if (s->store.prepare_exception(&s->store, &pe->e)) { + free_pending_exception(pe); + s->valid = 0; + return NULL; + } + + insert_exception(&s->pending, &pe->e); + } + + return pe; +} + +static inline void remap_exception(struct dm_snapshot *s, struct exception *e, + struct buffer_head *bh) +{ + bh->b_rdev = s->cow->dev; + bh->b_rsector = chunk_to_sector(s, e->new_chunk) + + (bh->b_rsector & s->chunk_mask); +} + +static int snapshot_map(struct buffer_head *bh, int rw, void *context) +{ + struct exception *e; + struct dm_snapshot *s = (struct dm_snapshot *) context; + int r = 1; + chunk_t chunk; + struct pending_exception *pe; + + chunk = sector_to_chunk(s, bh->b_rsector); + + /* Full snapshots are not usable */ + if (!s->valid) + return -1; + + /* + * Write to snapshot - higher level takes care of RW/RO + * flags so we should only get this if we are + * writeable. + */ + if (rw == WRITE) { + + down_write(&s->lock); + + /* If the block is already remapped - use that, else remap it */ + e = lookup_exception(&s->complete, chunk); + if (e) + remap_exception(s, e, bh); + + else { + pe = find_pending_exception(s, bh); + + if (!pe) { + s->store.drop_snapshot(&s->store); + s->valid = 0; + } + + queue_buffer(&pe->snapshot_bhs, bh); + start_copy(pe); + r = 0; + } + + up_write(&s->lock); + + } else { + /* + * FIXME: this read path scares me because we + * always use the origin when we have a pending + * exception. However I can't think of a + * situation where this is wrong - ejt. + */ + + /* Do reads */ + down_read(&s->lock); + + /* See if it it has been remapped */ + e = lookup_exception(&s->complete, chunk); + if (e) + remap_exception(s, e, bh); + else + bh->b_rdev = s->origin->dev; + + up_read(&s->lock); + } + + return r; +} + +static void list_merge(struct list_head *l1, struct list_head *l2) +{ + struct list_head *l1_n, *l2_p; + + l1_n = l1->next; + l2_p = l2->prev; + + l1->next = l2; + l2->prev = l1; + + l2_p->next = l1_n; + l1_n->prev = l2_p; +} + +static int __origin_write(struct list_head *snapshots, struct buffer_head *bh) +{ + int r = 1; + struct list_head *sl; + struct dm_snapshot *snap; + struct exception *e; + struct pending_exception *pe, *last = NULL; + chunk_t chunk; + + /* Do all the snapshots on this origin */ + list_for_each(sl, snapshots) { + snap = list_entry(sl, struct dm_snapshot, list); + + /* Only deal with valid snapshots */ + if (!snap->valid) + continue; + + down_write(&snap->lock); + + /* + * Remember, different snapshots can have + * different chunk sizes. + */ + chunk = sector_to_chunk(snap, bh->b_rsector); + + /* + * Check exception table to see if block + * is already remapped in this snapshot + * and trigger an exception if not. + */ + e = lookup_exception(&snap->complete, chunk); + if (!e) { + pe = find_pending_exception(snap, bh); + if (!pe) { + snap->store.drop_snapshot(&snap->store); + snap->valid = 0; + + } else { + if (last) + list_merge(&pe->siblings, + &last->siblings); + + last = pe; + r = 0; + } + } + + up_write(&snap->lock); + } + + /* + * Now that we have a complete pe list we can start the copying. + */ + if (last) { + pe = last; + do { + down_write(&pe->snap->lock); + queue_buffer(&pe->origin_bhs, bh); + start_copy(pe); + up_write(&pe->snap->lock); + pe = list_entry(pe->siblings.next, + struct pending_exception, siblings); + + } while (pe != last); + } + + return r; +} + +static int snapshot_status(status_type_t type, char *result, + int maxlen, void *context) +{ + struct dm_snapshot *snap = (struct dm_snapshot *) context; + char cow[16]; + char org[16]; + + switch (type) { + case STATUSTYPE_INFO: + if (!snap->valid) + snprintf(result, maxlen, "Invalid"); + else { + if (snap->store.percent_full) + snprintf(result, maxlen, "%d%%", + snap->store.percent_full(&snap-> + store)); + else + snprintf(result, maxlen, "Unknown"); + } + break; + + case STATUSTYPE_TABLE: + /* + * kdevname returns a static pointer so we need + * to make private copies if the output is to + * make sense. + */ + strncpy(cow, kdevname(snap->cow->dev), sizeof(cow)); + strncpy(org, kdevname(snap->origin->dev), sizeof(org)); + snprintf(result, maxlen, "%s %s %c %ld", org, cow, + snap->type, snap->chunk_size); + break; + } + + return 0; +} + +/* + * Called on a write from the origin driver. + */ +int do_origin(struct dm_dev *origin, struct buffer_head *bh) +{ + struct origin *o; + int r; + + down_read(&_origins_lock); + o = __lookup_origin(origin->dev); + if (!o) + BUG(); + + r = __origin_write(&o->snapshots, bh); + up_read(&_origins_lock); + + return r; +} + +/* + * Origin: maps a linear range of a device, with hooks for snapshotting. + */ + +/* + * Construct an origin mapping: + * The context for an origin is merely a 'struct dm_dev *' + * pointing to the real device. + */ +static int origin_ctr(struct dm_table *t, offset_t b, offset_t l, + int argc, char **argv, void **context) +{ + int r; + struct dm_dev *dev; + + if (argc != 1) { + *context = "dm-origin: incorrect number of arguments"; + return -EINVAL; + } + + r = dm_table_get_device(t, argv[0], 0, l, t->mode, &dev); + if (r) { + *context = "Cannot get target device"; + return r; + } + + *context = dev; + + return 0; +} + +static void origin_dtr(struct dm_table *t, void *c) +{ + struct dm_dev *dev = (struct dm_dev *) c; + dm_table_put_device(t, dev); +} + +static int origin_map(struct buffer_head *bh, int rw, void *context) +{ + struct dm_dev *dev = (struct dm_dev *) context; + bh->b_rdev = dev->dev; + + /* Only tell snapshots if this is a write */ + return (rw == WRITE) ? do_origin(dev, bh) : 1; +} + +static int origin_status(status_type_t type, char *result, + int maxlen, void *context) +{ + struct dm_dev *dev = (struct dm_dev *) context; + + switch (type) { + case STATUSTYPE_INFO: + result[0] = '\0'; + break; + + case STATUSTYPE_TABLE: + snprintf(result, maxlen, "%s", kdevname(dev->dev)); + break; + } + + return 0; +} + +static struct target_type origin_target = { + name: "snapshot-origin", + module: THIS_MODULE, + ctr: origin_ctr, + dtr: origin_dtr, + map: origin_map, + status: origin_status, + err: NULL +}; + +static struct target_type snapshot_target = { + name: "snapshot", + module: THIS_MODULE, + ctr: snapshot_ctr, + dtr: snapshot_dtr, + map: snapshot_map, + status: snapshot_status, + err: NULL +}; + +int __init dm_snapshot_init(void) +{ + int r; + + r = dm_register_target(&snapshot_target); + if (r) { + DMERR("snapshot target register failed %d", r); + return r; + } + + r = dm_register_target(&origin_target); + if (r < 0) { + DMERR("Device mapper: Origin: register failed %d\n", r); + goto bad1; + } + + r = init_origin_hash(); + if (r) { + DMERR("init_origin_hash failed."); + goto bad2; + } + + exception_cache = kmem_cache_create("dm-snapshot-ex", + sizeof(struct exception), + __alignof__(struct exception), + 0, NULL, NULL); + if (!exception_cache) { + DMERR("Couldn't create exception cache."); + r = -ENOMEM; + goto bad3; + } + + pending_cache = + kmem_cache_create("dm-snapshot-in", + sizeof(struct pending_exception), + __alignof__(struct pending_exception), + 0, NULL, NULL); + if (!pending_cache) { + DMERR("Couldn't create pending cache."); + r = -ENOMEM; + goto bad4; + } + + pending_pool = mempool_create(128, mempool_alloc_slab, + mempool_free_slab, pending_cache); + if (!pending_pool) { + DMERR("Couldn't create pending pool."); + r = -ENOMEM; + goto bad5; + } + + return 0; + + bad5: + kmem_cache_destroy(pending_cache); + bad4: + kmem_cache_destroy(exception_cache); + bad3: + exit_origin_hash(); + bad2: + dm_unregister_target(&origin_target); + bad1: + dm_unregister_target(&snapshot_target); + return r; +} + +void dm_snapshot_exit(void) +{ + int r; + + r = dm_unregister_target(&snapshot_target); + if (r) + DMERR("snapshot unregister failed %d", r); + + r = dm_unregister_target(&origin_target); + if (r) + DMERR("origin unregister failed %d", r); + + exit_origin_hash(); + mempool_destroy(pending_pool); + kmem_cache_destroy(pending_cache); + kmem_cache_destroy(exception_cache); +} + +/* + * 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-file-style: "linux" + * End: + */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-snapshot.h linux.21pre4-ac6/drivers/md/dm-snapshot.h --- linux.21pre4/drivers/md/dm-snapshot.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-snapshot.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,147 @@ +/* + * dm-snapshot.c + * + * Copyright (C) 2001-2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef DM_SNAPSHOT_H +#define DM_SNAPSHOT_H + +#include "dm.h" +#include + +struct exception_table { + uint32_t hash_mask; + struct list_head *table; +}; + +/* + * The snapshot code deals with largish chunks of the disk at a + * time. Typically 64k - 256k. + */ +/* FIXME: can we get away with limiting these to a uint32_t ? */ +typedef offset_t chunk_t; + +/* + * An exception is used where an old chunk of data has been + * replaced by a new one. + */ +struct exception { + struct list_head hash_list; + + chunk_t old_chunk; + chunk_t new_chunk; +}; + +/* + * Abstraction to handle the meta/layout of exception stores (the + * COW device). + */ +struct exception_store { + + /* + * Destroys this object when you've finished with it. + */ + void (*destroy) (struct exception_store *store); + + /* + * Find somewhere to store the next exception. + */ + int (*prepare_exception) (struct exception_store *store, + struct exception *e); + + /* + * Update the metadata with this exception. + */ + void (*commit_exception) (struct exception_store *store, + struct exception *e, + void (*callback) (void *, int success), + void *callback_context); + + /* + * The snapshot is invalid, note this in the metadata. + */ + void (*drop_snapshot) (struct exception_store *store); + + /* + * Return the %age full of the snapshot + */ + int (*percent_full) (struct exception_store *store); + + struct dm_snapshot *snap; + void *context; +}; + +struct dm_snapshot { + struct rw_semaphore lock; + struct dm_table *table; + + struct dm_dev *origin; + struct dm_dev *cow; + + /* List of snapshots per Origin */ + struct list_head list; + + /* Size of data blocks saved - must be a power of 2 */ + chunk_t chunk_size; + chunk_t chunk_mask; + chunk_t chunk_shift; + + /* You can't use a snapshot if this is 0 (e.g. if full) */ + int valid; + + /* Used for display of table */ + char type; + + /* The last percentage we notified */ + int last_percent; + + struct exception_table pending; + struct exception_table complete; + + /* The on disk metadata handler */ + struct exception_store store; +}; + +/* + * Used by the exception stores to load exceptions hen + * initialising. + */ +int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new); + +/* + * Constructor and destructor for the default persistent + * store. + */ +int dm_create_persistent(struct exception_store *store, uint32_t chunk_size); + +int dm_create_transient(struct exception_store *store, + struct dm_snapshot *s, int blocksize, void **error); + +/* + * Return the number of sectors in the device. + */ +static inline offset_t get_dev_size(kdev_t dev) +{ + int *sizes; + + sizes = blk_size[MAJOR(dev)]; + if (sizes) + return sizes[MINOR(dev)] << 1; + + return 0; +} + +static inline chunk_t sector_to_chunk(struct dm_snapshot *s, offset_t sector) +{ + return (sector & ~s->chunk_mask) >> s->chunk_shift; +} + +static inline offset_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk) +{ + return chunk << s->chunk_shift; +} + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-stripe.c linux.21pre4-ac6/drivers/md/dm-stripe.c --- linux.21pre4/drivers/md/dm-stripe.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-stripe.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include +#include +#include + +struct stripe { + struct dm_dev *dev; + offset_t physical_start; +}; + +struct stripe_c { + offset_t logical_start; + uint32_t stripes; + + /* The size of this target / num. stripes */ + uint32_t stripe_width; + + /* stripe chunk size */ + uint32_t chunk_shift; + offset_t chunk_mask; + + struct stripe stripe[0]; +}; + +static inline struct stripe_c *alloc_context(int stripes) +{ + size_t len; + + if (array_too_big(sizeof(struct stripe_c), sizeof(struct stripe), + stripes)) + return NULL; + + len = sizeof(struct stripe_c) + (sizeof(struct stripe) * stripes); + + return kmalloc(len, GFP_KERNEL); +} + +/* + * Parse a single pair + */ +static int get_stripe(struct dm_table *t, struct stripe_c *sc, + int stripe, char **argv) +{ + char *end; + unsigned long start; + + start = simple_strtoul(argv[1], &end, 10); + if (*end) + return -EINVAL; + + if (dm_table_get_device(t, argv[0], start, sc->stripe_width, + t->mode, &sc->stripe[stripe].dev)) + return -ENXIO; + + sc->stripe[stripe].physical_start = start; + return 0; +} + +/* + * Construct a striped mapping. + * [ ]+ + */ +static int stripe_ctr(struct dm_table *t, offset_t b, offset_t l, + int argc, char **argv, void **context) +{ + struct stripe_c *sc; + uint32_t stripes; + uint32_t chunk_size; + char *end; + int r, i; + + if (argc < 2) { + *context = "dm-stripe: Not enough arguments"; + return -EINVAL; + } + + stripes = simple_strtoul(argv[0], &end, 10); + if (*end) { + *context = "dm-stripe: Invalid stripe count"; + return -EINVAL; + } + + chunk_size = simple_strtoul(argv[1], &end, 10); + if (*end) { + *context = "dm-stripe: Invalid chunk_size"; + return -EINVAL; + } + + if (l % stripes) { + *context = "dm-stripe: Target length not divisable by " + "number of stripes"; + return -EINVAL; + } + + sc = alloc_context(stripes); + if (!sc) { + *context = "dm-stripe: Memory allocation for striped context " + "failed"; + return -ENOMEM; + } + + sc->logical_start = b; + sc->stripes = stripes; + sc->stripe_width = l / stripes; + + /* + * chunk_size is a power of two + */ + if (!chunk_size || (chunk_size & (chunk_size - 1))) { + *context = "dm-stripe: Invalid chunk size"; + kfree(sc); + return -EINVAL; + } + + sc->chunk_mask = chunk_size - 1; + for (sc->chunk_shift = 0; chunk_size; sc->chunk_shift++) + chunk_size >>= 1; + sc->chunk_shift--; + + /* + * Get the stripe destinations. + */ + for (i = 0; i < stripes; i++) { + if (argc < 2) { + *context = "dm-stripe: Not enough destinations " + "specified"; + kfree(sc); + return -EINVAL; + } + + argv += 2; + + r = get_stripe(t, sc, i, argv); + if (r < 0) { + *context = "dm-stripe: Couldn't parse stripe " + "destination"; + while (i--) + dm_table_put_device(t, sc->stripe[i].dev); + kfree(sc); + return r; + } + } + + *context = sc; + return 0; +} + +static void stripe_dtr(struct dm_table *t, void *c) +{ + unsigned int i; + struct stripe_c *sc = (struct stripe_c *) c; + + for (i = 0; i < sc->stripes; i++) + dm_table_put_device(t, sc->stripe[i].dev); + + kfree(sc); +} + +static int stripe_map(struct buffer_head *bh, int rw, void *context) +{ + struct stripe_c *sc = (struct stripe_c *) context; + + offset_t offset = bh->b_rsector - sc->logical_start; + uint32_t chunk = (uint32_t) (offset >> sc->chunk_shift); + uint32_t stripe = chunk % sc->stripes; /* 32bit modulus */ + chunk = chunk / sc->stripes; + + bh->b_rdev = sc->stripe[stripe].dev->dev; + bh->b_rsector = sc->stripe[stripe].physical_start + + (chunk << sc->chunk_shift) + (offset & sc->chunk_mask); + return 1; +} + +static int stripe_status(status_type_t type, char *result, int maxlen, + void *context) +{ + struct stripe_c *sc = (struct stripe_c *) context; + int offset; + int i; + + switch (type) { + case STATUSTYPE_INFO: + result[0] = '\0'; + break; + + case STATUSTYPE_TABLE: + offset = snprintf(result, maxlen, "%d %ld", + sc->stripes, sc->chunk_mask + 1); + for (i = 0; i < sc->stripes; i++) { + offset += + snprintf(result + offset, maxlen - offset, + " %s %ld", + kdevname(sc->stripe[i].dev->dev), + sc->stripe[i].physical_start); + } + break; + } + return 0; +} + +static struct target_type stripe_target = { + name: "striped", + module: THIS_MODULE, + ctr: stripe_ctr, + dtr: stripe_dtr, + map: stripe_map, + status: stripe_status, +}; + +int __init dm_stripe_init(void) +{ + int r; + + r = dm_register_target(&stripe_target); + if (r < 0) + DMWARN("striped target registration failed"); + + return r; +} + +void dm_stripe_exit(void) +{ + if (dm_unregister_target(&stripe_target)) + DMWARN("striped target unregistration failed"); + + return; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-table.c linux.21pre4-ac6/drivers/md/dm-table.c --- linux.21pre4/drivers/md/dm-table.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-table.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,452 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include + +/* ceiling(n / size) * size */ +static inline unsigned long round_up(unsigned long n, unsigned long size) +{ + unsigned long r = n % size; + return n + (r ? (size - r) : 0); +} + +/* ceiling(n / size) */ +static inline unsigned long div_up(unsigned long n, unsigned long size) +{ + return round_up(n, size) / size; +} + +/* similar to ceiling(log_size(n)) */ +static uint int_log(unsigned long n, unsigned long base) +{ + int result = 0; + + while (n > 1) { + n = div_up(n, base); + result++; + } + + return result; +} + +/* + * return the highest key that you could lookup + * from the n'th node on level l of the btree. + */ +static offset_t high(struct dm_table *t, int l, int n) +{ + for (; l < t->depth - 1; l++) + n = get_child(n, CHILDREN_PER_NODE - 1); + + if (n >= t->counts[l]) + return (offset_t) - 1; + + return get_node(t, l, n)[KEYS_PER_NODE - 1]; +} + +/* + * fills in a level of the btree based on the + * highs of the level below it. + */ +static int setup_btree_index(int l, struct dm_table *t) +{ + int n, k; + offset_t *node; + + for (n = 0; n < t->counts[l]; n++) { + node = get_node(t, l, n); + + for (k = 0; k < KEYS_PER_NODE; k++) + node[k] = high(t, l + 1, get_child(n, k)); + } + + return 0; +} + +/* + * highs, and targets are managed as dynamic + * arrays during a table load. + */ +static int alloc_targets(struct dm_table *t, int num) +{ + offset_t *n_highs; + struct target *n_targets; + int n = t->num_targets; + + /* + * Allocate both the target array and offset array at once. + */ + n_highs = (offset_t *) vcalloc(sizeof(struct target) + sizeof(offset_t), + num); + if (!n_highs) + return -ENOMEM; + + n_targets = (struct target *) (n_highs + num); + + if (n) { + memcpy(n_highs, t->highs, sizeof(*n_highs) * n); + memcpy(n_targets, t->targets, sizeof(*n_targets) * n); + } + + memset(n_highs + n, -1, sizeof(*n_highs) * (num - n)); + if (t->highs) + vfree(t->highs); + + t->num_allocated = num; + t->highs = n_highs; + t->targets = n_targets; + + return 0; +} + +int dm_table_create(struct dm_table **result, int mode) +{ + struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO); + + if (!t) + return -ENOMEM; + + memset(t, 0, sizeof(*t)); + INIT_LIST_HEAD(&t->devices); + + /* allocate a single node's worth of targets to begin with */ + if (alloc_targets(t, KEYS_PER_NODE)) { + kfree(t); + t = NULL; + return -ENOMEM; + } + + init_waitqueue_head(&t->eventq); + t->mode = mode; + *result = t; + return 0; +} + +static void free_devices(struct list_head *devices) +{ + struct list_head *tmp, *next; + + for (tmp = devices->next; tmp != devices; tmp = next) { + struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + next = tmp->next; + kfree(dd); + } +} + +void dm_table_destroy(struct dm_table *t) +{ + int i; + + /* destroying the table counts as an event */ + dm_table_event(t); + + /* free the indexes (see dm_table_complete) */ + if (t->depth >= 2) + vfree(t->index[t->depth - 2]); + + /* free the targets */ + for (i = 0; i < t->num_targets; i++) { + struct target *tgt = &t->targets[i]; + + dm_put_target_type(t->targets[i].type); + + if (tgt->type->dtr) + tgt->type->dtr(t, tgt->private); + } + + vfree(t->highs); + + /* free the device list */ + if (t->devices.next != &t->devices) { + DMWARN("devices still present during destroy: " + "dm_table_remove_device calls missing"); + + free_devices(&t->devices); + } + + kfree(t); +} + +/* + * Checks to see if we need to extend highs or targets. + */ +static inline int check_space(struct dm_table *t) +{ + if (t->num_targets >= t->num_allocated) + return alloc_targets(t, t->num_allocated * 2); + + return 0; +} + +/* + * Convert a device path to a kdev_t. + */ +int lookup_device(const char *path, kdev_t *dev) +{ + int r; + struct nameidata nd; + struct inode *inode; + + if (!path_init(path, LOOKUP_FOLLOW, &nd)) + return 0; + + if ((r = path_walk(path, &nd))) + goto bad; + + inode = nd.dentry->d_inode; + if (!inode) { + r = -ENOENT; + goto bad; + } + + if (!S_ISBLK(inode->i_mode)) { + r = -EINVAL; + goto bad; + } + + *dev = inode->i_rdev; + + bad: + path_release(&nd); + return r; +} + +/* + * See if we've already got a device in the list. + */ +static struct dm_dev *find_device(struct list_head *l, kdev_t dev) +{ + struct list_head *tmp; + + list_for_each(tmp, l) { + struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + if (dd->dev == dev) + return dd; + } + + return NULL; +} + +/* + * Open a device so we can use it as a map destination. + */ +static int open_dev(struct dm_dev *d) +{ + int err; + + if (d->bd) + BUG(); + + if (!(d->bd = bdget(kdev_t_to_nr(d->dev)))) + return -ENOMEM; + + if ((err = blkdev_get(d->bd, d->mode, 0, BDEV_FILE))) + return err; + + return 0; +} + +/* + * Close a device that we've been using. + */ +static void close_dev(struct dm_dev *d) +{ + if (!d->bd) + return; + + blkdev_put(d->bd, BDEV_FILE); + d->bd = NULL; +} + +/* + * If possible (ie. blk_size[major] is set), this + * checks an area of a destination device is + * valid. + */ +static int check_device_area(kdev_t dev, offset_t start, offset_t len) +{ + int *sizes; + offset_t dev_size; + + if (!(sizes = blk_size[MAJOR(dev)]) || !(dev_size = sizes[MINOR(dev)])) + /* we don't know the device details, + * so give the benefit of the doubt */ + return 1; + + /* convert to 512-byte sectors */ + dev_size <<= 1; + + return ((start < dev_size) && (len <= (dev_size - start))); +} + +/* + * This upgrades the mode on an already open dm_dev. Being + * careful to leave things as they were if we fail to reopen the + * device. + */ +static int upgrade_mode(struct dm_dev *dd, int new_mode) +{ + int r; + struct dm_dev dd_copy; + + memcpy(&dd_copy, dd, sizeof(dd_copy)); + + dd->mode |= new_mode; + dd->bd = NULL; + r = open_dev(dd); + if (!r) + close_dev(&dd_copy); + else + memcpy(dd, &dd_copy, sizeof(dd_copy)); + + return r; +} + +/* + * Add a device to the list, or just increment the usage count + * if it's already present. + */ +int dm_table_get_device(struct dm_table *t, const char *path, + offset_t start, offset_t len, int mode, + struct dm_dev **result) +{ + int r; + kdev_t dev; + struct dm_dev *dd; + int major, minor; + + if (sscanf(path, "%x:%x", &major, &minor) == 2) { + /* Extract the major/minor numbers */ + dev = MKDEV(major, minor); + } else { + /* convert the path to a device */ + if ((r = lookup_device(path, &dev))) + return r; + } + + dd = find_device(&t->devices, dev); + if (!dd) { + dd = kmalloc(sizeof(*dd), GFP_KERNEL); + if (!dd) + return -ENOMEM; + + dd->mode = mode; + dd->dev = dev; + dd->bd = NULL; + + if ((r = open_dev(dd))) { + kfree(dd); + return r; + } + + atomic_set(&dd->count, 0); + list_add(&dd->list, &t->devices); + + } else if (dd->mode != (mode | dd->mode)) { + r = upgrade_mode(dd, mode); + if (r) + return r; + } + atomic_inc(&dd->count); + + if (!check_device_area(dd->dev, start, len)) { + DMWARN("device %s too small for target", path); + dm_table_put_device(t, dd); + return -EINVAL; + } + + *result = dd; + + return 0; +} + +/* + * Decrement a devices use count and remove it if neccessary. + */ +void dm_table_put_device(struct dm_table *t, struct dm_dev *dd) +{ + if (atomic_dec_and_test(&dd->count)) { + close_dev(dd); + list_del(&dd->list); + kfree(dd); + } +} + +/* + * Adds a target to the map + */ +int dm_table_add_target(struct dm_table *t, offset_t highs, + struct target_type *type, void *private) +{ + int r, n; + + if ((r = check_space(t))) + return r; + + n = t->num_targets++; + t->highs[n] = highs; + t->targets[n].type = type; + t->targets[n].private = private; + + return 0; +} + +static int setup_indexes(struct dm_table *t) +{ + int i, total = 0; + offset_t *indexes; + + /* allocate the space for *all* the indexes */ + for (i = t->depth - 2; i >= 0; i--) { + t->counts[i] = div_up(t->counts[i + 1], CHILDREN_PER_NODE); + total += t->counts[i]; + } + + indexes = (offset_t *) vcalloc(total, (unsigned long) NODE_SIZE); + if (!indexes) + return -ENOMEM; + + /* set up internal nodes, bottom-up */ + for (i = t->depth - 2, total = 0; i >= 0; i--) { + t->index[i] = indexes; + indexes += (KEYS_PER_NODE * t->counts[i]); + setup_btree_index(i, t); + } + + return 0; +} + +/* + * Builds the btree to index the map + */ +int dm_table_complete(struct dm_table *t) +{ + int leaf_nodes, r = 0; + + /* how many indexes will the btree have ? */ + leaf_nodes = div_up(t->num_targets, KEYS_PER_NODE); + t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE); + + /* leaf layer has already been set up */ + t->counts[t->depth - 1] = leaf_nodes; + t->index[t->depth - 1] = t->highs; + + if (t->depth >= 2) + r = setup_indexes(t); + + return r; +} + +void dm_table_event(struct dm_table *t) +{ + wake_up_interruptible(&t->eventq); +} + +EXPORT_SYMBOL(dm_table_get_device); +EXPORT_SYMBOL(dm_table_put_device); +EXPORT_SYMBOL(dm_table_event); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/dm-target.c linux.21pre4-ac6/drivers/md/dm-target.c --- linux.21pre4/drivers/md/dm-target.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/dm-target.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include + +struct tt_internal { + struct target_type tt; + + struct list_head list; + long use; +}; + +static LIST_HEAD(_targets); +static rwlock_t _lock = RW_LOCK_UNLOCKED; + +#define DM_MOD_NAME_SIZE 32 + +/* + * Destructively splits up the argument list to pass to ctr. + */ +int split_args(int max, int *argc, char **argv, char *input) +{ + char *start, *end = input, *out; + *argc = 0; + + while (1) { + start = end; + + /* Skip whitespace */ + while (*start && isspace(*start)) + start++; + + if (!*start) + break; /* success, we hit the end */ + + /* 'out' is used to remove any back-quotes */ + end = out = start; + while (*end) { + /* Everything apart from '\0' can be quoted */ + if (*end == '\\' && *(end + 1)) { + *out++ = *(end + 1); + end += 2; + continue; + } + + if (isspace(*end)) + break; /* end of token */ + + *out++ = *end++; + } + + /* have we already filled the array ? */ + if ((*argc + 1) > max) + return -EINVAL; + + /* we know this is whitespace */ + if (*end) + end++; + + /* terminate the string and put it in the array */ + *out = '\0'; + argv[*argc] = start; + (*argc)++; + } + + return 0; +} + +static inline struct tt_internal *__find_target_type(const char *name) +{ + struct list_head *tih; + struct tt_internal *ti; + + list_for_each(tih, &_targets) { + ti = list_entry(tih, struct tt_internal, list); + + if (!strcmp(name, ti->tt.name)) + return ti; + } + + return NULL; +} + +static struct tt_internal *get_target_type(const char *name) +{ + struct tt_internal *ti; + + read_lock(&_lock); + ti = __find_target_type(name); + + if (ti) { + if (ti->use == 0 && ti->tt.module) + __MOD_INC_USE_COUNT(ti->tt.module); + ti->use++; + } + read_unlock(&_lock); + + return ti; +} + +static void load_module(const char *name) +{ + char module_name[DM_MOD_NAME_SIZE] = "dm-"; + + /* Length check for strcat() below */ + if (strlen(name) > (DM_MOD_NAME_SIZE - 4)) + return; + + strcat(module_name, name); + request_module(module_name); + + return; +} + +struct target_type *dm_get_target_type(const char *name) +{ + struct tt_internal *ti = get_target_type(name); + + if (!ti) { + load_module(name); + ti = get_target_type(name); + } + + return ti ? &ti->tt : NULL; +} + +void dm_put_target_type(struct target_type *t) +{ + struct tt_internal *ti = (struct tt_internal *) t; + + read_lock(&_lock); + if (--ti->use == 0 && ti->tt.module) + __MOD_DEC_USE_COUNT(ti->tt.module); + + if (ti->use < 0) + BUG(); + read_unlock(&_lock); + + return; +} + +static struct tt_internal *alloc_target(struct target_type *t) +{ + struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL); + + if (ti) { + memset(ti, 0, sizeof(*ti)); + ti->tt = *t; + } + + return ti; +} + +int dm_register_target(struct target_type *t) +{ + int rv = 0; + struct tt_internal *ti = alloc_target(t); + + if (!ti) + return -ENOMEM; + + write_lock(&_lock); + if (__find_target_type(t->name)) + rv = -EEXIST; + else + list_add(&ti->list, &_targets); + + write_unlock(&_lock); + return rv; +} + +int dm_unregister_target(struct target_type *t) +{ + struct tt_internal *ti; + + write_lock(&_lock); + if (!(ti = __find_target_type(t->name))) { + write_unlock(&_lock); + return -EINVAL; + } + + if (ti->use) { + write_unlock(&_lock); + return -ETXTBSY; + } + + list_del(&ti->list); + kfree(ti); + + write_unlock(&_lock); + return 0; +} + +/* + * io-err: always fails an io, useful for bringing + * up LV's that have holes in them. + */ +static int io_err_ctr(struct dm_table *t, offset_t b, offset_t l, + int argc, char **args, void **context) +{ + *context = NULL; + return 0; +} + +static void io_err_dtr(struct dm_table *t, void *c) +{ + /* empty */ + return; +} + +static int io_err_map(struct buffer_head *bh, int rw, void *context) +{ + buffer_IO_error(bh); + return 0; +} + +static struct target_type error_target = { + name: "error", + ctr: io_err_ctr, + dtr: io_err_dtr, + map: io_err_map, + status: NULL, +}; + +int dm_target_init(void) +{ + return dm_register_target(&error_target); +} + +void dm_target_exit(void) +{ + if (dm_unregister_target(&error_target)) + DMWARN("error target unregistration failed"); +} + +EXPORT_SYMBOL(dm_register_target); +EXPORT_SYMBOL(dm_unregister_target); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/kcopyd.c linux.21pre4-ac6/drivers/md/kcopyd.c --- linux.21pre4/drivers/md/kcopyd.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/kcopyd.c 2003-01-06 17:11:06.000000000 +0000 @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcopyd.h" + +/* FIXME: this is only needed for the DMERR macros */ +#include "dm.h" + +/* + * Hard sector size used all over the kernel. + */ +#define SECTOR_SIZE 512 +#define SECTOR_SHIFT 9 + +static void wake_kcopyd(void); + +/*----------------------------------------------------------------- + * We reserve our own pool of preallocated pages that are + * only used for kcopyd io. + *---------------------------------------------------------------*/ + +/* + * FIXME: This should be configurable. + */ +#define NUM_PAGES 512 + +static DECLARE_MUTEX(_pages_lock); +static int _num_free_pages; +static struct page *_pages_array[NUM_PAGES]; +static DECLARE_MUTEX(start_lock); + +static int init_pages(void) +{ + int i; + struct page *p; + + for (i = 0; i < NUM_PAGES; i++) { + p = alloc_page(GFP_KERNEL); + if (!p) + goto bad; + + LockPage(p); + _pages_array[i] = p; + } + + _num_free_pages = NUM_PAGES; + return 0; + + bad: + while (i--) + __free_page(_pages_array[i]); + return -ENOMEM; +} + +static void exit_pages(void) +{ + int i; + struct page *p; + + for (i = 0; i < NUM_PAGES; i++) { + p = _pages_array[i]; + UnlockPage(p); + __free_page(p); + } + + _num_free_pages = 0; +} + +static int kcopyd_get_pages(int num, struct page **result) +{ + int i; + + down(&_pages_lock); + if (_num_free_pages < num) { + up(&_pages_lock); + return -ENOMEM; + } + + for (i = 0; i < num; i++) { + _num_free_pages--; + result[i] = _pages_array[_num_free_pages]; + } + up(&_pages_lock); + + return 0; +} + +static void kcopyd_free_pages(int num, struct page **result) +{ + int i; + + down(&_pages_lock); + for (i = 0; i < num; i++) + _pages_array[_num_free_pages++] = result[i]; + up(&_pages_lock); +} + +/*----------------------------------------------------------------- + * We keep our own private pool of buffer_heads. These are just + * held in a list on the b_reqnext field. + *---------------------------------------------------------------*/ + +/* + * Make sure we have enough buffers to always keep the pages + * occupied. So we assume the worst case scenario where blocks + * are the size of a single sector. + */ +#define NUM_BUFFERS NUM_PAGES * (PAGE_SIZE / SECTOR_SIZE) + +static spinlock_t _buffer_lock = SPIN_LOCK_UNLOCKED; +static struct buffer_head *_all_buffers; +static struct buffer_head *_free_buffers; + +static int init_buffers(void) +{ + int i; + struct buffer_head *buffers; + + buffers = vcalloc(NUM_BUFFERS, sizeof(struct buffer_head)); + if (!buffers) { + DMWARN("Couldn't allocate buffer heads."); + return -ENOMEM; + } + + for (i = 0; i < NUM_BUFFERS; i++) { + if (i < NUM_BUFFERS - 1) + buffers[i].b_reqnext = &buffers[i + 1]; + init_waitqueue_head(&buffers[i].b_wait); + INIT_LIST_HEAD(&buffers[i].b_inode_buffers); + } + + _all_buffers = _free_buffers = buffers; + return 0; +} + +static void exit_buffers(void) +{ + vfree(_all_buffers); +} + +static struct buffer_head *alloc_buffer(void) +{ + struct buffer_head *r; + int flags; + + spin_lock_irqsave(&_buffer_lock, flags); + + if (!_free_buffers) + r = NULL; + else { + r = _free_buffers; + _free_buffers = _free_buffers->b_reqnext; + r->b_reqnext = NULL; + } + + spin_unlock_irqrestore(&_buffer_lock, flags); + + return r; +} + +/* + * Only called from interrupt context. + */ +static void free_buffer(struct buffer_head *bh) +{ + int flags, was_empty; + + spin_lock_irqsave(&_buffer_lock, flags); + was_empty = (_free_buffers == NULL) ? 1 : 0; + bh->b_reqnext = _free_buffers; + _free_buffers = bh; + spin_unlock_irqrestore(&_buffer_lock, flags); + + /* + * If the buffer list was empty then kcopyd probably went + * to sleep because it ran out of buffer heads, so let's + * wake it up. + */ + if (was_empty) + wake_kcopyd(); +} + +/*----------------------------------------------------------------- + * kcopyd_jobs need to be allocated by the *clients* of kcopyd, + * for this reason we use a mempool to prevent the client from + * ever having to do io (which could cause a + * deadlock). + *---------------------------------------------------------------*/ +#define MIN_JOBS NUM_PAGES + +static kmem_cache_t *_job_cache = NULL; +static mempool_t *_job_pool = NULL; + +/* + * We maintain three lists of jobs: + * + * i) jobs waiting for pages + * ii) jobs that have pages, and are waiting for the io to be issued. + * iii) jobs that have completed. + * + * All three of these are protected by job_lock. + */ + +static spinlock_t _job_lock = SPIN_LOCK_UNLOCKED; + +static LIST_HEAD(_complete_jobs); +static LIST_HEAD(_io_jobs); +static LIST_HEAD(_pages_jobs); + +static int init_jobs(void) +{ + INIT_LIST_HEAD(&_complete_jobs); + INIT_LIST_HEAD(&_io_jobs); + INIT_LIST_HEAD(&_pages_jobs); + + _job_cache = kmem_cache_create("kcopyd-jobs", sizeof(struct kcopyd_job), + __alignof__(struct kcopyd_job), + 0, NULL, NULL); + if (!_job_cache) + return -ENOMEM; + + _job_pool = mempool_create(MIN_JOBS, mempool_alloc_slab, + mempool_free_slab, _job_cache); + if (!_job_pool) { + kmem_cache_destroy(_job_cache); + return -ENOMEM; + } + + return 0; +} + +static void exit_jobs(void) +{ + mempool_destroy(_job_pool); + kmem_cache_destroy(_job_cache); +} + +struct kcopyd_job *kcopyd_alloc_job(void) +{ + struct kcopyd_job *job; + + job = mempool_alloc(_job_pool, GFP_KERNEL); + if (!job) + return NULL; + + memset(job, 0, sizeof(*job)); + return job; +} + +void kcopyd_free_job(struct kcopyd_job *job) +{ + mempool_free(job, _job_pool); +} + +/* + * Functions to push and pop a job onto the head of a given job + * list. + */ +static inline struct kcopyd_job *pop(struct list_head *jobs) +{ + struct kcopyd_job *job = NULL; + int flags; + + spin_lock_irqsave(&_job_lock, flags); + + if (!list_empty(jobs)) { + job = list_entry(jobs->next, struct kcopyd_job, list); + list_del(&job->list); + } + spin_unlock_irqrestore(&_job_lock, flags); + + return job; +} + +static inline void push(struct list_head *jobs, struct kcopyd_job *job) +{ + int flags; + + spin_lock_irqsave(&_job_lock, flags); + list_add(&job->list, jobs); + spin_unlock_irqrestore(&_job_lock, flags); +} + +/* + * Completion function for one of our buffers. + */ +static void end_bh(struct buffer_head *bh, int uptodate) +{ + struct kcopyd_job *job = bh->b_private; + + mark_buffer_uptodate(bh, uptodate); + unlock_buffer(bh); + + if (!uptodate) + job->err = -EIO; + + /* are we the last ? */ + if (atomic_dec_and_test(&job->nr_incomplete)) { + push(&_complete_jobs, job); + wake_kcopyd(); + } + + free_buffer(bh); +} + +static void dispatch_bh(struct kcopyd_job *job, + struct buffer_head *bh, int block) +{ + int p; + + /* + * Add in the job offset + */ + bh->b_blocknr = (job->disk.sector >> job->block_shift) + block; + + p = block >> job->bpp_shift; + block &= job->bpp_mask; + + bh->b_dev = B_FREE; + bh->b_size = job->block_size; + set_bh_page(bh, job->pages[p], ((block << job->block_shift) + + job->offset) << SECTOR_SHIFT); + bh->b_this_page = bh; + + init_buffer(bh, end_bh, job); + + bh->b_dev = job->disk.dev; + bh->b_state = ((1 << BH_Mapped) | (1 << BH_Lock) | (1 << BH_Req)); + + set_bit(BH_Uptodate, &bh->b_state); + if (job->rw == WRITE) + clear_bit(BH_Dirty, &bh->b_state); + + submit_bh(job->rw, bh); +} + +/* + * These three functions process 1 item from the corresponding + * job list. + * + * They return: + * < 0: error + * 0: success + * > 0: can't process yet. + */ +static int run_complete_job(struct kcopyd_job *job) +{ + job->callback(job); + return 0; +} + +/* + * Request io on as many buffer heads as we can currently get for + * a particular job. + */ +static int run_io_job(struct kcopyd_job *job) +{ + unsigned int block; + struct buffer_head *bh; + + for (block = atomic_read(&job->nr_requested); + block < job->nr_blocks; block++) { + bh = alloc_buffer(); + if (!bh) + break; + + atomic_inc(&job->nr_requested); + dispatch_bh(job, bh, block); + } + + return (block == job->nr_blocks) ? 0 : 1; +} + +static int run_pages_job(struct kcopyd_job *job) +{ + int r; + + job->nr_pages = (job->disk.count + job->offset) / + (PAGE_SIZE / SECTOR_SIZE); + r = kcopyd_get_pages(job->nr_pages, job->pages); + + if (!r) { + /* this job is ready for io */ + push(&_io_jobs, job); + return 0; + } + + if (r == -ENOMEM) + /* can complete now */ + return 1; + + return r; +} + +/* + * Run through a list for as long as possible. Returns the count + * of successful jobs. + */ +static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) +{ + struct kcopyd_job *job; + int r, count = 0; + + while ((job = pop(jobs))) { + + r = fn(job); + + if (r < 0) { + /* error this rogue job */ + job->err = r; + push(&_complete_jobs, job); + break; + } + + if (r > 0) { + /* + * We couldn't service this job ATM, so + * push this job back onto the list. + */ + push(jobs, job); + break; + } + + count++; + } + + return count; +} + +/* + * kcopyd does this every time it's woken up. + */ +static void do_work(void) +{ + int count; + + /* + * We loop round until there is no more work to do. + */ + do { + count = process_jobs(&_complete_jobs, run_complete_job); + count += process_jobs(&_io_jobs, run_io_job); + count += process_jobs(&_pages_jobs, run_pages_job); + + } while (count); + + run_task_queue(&tq_disk); +} + +/*----------------------------------------------------------------- + * The daemon + *---------------------------------------------------------------*/ +static atomic_t _kcopyd_must_die; +static DECLARE_MUTEX(_run_lock); +static DECLARE_WAIT_QUEUE_HEAD(_job_queue); + +static int kcopyd(void *arg) +{ + DECLARE_WAITQUEUE(wq, current); + + daemonize(); + strcpy(current->comm, "kcopyd"); + atomic_set(&_kcopyd_must_die, 0); + + add_wait_queue(&_job_queue, &wq); + + down(&_run_lock); + up(&start_lock); + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + if (atomic_read(&_kcopyd_must_die)) + break; + + do_work(); + schedule(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&_job_queue, &wq); + + up(&_run_lock); + + return 0; +} + +static int start_daemon(void) +{ + static pid_t pid = 0; + + down(&start_lock); + + pid = kernel_thread(kcopyd, NULL, 0); + if (pid <= 0) { + DMERR("Failed to start kcopyd thread"); + return -EAGAIN; + } + + /* + * wait for the daemon to up this mutex. + */ + down(&start_lock); + up(&start_lock); + + return 0; +} + +static int stop_daemon(void) +{ + atomic_set(&_kcopyd_must_die, 1); + wake_kcopyd(); + down(&_run_lock); + up(&_run_lock); + + return 0; +} + +static void wake_kcopyd(void) +{ + wake_up_interruptible(&_job_queue); +} + +static int calc_shift(unsigned int n) +{ + int s; + + for (s = 0; n; s++, n >>= 1) + ; + + return --s; +} + +static void calc_block_sizes(struct kcopyd_job *job) +{ + job->block_size = get_hardsect_size(job->disk.dev); + job->block_shift = calc_shift(job->block_size / SECTOR_SIZE); + job->bpp_shift = PAGE_SHIFT - job->block_shift - SECTOR_SHIFT; + job->bpp_mask = (1 << job->bpp_shift) - 1; + job->nr_blocks = job->disk.count >> job->block_shift; + atomic_set(&job->nr_requested, 0); + atomic_set(&job->nr_incomplete, job->nr_blocks); +} + +int kcopyd_io(struct kcopyd_job *job) +{ + calc_block_sizes(job); + push(job->pages[0] ? &_io_jobs : &_pages_jobs, job); + wake_kcopyd(); + return 0; +} + +/*----------------------------------------------------------------- + * The copier is implemented on top of the simpler async io + * daemon above. + *---------------------------------------------------------------*/ +struct copy_info { + kcopyd_notify_fn notify; + void *notify_context; + + struct kcopyd_region to; +}; + +#define MIN_INFOS 128 +static kmem_cache_t *_copy_cache = NULL; +static mempool_t *_copy_pool = NULL; + +static int init_copier(void) +{ + _copy_cache = kmem_cache_create("kcopyd-info", + sizeof(struct copy_info), + __alignof__(struct copy_info), + 0, NULL, NULL); + if (!_copy_cache) + return -ENOMEM; + + _copy_pool = mempool_create(MIN_INFOS, mempool_alloc_slab, + mempool_free_slab, _copy_cache); + if (!_copy_pool) { + kmem_cache_destroy(_copy_cache); + return -ENOMEM; + } + + return 0; +} + +static void exit_copier(void) +{ + if (_copy_pool) + mempool_destroy(_copy_pool); + + if (_copy_cache) + kmem_cache_destroy(_copy_cache); +} + +static inline struct copy_info *alloc_copy_info(void) +{ + return mempool_alloc(_copy_pool, GFP_KERNEL); +} + +static inline void free_copy_info(struct copy_info *info) +{ + mempool_free(info, _copy_pool); +} + +void copy_complete(struct kcopyd_job *job) +{ + struct copy_info *info = (struct copy_info *) job->context; + + if (info->notify) + info->notify(job->err, info->notify_context); + + free_copy_info(info); + + kcopyd_free_pages(job->nr_pages, job->pages); + + kcopyd_free_job(job); +} + +static void page_write_complete(struct kcopyd_job *job) +{ + struct copy_info *info = (struct copy_info *) job->context; + int i; + + if (info->notify) + info->notify(job->err, info->notify_context); + + free_copy_info(info); + for (i = 0; i < job->nr_pages; i++) + put_page(job->pages[i]); + + kcopyd_free_job(job); +} + +/* + * These callback functions implement the state machine that copies regions. + */ +void copy_write(struct kcopyd_job *job) +{ + struct copy_info *info = (struct copy_info *) job->context; + + if (job->err && info->notify) { + info->notify(job->err, job->context); + kcopyd_free_job(job); + free_copy_info(info); + return; + } + + job->rw = WRITE; + memcpy(&job->disk, &info->to, sizeof(job->disk)); + job->callback = copy_complete; + job->context = info; + + /* + * Queue the write. + */ + kcopyd_io(job); +} + +int kcopyd_write_pages(struct kcopyd_region *to, int nr_pages, + struct page **pages, int offset, kcopyd_notify_fn fn, + void *context) +{ + struct copy_info *info; + struct kcopyd_job *job; + int i; + + /* + * Allocate a new copy_info. + */ + info = alloc_copy_info(); + if (!info) + return -ENOMEM; + + job = kcopyd_alloc_job(); + if (!job) { + free_copy_info(info); + return -ENOMEM; + } + + /* + * set up for the write. + */ + info->notify = fn; + info->notify_context = context; + memcpy(&info->to, to, sizeof(*to)); + + /* Get the pages */ + job->nr_pages = nr_pages; + for (i = 0; i < nr_pages; i++) { + get_page(pages[i]); + job->pages[i] = pages[i]; + } + + job->rw = WRITE; + + memcpy(&job->disk, &info->to, sizeof(job->disk)); + job->offset = offset; + calc_block_sizes(job); + job->callback = page_write_complete; + job->context = info; + + /* + * Trigger job. + */ + kcopyd_io(job); + return 0; +} + +int kcopyd_copy(struct kcopyd_region *from, struct kcopyd_region *to, + kcopyd_notify_fn fn, void *context) +{ + struct copy_info *info; + struct kcopyd_job *job; + + /* + * Allocate a new copy_info. + */ + info = alloc_copy_info(); + if (!info) + return -ENOMEM; + + job = kcopyd_alloc_job(); + if (!job) { + free_copy_info(info); + return -ENOMEM; + } + + /* + * set up for the read. + */ + info->notify = fn; + info->notify_context = context; + memcpy(&info->to, to, sizeof(*to)); + + job->rw = READ; + memcpy(&job->disk, from, sizeof(*from)); + + job->offset = 0; + calc_block_sizes(job); + job->callback = copy_write; + job->context = info; + + /* + * Trigger job. + */ + kcopyd_io(job); + return 0; +} + +/*----------------------------------------------------------------- + * Unit setup + *---------------------------------------------------------------*/ +static struct { + int (*init) (void); + void (*exit) (void); + +} _inits[] = { +#define xx(n) { init_ ## n, exit_ ## n} + xx(pages), + xx(buffers), + xx(jobs), + xx(copier) +#undef xx +}; + +static int _client_count = 0; +static DECLARE_MUTEX(_client_count_sem); + +static int kcopyd_init(void) +{ + const int count = sizeof(_inits) / sizeof(*_inits); + + int r, i; + + for (i = 0; i < count; i++) { + r = _inits[i].init(); + if (r) + goto bad; + } + + start_daemon(); + return 0; + + bad: + while (i--) + _inits[i].exit(); + + return r; +} + +static void kcopyd_exit(void) +{ + int i = sizeof(_inits) / sizeof(*_inits); + + if (stop_daemon()) + DMWARN("Couldn't stop kcopyd."); + + while (i--) + _inits[i].exit(); +} + +void kcopyd_inc_client_count(void) +{ + /* + * What I need here is an atomic_test_and_inc that returns + * the previous value of the atomic... In its absence I lock + * an int with a semaphore. :-( + */ + down(&_client_count_sem); + if (_client_count == 0) + kcopyd_init(); + _client_count++; + + up(&_client_count_sem); +} + +void kcopyd_dec_client_count(void) +{ + down(&_client_count_sem); + if (--_client_count == 0) + kcopyd_exit(); + + up(&_client_count_sem); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/kcopyd.h linux.21pre4-ac6/drivers/md/kcopyd.h --- linux.21pre4/drivers/md/kcopyd.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/md/kcopyd.h 2003-02-07 15:49:47.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * This file is released under the GPL. + */ + +#ifndef DM_KCOPYD_H +#define DM_KCOPYD_H + +/* + * Needed for the definition of offset_t. + */ +#include +#include + +struct kcopyd_region { + kdev_t dev; + offset_t sector; + offset_t count; +}; + +#define MAX_KCOPYD_PAGES 128 + +struct kcopyd_job { + struct list_head list; + + /* + * Error state of the job. + */ + int err; + + /* + * Either READ or WRITE + */ + int rw; + + /* + * The source or destination for the transfer. + */ + struct kcopyd_region disk; + + int nr_pages; + struct page *pages[MAX_KCOPYD_PAGES]; + + /* + * Shifts and masks that will be useful when dispatching + * each buffer_head. + */ + offset_t offset; + offset_t block_size; + offset_t block_shift; + offset_t bpp_shift; /* blocks per page */ + offset_t bpp_mask; + + /* + * nr_blocks is how many buffer heads will have to be + * displatched to service this job, nr_requested is how + * many have been dispatched and nr_complete is how many + * have come back. + */ + unsigned int nr_blocks; + atomic_t nr_requested; + atomic_t nr_incomplete; + + /* + * Set this to ensure you are notified when the job has + * completed. 'context' is for callback to use. + */ + void (*callback)(struct kcopyd_job *job); + void *context; +}; + +/* + * Low level async io routines. + */ +struct kcopyd_job *kcopyd_alloc_job(void); +void kcopyd_free_job(struct kcopyd_job *job); + +int kcopyd_queue_job(struct kcopyd_job *job); + +/* + * Submit a copy job to kcopyd. This is built on top of the + * previous three fns. + */ +typedef void (*kcopyd_notify_fn)(int err, void *context); + +int kcopyd_copy(struct kcopyd_region *from, struct kcopyd_region *to, + kcopyd_notify_fn fn, void *context); + +int kcopyd_write_pages(struct kcopyd_region *to, int nr_pages, + struct page **pages, int offset, kcopyd_notify_fn fn, + void *context); + +/* + * We only want kcopyd to reserve resources if someone is + * actually using it. + */ +void kcopyd_inc_client_count(void); +void kcopyd_dec_client_count(void); + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/lvm.c linux.21pre4-ac6/drivers/md/lvm.c --- linux.21pre4/drivers/md/lvm.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/md/lvm.c 2003-02-06 16:04:53.000000000 +0000 @@ -2405,7 +2405,7 @@ } } - /* save availiable i/o statistic data */ + /* save available i/o statistic data */ if (old_lv->lv_stripes < 2) { /* linear logical volume */ end = min(old_lv->lv_current_le, new_lv->lv_current_le); for (l = 0; l < end; l++) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/Makefile linux.21pre4-ac6/drivers/md/Makefile --- linux.21pre4/drivers/md/Makefile 2003-01-29 16:27:04.000000000 +0000 +++ linux.21pre4-ac6/drivers/md/Makefile 2003-01-06 17:11:06.000000000 +0000 @@ -4,9 +4,11 @@ O_TARGET := mddev.o -export-objs := md.o xor.o +export-objs := md.o xor.o dm-table.o dm-target.o kcopyd.o list-multi := lvm-mod.o lvm-mod-objs := lvm.o lvm-snap.o lvm-fs.o +dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ + dm-ioctl.o dm-snapshot.o dm-exception-store.o kcopyd.o # Note: link order is important. All raid personalities # and xor.o must come before md.o, as they each initialise @@ -20,8 +22,12 @@ obj-$(CONFIG_MD_MULTIPATH) += multipath.o obj-$(CONFIG_BLK_DEV_MD) += md.o obj-$(CONFIG_BLK_DEV_LVM) += lvm-mod.o +obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o include $(TOPDIR)/Rules.make lvm-mod.o: $(lvm-mod-objs) $(LD) -r -o $@ $(lvm-mod-objs) + +dm-mod.o: $(dm-mod-objs) + $(LD) -r -o $@ $(dm-mod-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/md/md.c linux.21pre4-ac6/drivers/md/md.c --- linux.21pre4/drivers/md/md.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/md/md.c 2003-01-29 17:17:53.000000000 +0000 @@ -77,7 +77,7 @@ */ static int sysctl_speed_limit_min = 100; -static int sysctl_speed_limit_max = 100000; +static int sysctl_speed_limit_max = 10000; static struct ctl_table_header *raid_table_header; @@ -2930,8 +2930,6 @@ * bdflush, otherwise bdflush will deadlock if there are too * many dirty RAID5 blocks. */ - current->policy = SCHED_OTHER; - current->nice = -20; md_unlock_kernel(); complete(thread->event); @@ -3384,11 +3382,6 @@ "(but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max); - /* - * Resync has low priority. - */ - current->nice = 19; - is_mddev_idle(mddev); /* this also initializes IO event counters */ for (m = 0; m < SYNC_MARKS; m++) { mark[m] = jiffies; @@ -3466,16 +3459,13 @@ currspeed = (j-mddev->resync_mark_cnt)/2/((jiffies-mddev->resync_mark)/HZ +1) +1; if (currspeed > sysctl_speed_limit_min) { - current->nice = 19; - if ((currspeed > sysctl_speed_limit_max) || !is_mddev_idle(mddev)) { current->state = TASK_INTERRUPTIBLE; md_schedule_timeout(HZ/4); goto repeat; } - } else - current->nice = -20; + } } printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev)); err = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/radio/radio-cadet.c linux.21pre4-ac6/drivers/media/radio/radio-cadet.c --- linux.21pre4/drivers/media/radio/radio-cadet.c 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/radio/radio-cadet.c 2003-02-11 18:07:08.000000000 +0000 @@ -20,7 +20,9 @@ * Removed dead CONFIG_RADIO_CADET_PORT code * PnP detection on load is now default (no args necessary) * -*/ + * 2003-01-31 Alan Cox + * Cleaned up locking, delay code, general odds and ends + */ #include /* Modules */ #include /* Initdata */ @@ -40,11 +42,11 @@ static int curtuner=0; static int tunestat=0; static int sigstrength=0; -static wait_queue_head_t tunerq,rdsq,readq; +static wait_queue_head_t readq; struct timer_list tunertimer,rdstimer,readtimer; static __u8 rdsin=0,rdsout=0,rdsstat=0; static unsigned char rdsbuf[RDS_BUFFER]; -static int cadet_lock=0; +static spinlock_t cadet_io_lock; static int cadet_probe(void); static struct pci_dev *dev; @@ -57,37 +59,19 @@ */ static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; -void cadet_wake(unsigned long qnum) -{ - switch(qnum) { - case 0: /* cadet_setfreq */ - wake_up(&tunerq); - break; - case 1: /* cadet_getrds */ - wake_up(&rdsq); - break; - } -} - - - static int cadet_getrds(void) { int rdsstat=0; - cadet_lock++; + spin_lock(&cadet_io_lock); outb(3,io); /* Select Decoder Control/Status */ outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */ - cadet_lock--; - init_timer(&rdstimer); - rdstimer.function=cadet_wake; - rdstimer.data=(unsigned long)1; - rdstimer.expires=jiffies+(HZ/10); - init_waitqueue_head(&rdsq); - add_timer(&rdstimer); - sleep_on(&rdsq); + spin_unlock(&cadet_io_lock); - cadet_lock++; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); + + spin_lock(&cadet_io_lock); outb(3,io); /* Select Decoder Control/Status */ if((inb(io+1)&0x80)!=0) { rdsstat|=VIDEO_TUNER_RDS_ON; @@ -95,32 +79,24 @@ if((inb(io+1)&0x10)!=0) { rdsstat|=VIDEO_TUNER_MBS_ON; } - cadet_lock--; + spin_unlock(&cadet_io_lock); return rdsstat; + } - - - static int cadet_getstereo(void) { - if(curtuner!=0) { /* Only FM has stereo capability! */ + int ret = 0; + if(curtuner != 0) /* Only FM has stereo capability! */ return 0; - } - cadet_lock++; + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ - if((inb(io+1)&0x40)==0) { - cadet_lock--; - return 1; /* Stereo pilot detected */ - } - else { - cadet_lock--; - return 0; /* Mono */ - } + if( (inb(io+1) & 0x40) == 0) + ret = 1; + spin_unlock(&cadet_io_lock); + return ret; } - - static unsigned cadet_gettune(void) { int curvol,i; @@ -129,7 +105,9 @@ /* * Prepare for read */ - cadet_lock++; + + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ curvol=inb(io+1); /* Save current volume/mute setting */ outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ @@ -151,7 +129,8 @@ * Restore volume/mute setting */ outb(curvol,io+1); - cadet_lock--; + + spin_unlock(&cadet_io_lock); return fifo; } @@ -197,7 +176,8 @@ int i; unsigned test; - cadet_lock++; + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ /* * Write the shift register @@ -216,7 +196,7 @@ test=0x1c|((fifo>>23)&0x02); outb(test,io+1); } - cadet_lock--; + spin_unlock(&cadet_io_lock); } @@ -252,92 +232,92 @@ /* * Save current volume/mute setting */ - cadet_lock++; + + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ curvol=inb(io+1); + spin_unlock(&cadet_io_lock); /* * Tune the card */ for(j=3;j>-1;j--) { cadet_settune(fifo|(j<<16)); + + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ outb(curvol,io+1); - cadet_lock--; - init_timer(&tunertimer); - tunertimer.function=cadet_wake; - tunertimer.data=(unsigned long)0; - tunertimer.expires=jiffies+(HZ/10); - init_waitqueue_head(&tunerq); - add_timer(&tunertimer); - sleep_on(&tunerq); + spin_unlock(&cadet_io_lock); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); + cadet_gettune(); - if((tunestat&0x40)==0) { /* Tuned */ + if((tunestat & 0x40) == 0) { /* Tuned */ sigstrength=sigtable[curtuner][j]; return; } - cadet_lock++; } - cadet_lock--; sigstrength=0; } static int cadet_getvol(void) { - cadet_lock++; + int ret = 0; + + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ - if((inb(io+1)&0x20)!=0) { - cadet_lock--; - return 0xffff; - } - else { - cadet_lock--; - return 0; - } + if((inb(io + 1) & 0x20) != 0) + ret = 0xffff; + + spin_unlock(&cadet_io_lock); + return ret; } static void cadet_setvol(int vol) { - cadet_lock++; + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ - if(vol>0) { + if(vol>0) outb(0x20,io+1); - } - else { + else outb(0x00,io+1); - } - cadet_lock--; -} + spin_unlock(&cadet_io_lock); +} -void cadet_handler(unsigned long data) +static void cadet_handler(unsigned long data) { /* * Service the RDS fifo */ - if(cadet_lock==0) { + + if(spin_trylock(&cadet_io_lock)) + { outb(0x3,io); /* Select RDS Decoder Control */ if((inb(io+1)&0x20)!=0) { printk(KERN_CRIT "cadet: RDS fifo overflow\n"); } outb(0x80,io); /* Select RDS fifo */ while((inb(io)&0x80)!=0) { - rdsbuf[rdsin++]=inb(io+1); + rdsbuf[rdsin]=inb(io+1); if(rdsin==rdsout) { - printk(KERN_CRIT "cadet: RDS buffer overflow\n"); + printk(KERN_WARNING "cadet: RDS buffer overflow\n"); } + else rdsin++; } + spin_unlock(&cadet_io_lock); } /* * Service pending read */ - if( rdsin!=rdsout) { + if( rdsin!=rdsout) wake_up_interruptible(&readq); - } /* * Clean up and exit @@ -358,10 +338,10 @@ unsigned char readbuf[RDS_BUFFER]; if(rdsstat==0) { - cadet_lock++; + spin_lock(&cadet_io_lock); rdsstat=1; outb(0x80,io); /* Select RDS fifo */ - cadet_lock--; + spin_unlock(&cadet_io_lock); init_timer(&readtimer); readtimer.function=cadet_handler; readtimer.data=(unsigned long)0; @@ -369,17 +349,15 @@ add_timer(&readtimer); } if(rdsin==rdsout) { - if(nonblock) { + if(nonblock) return -EWOULDBLOCK; - } interruptible_sleep_on(&readq); } - while((i1)) { - return -EINVAL; - } + switch(v.tuner) { - case 0: + case 0: strcpy(v.name,"FM"); v.rangelow=1400; /* 87.5 MHz */ v.rangehigh=1728; /* 108.0 MHz */ v.flags=0; - v.mode=0; v.mode|=VIDEO_MODE_AUTO; - v.signal=sigstrength; - if(cadet_getstereo()==1) { + if(cadet_getstereo()==1) v.flags|=VIDEO_TUNER_STEREO_ON; - } + v.flags|=cadet_getrds(); - if(copy_to_user(arg,&v, sizeof(v))) { - return -EFAULT; - } break; - case 1: + case 1: strcpy(v.name,"AM"); v.rangelow=8320; /* 520 kHz */ v.rangehigh=26400; /* 1650 kHz */ - v.flags=0; - v.flags|=VIDEO_TUNER_LOW; - v.mode=0; - v.mode|=VIDEO_MODE_AUTO; - v.signal=sigstrength; - if(copy_to_user(arg,&v, sizeof(v))) { - return -EFAULT; - } + v.flags = VIDEO_TUNER_LOW; + v.mode = VIDEO_MODE_AUTO; break; + default: + return -EINVAL; } + v.signal=sigstrength; + if(copy_to_user(arg,&v, sizeof(v))) { + return -EFAULT; + } return 0; } case VIDIOCSTUNER: { struct video_tuner v; - if(copy_from_user(&v, arg, sizeof(v))) { + if(copy_from_user(&v, arg, sizeof(v))) return -EFAULT; - } - if((v.tuner<0)||(v.tuner>1)) { + + if(v.tuner < 0 || v.tuner > 1) return -EINVAL; - } + curtuner=v.tuner; return 0; } @@ -468,25 +434,24 @@ case VIDIOCSFREQ: if(copy_from_user(&freq, arg,sizeof(freq))) return -EFAULT; - if((curtuner==0)&&((freq<1400)||(freq>1728))) { + if(curtuner==0 && (freq<1400 || freq>1728)) return -EINVAL; - } - if((curtuner==1)&&((freq<8320)||(freq>26400))) { + if(curtuner==1 && (freq<8320 || freq>26400)) return -EINVAL; - } + cadet_setfreq(freq); return 0; + case VIDIOCGAUDIO: { struct video_audio v; memset(&v,0, sizeof(v)); v.flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; - if(cadet_getstereo()==0) { + if(cadet_getstereo()==0) v.mode=VIDEO_SOUND_MONO; - } - else { - v.mode=VIDEO_SOUND_STEREO; - } + else + v.mode=VIDEO_SOUND_STEREO; + v.volume=cadet_getvol(); v.step=0xffff; strcpy(v.name, "Radio"); @@ -525,10 +490,8 @@ static void cadet_close(struct video_device *dev) { - if(rdsstat==1) { - del_timer(&readtimer); - rdsstat=0; - } + del_timer_sync(&readtimer); + rdsstat=0; users--; } @@ -557,13 +520,13 @@ if (!(dev->resource[0].flags & IORESOURCE_IO)) return -ENODEV; if (dev->activate(dev)<0) { - printk ("radio-cadet: isapnp configure failed (out of resources?)\n"); + printk(KERN_ERR "radio-cadet: isapnp configure failed (out of resources?)\n"); return -ENOMEM; } io = dev->resource[0].start; - printk ("radio-cadet: ISAPnP reports card at %#x\n", io); + printk(KERN_INFO "radio-cadet: ISAPnP reports card at %#x\n", io); return io; } @@ -575,7 +538,7 @@ for(i=0;i<8;i++) { io=iovals[i]; - if(request_region(io,2, "cadet-probe")>=0) { + if(request_region(io,2, "cadet-probe") != NULL) { cadet_setfreq(1410); if(cadet_getfreq()==1410) { release_region(io, 2); @@ -594,6 +557,9 @@ static int __init cadet_init(void) { + + spin_lock_init(&cadet_io_lock); + /* * If a probe was requested then probe ISAPnP first (safest) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/radio/radio-maxiradio.c linux.21pre4-ac6/drivers/media/radio/radio-maxiradio.c --- linux.21pre4/drivers/media/radio/radio-maxiradio.c 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/radio/radio-maxiradio.c 2003-02-06 16:04:19.000000000 +0000 @@ -54,7 +54,7 @@ /* TEA5757 pin mappings */ -const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ; +static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ; static int radio_nr = -1; MODULE_PARM(radio_nr, "i"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/bttv-driver.c linux.21pre4-ac6/drivers/media/video/bttv-driver.c --- linux.21pre4/drivers/media/video/bttv-driver.c 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/bttv-driver.c 2003-02-06 16:06:37.000000000 +0000 @@ -1507,7 +1507,7 @@ v.tuners=0; v.type=VIDEO_TYPE_CAMERA; v.norm = btv->win.norm; - if (v.channel>=bttv_tvcards[btv->type].video_inputs) + if (v.channel < 0 || v.channel >= bttv_tvcards[btv->type].video_inputs) return -EINVAL; if(v.channel==bttv_tvcards[btv->type].tuner) { @@ -1534,7 +1534,7 @@ if(copy_from_user(&v, arg,sizeof(v))) return -EFAULT; - if (v.channel>bttv_tvcards[btv->type].video_inputs) + if (v.channel < 0 || v.channel >= bttv_tvcards[btv->type].video_inputs) return -EINVAL; if (v.norm > (sizeof(tvnorms)/sizeof(*tvnorms))) return -EOPNOTSUPP; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/cpia.c linux.21pre4-ac6/drivers/media/video/cpia.c --- linux.21pre4/drivers/media/video/cpia.c 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/cpia.c 2003-02-19 15:55:06.000000000 +0000 @@ -6,6 +6,7 @@ * (C) Copyright 1999-2000 Peter Pregler * (C) Copyright 1999-2000 Scott J. Bertin * (C) Copyright 1999-2000 Johannes Erdfelt + * (C) Copyright 2000 STMicroelectronics * * 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 @@ -22,7 +23,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* #define _CPIA_DEBUG_ define for verbose debug output */ +/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */ +/* #define _CPIA_DEBUG_ 1 */ + #include #include @@ -512,6 +515,46 @@ return len; } +static int match(char *checkstr, char **buffer, unsigned long *count, + int *find_colon, int *err) +{ + int ret, colon_found = 1; + int len = strlen(checkstr); + ret = (len <= *count && strncmp(*buffer, checkstr, len) == 0); + if (ret) { + *buffer += len; + *count -= len; + if (*find_colon) { + colon_found = 0; + while (*count && (**buffer == ' ' || **buffer == '\t' || + (!colon_found && **buffer == ':'))) { + if (**buffer == ':') + colon_found = 1; + --*count; + ++*buffer; + } + if (!*count || !colon_found) + *err = -EINVAL; + *find_colon = 0; + } + } + return ret; +} + +static unsigned long int value(char **buffer, unsigned long *count, int *err) +{ + char *p; + unsigned long int ret; + ret = simple_strtoul(*buffer, &p, 0); + if (p == *buffer) + *err = -EINVAL; + else { + *count -= p - *buffer; + *buffer = p; + } + return ret; +} + static int cpia_write_proc(struct file *file, const char *buf, unsigned long count, void *data) { @@ -566,44 +609,11 @@ memcpy(&new_params, &cam->params, sizeof(struct cam_params)); new_mains = cam->mainsFreq; -#define MATCH(x) \ - ({ \ - int _len = strlen(x), _ret, _colon_found; \ - _ret = (_len <= count && strncmp(buffer, x, _len) == 0); \ - if (_ret) { \ - buffer += _len; \ - count -= _len; \ - if (find_colon) { \ - _colon_found = 0; \ - while (count && (*buffer == ' ' || *buffer == '\t' || \ - (!_colon_found && *buffer == ':'))) { \ - if (*buffer == ':') \ - _colon_found = 1; \ - --count; \ - ++buffer; \ - } \ - if (!count || !_colon_found) \ - retval = -EINVAL; \ - find_colon = 0; \ - } \ - } \ - _ret; \ - }) +#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval)) +#define VALUE (value(&buffer,&count, &retval)) #define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \ new_params.version.firmwareRevision == (y)) -#define VALUE \ - ({ \ - char *_p; \ - unsigned long int _ret; \ - _ret = simple_strtoul(buffer, &_p, 0); \ - if (_p == buffer) \ - retval = -EINVAL; \ - else { \ - count -= _p - buffer; \ - buffer = _p; \ - } \ - _ret; \ - }) + retval = 0; while (count && !retval) { @@ -1248,10 +1258,9 @@ } } #undef MATCH -#undef FIRMWARE_VERSION #undef VALUE -#undef FIND_VALUE -#undef FIND_END +#undef FIRMWARE_VERSION + if (!retval) { if (command_flags & COMMAND_SETCOLOURPARAMS) { /* Adjust cam->vp to reflect these changes */ @@ -1560,7 +1569,7 @@ } -static void inline free_frames(struct cpia_frame frame[FRAME_NUM]) +static inline void free_frames(struct cpia_frame frame[FRAME_NUM]) { int i; @@ -1745,7 +1754,7 @@ retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data); if (retval) - LOG("%x - failed\n", command); + DBG("%x - failed\n", command); return retval; } @@ -1970,7 +1979,7 @@ while (size > 0) { size -= (ll+2); if (size < 0) { - LOG("Insufficient data in buffer\n"); + DBG("Insufficient data in buffer\n"); return -1; } @@ -1985,7 +1994,7 @@ int skipsize = skipcount(*ibuf >> 1, out_fmt); obuf += skipsize; if (obuf > end_obuf) { - LOG("Insufficient data in buffer\n"); + DBG("Insufficient data in buffer\n"); return -1; } ++ibuf; @@ -1994,7 +2003,7 @@ } if (ll == 1) { if (*ibuf != EOL) { - LOG("EOL not found giving up after %d/%d" + DBG("EOL not found giving up after %d/%d" " bytes\n", origsize-size, origsize); return -1; } @@ -2012,7 +2021,7 @@ ibuf += 2; /* skip over line length */ } } else { - LOG("line length was not 1 but %d after %d/%d bytes\n", + DBG("line length was not 1 but %d after %d/%d bytes\n", ll, origsize-size, origsize); return -1; } @@ -2501,54 +2510,56 @@ return 0; } +static void put_cam(struct cpia_camera_ops* ops) +{ + if (ops->owner) + __MOD_DEC_USE_COUNT(ops->owner); +} + /* ------------------------- V4L interface --------------------- */ -static int cpia_open(struct video_device *dev, int flags) +static int cpia_open(struct inode *inode, struct file *file) { - int i; + struct video_device *dev = video_devdata(file); struct cam_data *cam = dev->priv; + int err; if (!cam) { DBG("Internal error, cam_data not found!\n"); - return -EBUSY; + return -ENODEV; } - + if (cam->open_count > 0) { DBG("Camera already open\n"); return -EBUSY; } - + + if (!try_inc_mod_count(cam->ops->owner)) + return -ENODEV; + + down(&cam->busy_lock); + + err = -ENOMEM; if (!cam->raw_image) { cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE); if (!cam->raw_image) - return -ENOMEM; + goto oops; } if (!cam->decompressed_frame.data) { cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE); - if (!cam->decompressed_frame.data) { - rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); - cam->raw_image = NULL; - return -ENOMEM; - } + if (!cam->decompressed_frame.data) + goto oops; } /* open cpia */ - if (cam->ops->open(cam->lowlevel_data)) { - rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE); - cam->decompressed_frame.data = NULL; - rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); - cam->raw_image = NULL; - return -ENODEV; - } + err = -ENODEV; + if (cam->ops->open(cam->lowlevel_data)) + goto oops; /* reset the camera */ - if ((i = reset_camera(cam)) != 0) { + if ((err = reset_camera(cam)) != 0) { cam->ops->close(cam->lowlevel_data); - rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE); - cam->decompressed_frame.data = NULL; - rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); - cam->raw_image = NULL; - return i; + goto oops; } /* Set ownership of /proc/cpia/videoX to current user */ @@ -2562,14 +2573,28 @@ cam->mmap_kludge = 0; ++cam->open_count; + file->private_data = dev; + up(&cam->busy_lock); return 0; + + oops: + if (cam->decompressed_frame.data) { + rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE); + cam->decompressed_frame.data = NULL; + } + if (cam->raw_image) { + rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); + cam->raw_image = NULL; + } + up(&cam->busy_lock); + put_cam(cam->ops); + return err; } -static void cpia_close(struct video_device *dev) +static int cpia_close(struct inode *inode, struct file *file) { - struct cam_data *cam; - - cam = dev->priv; + struct video_device *dev = file->private_data; + struct cam_data *cam = dev->priv; if (cam->ops) { /* Return ownership of /proc/cpia/videoX to root */ @@ -2590,6 +2615,7 @@ /* close cpia */ cam->ops->close(cam->lowlevel_data); + put_cam(cam->ops); } if (--cam->open_count == 0) { @@ -2607,20 +2633,20 @@ if (cam->frame_buf) free_frame_buf(cam); - if (!cam->ops) { - video_unregister_device(dev); + if (!cam->ops) kfree(cam); - } } + file->private_data = NULL; - return; + return 0; } -static long cpia_read(struct video_device *dev, char *buf, - unsigned long count, int noblock) +static int cpia_read(struct file *file, char *buf, + size_t count, loff_t *ppos) { - struct cam_data *cam = dev->priv; + struct video_device *dev = file->private_data; + struct cam_data *cam = dev->priv; /* make this _really_ smp and multithread-safe */ if (down_interruptible(&cam->busy_lock)) @@ -2659,7 +2685,7 @@ /* copy data to user space */ if (cam->decompressed_frame.count > count) { DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count, - count); + (unsigned long) count); up(&cam->busy_lock); return -EFAULT; } @@ -2674,8 +2700,10 @@ return cam->decompressed_frame.count; } -static int cpia_ioctl(struct video_device *dev, unsigned int ioctlnr, void *arg) +static int cpia_do_ioctl(struct inode *inode, struct file *file, + unsigned int ioctlnr, void *arg) { + struct video_device *dev = file->private_data; struct cam_data *cam = dev->priv; int retval = 0; @@ -2692,20 +2720,17 @@ /* query capabilites */ case VIDIOCGCAP: { - struct video_capability b; + struct video_capability *b = arg; DBG("VIDIOCGCAP\n"); - strcpy(b.name, "CPiA Camera"); - b.type = VID_TYPE_CAPTURE; - b.channels = 1; - b.audios = 0; - b.maxwidth = 352; /* VIDEOSIZE_CIF */ - b.maxheight = 288; - b.minwidth = 48; /* VIDEOSIZE_48_48 */ - b.minheight = 48; - - if (copy_to_user(arg, &b, sizeof(b))) - retval = -EFAULT; + strcpy(b->name, "CPiA Camera"); + b->type = VID_TYPE_CAPTURE; + b->channels = 1; + b->audios = 0; + b->maxwidth = 352; /* VIDEOSIZE_CIF */ + b->maxheight = 288; + b->minwidth = 48; /* VIDEOSIZE_48_48 */ + b->minheight = 48; break; } @@ -2713,39 +2738,30 @@ /* get/set video source - we are a camera and nothing else */ case VIDIOCGCHAN: { - struct video_channel v; + struct video_channel *v = arg; DBG("VIDIOCGCHAN\n"); - if (copy_from_user(&v, arg, sizeof(v))) { - retval = -EFAULT; - break; - } - if (v.channel != 0) { + if (v->channel != 0) { retval = -EINVAL; break; } - v.channel = 0; - strcpy(v.name, "Camera"); - v.tuners = 0; - v.flags = 0; - v.type = VIDEO_TYPE_CAMERA; - v.norm = 0; + v->channel = 0; + strcpy(v->name, "Camera"); + v->tuners = 0; + v->flags = 0; + v->type = VIDEO_TYPE_CAMERA; + v->norm = 0; - if (copy_to_user(arg, &v, sizeof(v))) - retval = -EFAULT; break; } case VIDIOCSCHAN: { - int v; + struct video_channel *v = arg; DBG("VIDIOCSCHAN\n"); - if (copy_from_user(&v, arg, sizeof(v))) - retval = -EFAULT; - - if (retval == 0 && v != 0) + if (v->channel != 0) retval = -EINVAL; break; @@ -2753,38 +2769,35 @@ /* image properties */ case VIDIOCGPICT: + { + struct video_picture *pic = arg; + DBG("VIDIOCGPICT\n"); - if (copy_to_user(arg, &cam->vp, sizeof(struct video_picture))) - retval = -EFAULT; + *pic = cam->vp; break; - + } + case VIDIOCSPICT: { - struct video_picture vp; + struct video_picture *vp = arg; DBG("VIDIOCSPICT\n"); - /* copy_from_user */ - if (copy_from_user(&vp, arg, sizeof(vp))) { - retval = -EFAULT; - break; - } - /* check validity */ - DBG("palette: %d\n", vp.palette); - DBG("depth: %d\n", vp.depth); - if (!valid_mode(vp.palette, vp.depth)) { + DBG("palette: %d\n", vp->palette); + DBG("depth: %d\n", vp->depth); + if (!valid_mode(vp->palette, vp->depth)) { retval = -EINVAL; break; } down(&cam->param_lock); /* brightness, colour, contrast need no check 0-65535 */ - memcpy( &cam->vp, &vp, sizeof(vp) ); + cam->vp = *vp; /* update cam->params.colourParams */ - cam->params.colourParams.brightness = vp.brightness*100/65535; - cam->params.colourParams.contrast = vp.contrast*100/65535; - cam->params.colourParams.saturation = vp.colour*100/65535; + cam->params.colourParams.brightness = vp->brightness*100/65535; + cam->params.colourParams.contrast = vp->contrast*100/65535; + cam->params.colourParams.saturation = vp->colour*100/65535; /* contrast is in steps of 8, so round */ cam->params.colourParams.contrast = ((cam->params.colourParams.contrast + 3) / 8) * 8; @@ -2799,34 +2812,33 @@ cam->cmd_queue |= COMMAND_SETCOLOURPARAMS; up(&cam->param_lock); DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n", - vp.depth, vp.palette, vp.brightness, vp.hue, vp.colour, - vp.contrast); + vp->depth, vp->palette, vp->brightness, vp->hue, + vp->colour, vp->contrast); break; } /* get/set capture window */ case VIDIOCGWIN: + { + struct video_window *vw = arg; + DBG("VIDIOCGWIN\n"); - if (copy_to_user(arg, &cam->vw, sizeof(struct video_window))) - retval = -EFAULT; + *vw = cam->vw; break; - + } + case VIDIOCSWIN: { /* copy_from_user, check validity, copy to internal structure */ - struct video_window vw; + struct video_window *vw = arg; DBG("VIDIOCSWIN\n"); - if (copy_from_user(&vw, arg, sizeof(vw))) { - retval = -EFAULT; - break; - } - if (vw.clipcount != 0) { /* clipping not supported */ + if (vw->clipcount != 0) { /* clipping not supported */ retval = -EINVAL; break; } - if (vw.clips != NULL) { /* clipping not supported */ + if (vw->clips != NULL) { /* clipping not supported */ retval = -EINVAL; break; } @@ -2835,8 +2847,8 @@ * is requested by the user??? */ down(&cam->param_lock); - if (vw.width != cam->vw.width || vw.height != cam->vw.height) { - int video_size = match_videosize(vw.width, vw.height); + if (vw->width != cam->vw.width || vw->height != cam->vw.height) { + int video_size = match_videosize(vw->width, vw->height); if (video_size < 0) { retval = -EINVAL; @@ -2865,41 +2877,34 @@ /* mmap interface */ case VIDIOCGMBUF: { - struct video_mbuf vm; + struct video_mbuf *vm = arg; int i; DBG("VIDIOCGMBUF\n"); - memset(&vm, 0, sizeof(vm)); - vm.size = CPIA_MAX_FRAME_SIZE*FRAME_NUM; - vm.frames = FRAME_NUM; + memset(vm, 0, sizeof(*vm)); + vm->size = CPIA_MAX_FRAME_SIZE*FRAME_NUM; + vm->frames = FRAME_NUM; for (i = 0; i < FRAME_NUM; i++) - vm.offsets[i] = CPIA_MAX_FRAME_SIZE * i; - - if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) - retval = -EFAULT; + vm->offsets[i] = CPIA_MAX_FRAME_SIZE * i; break; } case VIDIOCMCAPTURE: { - struct video_mmap vm; + struct video_mmap *vm = arg; int video_size; - if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) { - retval = -EFAULT; - break; - } - DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm.format, vm.frame, - vm.width, vm.height); - if (vm.frame<0||vm.frame>=FRAME_NUM) { + DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame, + vm->width, vm->height); + if (vm->frame<0||vm->frame>=FRAME_NUM) { retval = -EINVAL; break; } /* set video format */ - cam->vp.palette = vm.format; - switch(vm.format) { + cam->vp.palette = vm->format; + switch(vm->format) { case VIDEO_PALETTE_GREY: cam->vp.depth=8; break; @@ -2924,7 +2929,7 @@ break; /* set video size */ - video_size = match_videosize(vm.width, vm.height); + video_size = match_videosize(vm->width, vm->height); if (video_size < 0) { retval = -EINVAL; break; @@ -2937,37 +2942,33 @@ } /* according to v4l-spec we must start streaming here */ cam->mmap_kludge = 1; - retval = capture_frame(cam, &vm); + retval = capture_frame(cam, vm); break; } case VIDIOCSYNC: { - int frame; + int *frame = arg; - if (copy_from_user((void *)&frame, arg, sizeof(int))) { - retval = -EFAULT; - break; - } - //DBG("VIDIOCSYNC: %d\n", frame); + //DBG("VIDIOCSYNC: %d\n", *frame); - if (frame<0 || frame >= FRAME_NUM) { + if (*frame<0 || *frame >= FRAME_NUM) { retval = -EINVAL; break; } - switch (cam->frame[frame].state) { + switch (cam->frame[*frame].state) { case FRAME_UNUSED: case FRAME_READY: case FRAME_GRABBING: - DBG("sync to unused frame %d\n", frame); + DBG("sync to unused frame %d\n", *frame); retval = -EINVAL; break; case FRAME_DONE: - cam->frame[frame].state = FRAME_UNUSED; - //DBG("VIDIOCSYNC: %d synced\n", frame); + cam->frame[*frame].state = FRAME_UNUSED; + //DBG("VIDIOCSYNC: %d synced\n", *frame); break; } if (retval == -EINTR) { @@ -2979,36 +2980,22 @@ /* pointless to implement overlay with this camera */ case VIDIOCCAPTURE: - retval = -EINVAL; - break; case VIDIOCGFBUF: - retval = -EINVAL; - break; case VIDIOCSFBUF: - retval = -EINVAL; - break; case VIDIOCKEY: retval = -EINVAL; break; /* tuner interface - we have none */ case VIDIOCGTUNER: - retval = -EINVAL; - break; case VIDIOCSTUNER: - retval = -EINVAL; - break; case VIDIOCGFREQ: - retval = -EINVAL; - break; case VIDIOCSFREQ: retval = -EINVAL; break; /* audio interface - we have none */ case VIDIOCGAUDIO: - retval = -EINVAL; - break; case VIDIOCSAUDIO: retval = -EINVAL; break; @@ -3017,16 +3004,23 @@ break; } - up(&cam->param_lock); up(&cam->busy_lock); return retval; } +static int cpia_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return video_usercopy(inode, file, cmd, arg, cpia_do_ioctl); +} + + /* FIXME */ -static int cpia_mmap(struct video_device *dev, const char *adr, - unsigned long size) +static int cpia_mmap(struct file *file, struct vm_area_struct *vma) { - unsigned long start = (unsigned long)adr; + struct video_device *dev = file->private_data; + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; unsigned long page, pos; struct cam_data *cam = dev->priv; int retval; @@ -3074,25 +3068,22 @@ return 0; } -int cpia_video_init(struct video_device *vdev) -{ -#ifdef CONFIG_PROC_FS - create_proc_cpia_cam(vdev->priv); -#endif - return 0; -} +static struct file_operations cpia_fops = { + owner: THIS_MODULE, + open: cpia_open, + release: cpia_close, + read: cpia_read, + mmap: cpia_mmap, + ioctl: cpia_ioctl, + llseek: no_llseek, +}; static struct video_device cpia_template = { owner: THIS_MODULE, name: "CPiA Camera", type: VID_TYPE_CAPTURE, hardware: VID_HARDWARE_CPIA, - open: cpia_open, - close: cpia_close, - read: cpia_read, - ioctl: cpia_ioctl, - mmap: cpia_mmap, - initialize: cpia_video_init, + fops: &cpia_fops, minor: -1, }; @@ -3229,16 +3220,10 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel) { - struct cam_data *camera; - - /* Need a lock when adding/removing cameras. This doesn't happen - * often and doesn't take very long, so grabbing the kernel lock - * should be OK. */ + struct cam_data *camera; - if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL) { - unlock_kernel(); + if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL) return NULL; - } init_camera_struct( camera, ops ); camera->lowlevel_data = lowlevel; @@ -3246,7 +3231,6 @@ /* register v4l device */ if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { kfree(camera); - unlock_kernel(); printk(KERN_DEBUG "video_register_device failed\n"); return NULL; } @@ -3266,6 +3250,10 @@ /* close cpia */ camera->ops->close(camera->lowlevel_data); +#ifdef CONFIG_PROC_FS + create_proc_cpia_cam(camera); +#endif + printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n", camera->params.version.firmwareVersion, camera->params.version.firmwareRevision, @@ -3285,12 +3273,10 @@ void cpia_unregister_camera(struct cam_data *cam) { - if (!cam->open_count) { - DBG("unregistering video\n"); - video_unregister_device(&cam->vdev); - } else { - LOG("/dev/video%d removed while open, " - "deferring video_unregister_device\n", cam->vdev.minor); + DBG("unregistering video\n"); + video_unregister_device(&cam->vdev); + if (cam->open_count) { + put_cam(cam->ops); DBG("camera open -- setting ops to NULL\n"); cam->ops = NULL; } @@ -3313,9 +3299,6 @@ proc_cpia_create(); #endif -#ifdef CONFIG_VIDEO_CPIA_PP - cpia_pp_init(); -#endif #ifdef CONFIG_KMOD #ifdef CONFIG_VIDEO_CPIA_PP_MODULE request_module("cpia_pp"); @@ -3325,6 +3308,10 @@ request_module("cpia_usb"); #endif #endif /* CONFIG_KMOD */ + +#ifdef CONFIG_VIDEO_CPIA_PP + cpia_pp_init(); +#endif #ifdef CONFIG_VIDEO_CPIA_USB cpia_usb_init(); #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/cpia.h linux.21pre4-ac6/drivers/media/video/cpia.h --- linux.21pre4/drivers/media/video/cpia.h 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/cpia.h 2003-02-21 16:32:35.000000000 +0000 @@ -27,12 +27,16 @@ */ #define CPIA_MAJ_VER 0 -#define CPIA_MIN_VER 8 -#define CPIA_PATCH_VER 1 +#define CPIA_MIN_VER 8 +#define CPIA_PATCH_VER 5 -#define CPIA_PP_MAJ_VER 0 -#define CPIA_PP_MIN_VER 8 -#define CPIA_PP_PATCH_VER 1 +#define CPIA_PP_MAJ_VER CPIA_MAJ_VER +#define CPIA_PP_MIN_VER CPIA_MIN_VER +#define CPIA_PP_PATCH_VER CPIA_PATCH_VER + +#define CPIA_USB_MAJ_VER CPIA_MAJ_VER +#define CPIA_USB_MIN_VER CPIA_MIN_VER +#define CPIA_USB_PATCH_VER CPIA_PATCH_VER #define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */ #define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */ @@ -41,6 +45,7 @@ #include #include +#include #include struct cpia_camera_ops @@ -93,6 +98,10 @@ * is STREAM_READY before calling streamRead. */ int wait_for_stream_ready; + /* + * Used to maintain lowlevel module usage counts + */ + struct module *owner; }; struct cpia_frame { @@ -233,8 +242,7 @@ #define FRAME_NUM 2 /* double buffering for now */ struct cam_data { - struct cam_data **previous; - struct cam_data *next; + struct list_head cam_data_list; struct semaphore busy_lock; /* guard against SMP multithreading */ struct cpia_camera_ops *ops; /* lowlevel driver operations */ @@ -400,24 +408,6 @@ (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\ (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0); -static inline void cpia_add_to_list(struct cam_data* l, struct cam_data* drv) -{ - drv->next = l; - drv->previous = &l; - l = drv; -} - -static inline void cpia_remove_from_list(struct cam_data* drv) -{ - if (drv->previous != NULL) { - if (drv->next != NULL) - drv->next->previous = drv->previous; - *(drv->previous) = drv->next; - drv->previous = NULL; - drv->next = NULL; - } -} - #endif /* __KERNEL__ */ #endif /* cpia_h */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/cpia_pp.c linux.21pre4-ac6/drivers/media/video/cpia_pp.c --- linux.21pre4/drivers/media/video/cpia_pp.c 2003-01-29 16:27:01.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/cpia_pp.c 2003-02-19 15:55:06.000000000 +0000 @@ -22,6 +22,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */ +/* #define _CPIA_DEBUG_ 1 */ + #include #include @@ -33,6 +36,7 @@ #include #include #include +#include #include @@ -50,65 +54,6 @@ #define ABOUT "Parallel port driver for Vision CPiA based cameras" -/* IEEE 1284 Compatiblity Mode signal names */ -#define nStrobe PARPORT_CONTROL_STROBE /* inverted */ -#define nAutoFd PARPORT_CONTROL_AUTOFD /* inverted */ -#define nInit PARPORT_CONTROL_INIT -#define nSelectIn PARPORT_CONTROL_SELECT -#define IntrEnable PARPORT_CONTROL_INTEN /* normally zero for no IRQ */ -#define DirBit PARPORT_CONTROL_DIRECTION /* 0 = Forward, 1 = Reverse */ - -#define nFault PARPORT_STATUS_ERROR -#define Select PARPORT_STATUS_SELECT -#define PError PARPORT_STATUS_PAPEROUT -#define nAck PARPORT_STATUS_ACK -#define Busy PARPORT_STATUS_BUSY /* inverted */ - -/* some more */ -#define HostClk nStrobe -#define HostAck nAutoFd -#define nReverseRequest nInit -#define Active_1284 nSelectIn -#define nPeriphRequest nFault -#define XFlag Select -#define nAckReverse PError -#define PeriphClk nAck -#define PeriphAck Busy - -/* these can be used to correct for the inversion on some bits */ -#define STATUS_INVERSION_MASK (Busy) -#define CONTROL_INVERSION_MASK (nStrobe|nAutoFd|nSelectIn) - -#define ECR_empty 0x01 -#define ECR_full 0x02 -#define ECR_serviceIntr 0x04 -#define ECR_dmaEn 0x08 -#define ECR_nErrIntrEn 0x10 - -#define ECR_mode_mask 0xE0 -#define ECR_SPP_mode 0x00 -#define ECR_PS2_mode 0x20 -#define ECR_FIFO_mode 0x40 -#define ECR_ECP_mode 0x60 - -#define ECP_FIFO_SIZE 16 -#define DMA_BUFFER_SIZE PAGE_SIZE - /* for 16bit DMA make sure DMA_BUFFER_SIZE is 16 bit aligned */ -#define PARPORT_CHUNK_SIZE PAGE_SIZE/* >=2.3.x */ - /* we read this many bytes at once */ - -#define GetECRMasked(port,mask) (parport_read_econtrol(port) & (mask)) -#define GetStatus(port) ((parport_read_status(port)^STATUS_INVERSION_MASK)&(0xf8)) -#define SetStatus(port,val) parport_write_status(port,(val)^STATUS_INVERSION_MASK) -#define GetControl(port) ((parport_read_control(port)^CONTROL_INVERSION_MASK)&(0x3f)) -#define SetControl(port,val) parport_write_control(port,(val)^CONTROL_INVERSION_MASK) - -#define GetStatusMasked(port,mask) (GetStatus(port) & (mask)) -#define GetControlMasked(port,mask) (GetControl(port) & (mask)) -#define SetControlMasked(port,mask) SetControl(port,GetControl(port) | (mask)); -#define ClearControlMasked(port,mask) SetControl(port,GetControl(port)&~(mask)); -#define FrobControlBit(port,mask,value) SetControl(port,(GetControl(port)&~(mask))|((value)&(mask))); - #define PACKET_LENGTH 8 /* Magic numbers for defining port-device mappings */ @@ -156,35 +101,13 @@ cpia_pp_streamStop, cpia_pp_streamRead, cpia_pp_close, - 1 + 1, + THIS_MODULE }; -static struct cam_data *cam_list; +static LIST_HEAD(cam_list); static spinlock_t cam_list_lock_pp; -#ifdef _CPIA_DEBUG_ -#define DEB_PORT(port) { \ -u8 controll = GetControl(port); \ -u8 statusss = GetStatus(port); \ -DBG("nsel %c per %c naut %c nstrob %c nak %c busy %c nfaul %c sel %c init %c dir %c\n",\ -((controll & nSelectIn) ? 'U' : 'D'), \ -((statusss & PError) ? 'U' : 'D'), \ -((controll & nAutoFd) ? 'U' : 'D'), \ -((controll & nStrobe) ? 'U' : 'D'), \ -((statusss & nAck) ? 'U' : 'D'), \ -((statusss & Busy) ? 'U' : 'D'), \ -((statusss & nFault) ? 'U' : 'D'), \ -((statusss & Select) ? 'U' : 'D'), \ -((controll & nInit) ? 'U' : 'D'), \ -((controll & DirBit) ? 'R' : 'F') \ -); } -#else -#define DEB_PORT(port) {} -#endif - -#define WHILE_OUT_TIMEOUT (HZ/10) -#define DMA_TIMEOUT 10*HZ - /* FIXME */ static void cpia_parport_enable_irq( struct parport *port ) { parport_enable_irq(port); @@ -198,6 +121,14 @@ return; } +/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility + * Link Flag during negotiation */ +#define UPLOAD_FLAG 0x08 +#define ECP_TRANSFER 0x03 + +#define PARPORT_CHUNK_SIZE PAGE_SIZE + + /**************************************************************************** * * EndTransferMode @@ -240,7 +171,7 @@ { int retry; int mode = IEEE1284_MODE_ECP; - if(extensibility) mode = 8|3|IEEE1284_EXT_LINK; + if(extensibility) mode = UPLOAD_FLAG|ECP_TRANSFER|IEEE1284_EXT_LINK; /* After some commands the camera needs extra time before * it will respond again, so we try up to 3 times */ @@ -345,11 +276,22 @@ * cpia_pp_streamRead * ***************************************************************************/ +static int cpia_pp_read(struct parport *port, u8 *buffer, int len) +{ + int bytes_read, new_bytes; + for(bytes_read=0; bytes_readport, buffer, CPIA_MAX_IMAGE_SIZE ); - - EndTransferMode(cam); - DBG("read %d bytes\n", read_bytes); - if( read_bytes<0) return -EIO; - endseen = 0; endseen = 0; - for( i=0; i3 ) { - cam->image_complete=1; - DBG("endseen at %d bytes\n", i); + block_size = PARPORT_CHUNK_SIZE; + while( !cam->image_complete ) { + if(current->need_resched) schedule(); + + new_bytes = cpia_pp_read(cam->port, buffer, block_size ); + if( new_bytes <= 0 ) { + break; + } + i=-1; + while(++iimage_complete=1; + break; + } + if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) { + block_size=CPIA_MAX_IMAGE_SIZE-read_bytes; + } } + EndTransferMode(cam); return cam->image_complete ? read_bytes : -EIO; } @@ -566,7 +517,7 @@ return -ENXIO; } spin_lock( &cam_list_lock_pp ); - cpia_add_to_list(cam_list, cpia); + list_add( &cpia->cam_data_list, &cam_list ); spin_unlock( &cam_list_lock_pp ); return 0; @@ -574,27 +525,34 @@ static void cpia_pp_detach (struct parport *port) { - struct cam_data *cpia; + struct list_head *tmp; + struct cam_data *cpia = NULL; + struct pp_cam_entry *cam; spin_lock( &cam_list_lock_pp ); - for(cpia = cam_list; cpia != NULL; cpia = cpia->next) { - struct pp_cam_entry *cam = cpia->lowlevel_data; + list_for_each (tmp, &cam_list) { + cpia = list_entry(tmp, struct cam_data, cam_data_list); + cam = (struct pp_cam_entry *) cpia->lowlevel_data; if (cam && cam->port->number == port->number) { - cpia_remove_from_list(cpia); - spin_unlock( &cam_list_lock_pp ); - cpia_unregister_camera(cpia); - - if(cam->open_count > 0) { - cpia_pp_close(cam); - } - - parport_unregister_device(cam->pdev); - - kfree(cam); - cpia->lowlevel_data = NULL; + list_del(&cpia->cam_data_list); break; } + cpia = NULL; + } + spin_unlock( &cam_list_lock_pp ); + + if (!cpia) { + DBG("cpia_pp_detach failed to find cam_data in cam_list\n"); + return; } + + cam = (struct pp_cam_entry *) cpia->lowlevel_data; + cpia_unregister_camera(cpia); + if(cam->open_count > 0) + cpia_pp_close(cam); + parport_unregister_device(cam->pdev); + cpia->lowlevel_data = NULL; + kfree(cam); } static void cpia_pp_attach (struct parport *port) @@ -642,14 +600,12 @@ return 0; } + spin_lock_init( &cam_list_lock_pp ); + if (parport_register_driver (&cpia_pp_driver)) { LOG ("unable to register with parport\n"); return -EIO; } - - cam_list = NULL; - spin_lock_init( &cam_list_lock_pp ); - return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/cpia_usb.c linux.21pre4-ac6/drivers/media/video/cpia_usb.c --- linux.21pre4/drivers/media/video/cpia_usb.c 2003-01-29 16:27:02.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/cpia_usb.c 2003-02-19 15:55:06.000000000 +0000 @@ -21,11 +21,13 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */ +/* #define _CPIA_DEBUG_ 1 */ + #include #include #include #include -#include #include #include #include @@ -100,10 +102,11 @@ cpia_usb_streamStop, cpia_usb_streamRead, cpia_usb_close, - 0 + 0, + THIS_MODULE }; -static struct cam_data *cam_list; +static LIST_HEAD(cam_list); static spinlock_t cam_list_lock_usb; static void cpia_usb_complete(struct urb *urb) @@ -456,12 +459,14 @@ { struct usb_cpia *ucpia = (struct usb_cpia *) privdata; - ucpia->open = 0; + if(!ucpia) + return -ENODEV; - cpia_usb_free_resources(ucpia, 1); + ucpia->open = 0; - if (!ucpia->present) - kfree(ucpia); + /* ucpia->present = 0 protects against trying to reset the + * alt setting if camera is physically disconnected while open */ + cpia_usb_free_resources(ucpia, ucpia->present); return 0; } @@ -540,7 +545,7 @@ } spin_lock( &cam_list_lock_usb ); - cpia_add_to_list(cam_list, cam); + list_add( &cam->cam_data_list, &cam_list ); spin_unlock( &cam_list_lock_usb ); return cam; @@ -555,6 +560,7 @@ vfree(ucpia->buffers[0]); ucpia->buffers[0] = NULL; fail_alloc_0: + kfree(ucpia); return NULL; } @@ -578,76 +584,57 @@ id_table: cpia_id_table, }; -/* don't use dev, it may be NULL! (see usb_cpia_cleanup) */ -/* _disconnect from usb_cpia_cleanup is not necessary since usb_deregister */ -/* will do it for us as well as passing a udev structure - jerdfelt */ static void cpia_disconnect(struct usb_device *udev, void *ptr) { struct cam_data *cam = (struct cam_data *) ptr; struct usb_cpia *ucpia = (struct usb_cpia *) cam->lowlevel_data; spin_lock( &cam_list_lock_usb ); - cpia_remove_from_list(cam); + list_del(&cam->cam_data_list); spin_unlock( &cam_list_lock_usb ); - /* Don't even try to reset the altsetting if we're disconnected */ - cpia_usb_free_resources(ucpia, 0); - ucpia->present = 0; - cpia_unregister_camera(cam); + if(ucpia->open) + cpia_usb_close(cam->lowlevel_data); ucpia->curbuff->status = FRAME_ERROR; - if (waitqueue_active(&ucpia->wq_stream)) wake_up_interruptible(&ucpia->wq_stream); - usb_driver_release_interface(&cpia_driver, &udev->actconfig->interface[0]); - ucpia->curbuff = ucpia->workbuff = NULL; - if (ucpia->buffers[2]) { vfree(ucpia->buffers[2]); ucpia->buffers[2] = NULL; } - if (ucpia->buffers[1]) { vfree(ucpia->buffers[1]); ucpia->buffers[1] = NULL; } - if (ucpia->buffers[0]) { vfree(ucpia->buffers[0]); ucpia->buffers[0] = NULL; } - if (!ucpia->open) { - kfree(ucpia); - cam->lowlevel_data = NULL; - } + cam->lowlevel_data = NULL; + kfree(ucpia); } static int __init usb_cpia_init(void) { - cam_list = NULL; + printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, + CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER); + spin_lock_init(&cam_list_lock_usb); return usb_register(&cpia_driver); } static void __exit usb_cpia_cleanup(void) { -/* - struct cam_data *cam; - - while ((cam = cam_list) != NULL) - cpia_disconnect(NULL, cam); -*/ - usb_deregister(&cpia_driver); } - module_init (usb_cpia_init); module_exit (usb_cpia_cleanup); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/meye.c linux.21pre4-ac6/drivers/media/video/meye.c --- linux.21pre4/drivers/media/video/meye.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/meye.c 2003-02-24 00:01:05.000000000 +0000 @@ -1,7 +1,7 @@ /* * Motion Eye video4linux driver for Sony Vaio PictureBook * - * Copyright (C) 2001-2002 Stelian Pop + * Copyright (C) 2001-2003 Stelian Pop * * Copyright (C) 2001-2002 Alcôve * @@ -1225,6 +1225,42 @@ .fops = &meye_fops, }; +#ifdef CONFIG_PM +static int meye_suspend(struct pci_dev *pdev, u32 state) +{ + pci_save_state(pdev, meye.pm_state); + meye.pm_mchip_mode = meye.mchip_mode; + mchip_hic_stop(); + mchip_set(MCHIP_MM_INTA, 0x0); + return 0; +} + +static int meye_resume(struct pci_dev *pdev) +{ + pci_restore_state(pdev, meye.pm_state); + pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1); + + mchip_delay(MCHIP_HIC_CMD, 0); + mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE); + wait_ms(1); + mchip_set(MCHIP_VRJ_SOFT_RESET, 1); + wait_ms(1); + mchip_set(MCHIP_MM_PCI_MODE, 5); + wait_ms(1); + mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); + + switch (meye.pm_mchip_mode) { + case MCHIP_HIC_MODE_CONT_OUT: + mchip_continuous_start(); + break; + case MCHIP_HIC_MODE_CONT_COMP: + mchip_cont_compression_start(); + break; + } + return 0; +} +#endif + static int __devinit meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) { int ret; @@ -1391,6 +1427,10 @@ .id_table = meye_pci_tbl, .probe = meye_probe, .remove = __devexit_p(meye_remove), +#ifdef CONFIG_PM + .suspend = meye_suspend, + .resume = meye_resume, +#endif }; static int __init meye_init_module(void) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/meye.h linux.21pre4-ac6/drivers/media/video/meye.h --- linux.21pre4/drivers/media/video/meye.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/meye.h 2003-02-24 00:01:05.000000000 +0000 @@ -1,7 +1,7 @@ /* * Motion Eye video4linux driver for Sony Vaio PictureBook * - * Copyright (C) 2001-2002 Stelian Pop + * Copyright (C) 2001-2003 Stelian Pop * * Copyright (C) 2001-2002 Alcôve * @@ -31,7 +31,13 @@ #define _MEYE_PRIV_H_ #define MEYE_DRIVER_MAJORVERSION 1 -#define MEYE_DRIVER_MINORVERSION 5 +#define MEYE_DRIVER_MINORVERSION 6 + +#include +#include +#include +#include +#include /****************************************************************************/ /* Motion JPEG chip registers */ @@ -309,6 +315,10 @@ struct video_device video_dev; /* video device parameters */ struct video_picture picture; /* video picture parameters */ struct meye_params params; /* additional parameters */ +#ifdef CONFIG_PM + u32 pm_state[16]; /* PCI configuration space */ + u8 pm_mchip_mode; /* old mchip mode */ +#endif }; #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/media/video/w9966.c linux.21pre4-ac6/drivers/media/video/w9966.c --- linux.21pre4/drivers/media/video/w9966.c 2003-01-29 16:27:04.000000000 +0000 +++ linux.21pre4-ac6/drivers/media/video/w9966.c 2003-02-06 22:34:07.000000000 +0000 @@ -931,7 +931,7 @@ if(copy_from_user(&vtune, arg, sizeof(vtune)) != 0) return -EFAULT; - if(vtune.tuner != 0); + if(vtune.tuner != 0) return -EINVAL; strcpy(vtune.name, "no tuner"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/message/fusion/mptbase.c linux.21pre4-ac6/drivers/message/fusion/mptbase.c --- linux.21pre4/drivers/message/fusion/mptbase.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/message/fusion/mptbase.c 2003-02-19 16:20:11.000000000 +0000 @@ -1802,6 +1802,7 @@ if (this != NULL) { int sz; u32 state; + int ret; /* Disable the FW */ state = mpt_GetIocState(this, 1); @@ -1812,9 +1813,9 @@ if (this->cached_fw != NULL) { ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n")); - if ((state = mpt_downloadboot(this, NO_SLEEP)) < 0) { + if ((ret = mpt_downloadboot(this, NO_SLEEP)) < 0) { printk(KERN_WARNING MYNAM - ": firmware downloadboot failure (%d)!\n", state); + ": firmware downloadboot failure (%d)!\n", ret); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/mtd/maps/Config.in linux.21pre4-ac6/drivers/mtd/maps/Config.in --- linux.21pre4/drivers/mtd/maps/Config.in 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/mtd/maps/Config.in 2003-01-29 17:18:17.000000000 +0000 @@ -19,7 +19,7 @@ if [ "$CONFIG_X86" = "y" ]; then dep_tristate ' CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS - dep_tristate ' CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI + dep_tristate ' CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI $CONFIG_MTD_CONCAT dep_tristate ' CFI Flash device mapped on AMD NetSc520' CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/mtd/nftlmount.c linux.21pre4-ac6/drivers/mtd/nftlmount.c --- linux.21pre4/drivers/mtd/nftlmount.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/mtd/nftlmount.c 2003-02-06 22:43:19.000000000 +0000 @@ -94,7 +94,7 @@ /* To be safer with BIOS, also use erase mark as discriminant */ if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, - 8, &retlen, (char *)&h1) < 0)) { + 8, &retlen, (char *)&h1)) < 0) { printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n", block * nftl->EraseSize, nftl->mtd->index, ret); continue; @@ -113,7 +113,7 @@ /* Finally reread to check ECC */ if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, - &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP) < 0)) { + &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n", block * nftl->EraseSize, nftl->mtd->index, ret); continue; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/3c523.c linux.21pre4-ac6/drivers/net/3c523.c --- linux.21pre4/drivers/net/3c523.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/3c523.c 2003-01-09 00:47:04.000000000 +0000 @@ -1125,7 +1125,7 @@ len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; if(len != skb->len) - memset((char *) p->xmit_cbuffs[p->xmit)count], 0, ETH_ZLEN); + memset((char *) p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN); memcpy((char *) p->xmit_cbuffs[p->xmit_count], (char *) (skb->data), skb->len); #if (NUM_XMIT_BUFFS == 1) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/3c527.c linux.21pre4-ac6/drivers/net/3c527.c --- linux.21pre4/drivers/net/3c527.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/3c527.c 2003-01-06 15:38:18.000000000 +0000 @@ -1086,6 +1086,12 @@ /* We will need this to flush the buffer out */ lp->tx_ring[lp->tx_ring_head].skb=skb; + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + goto out; + } np->length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; np->data = virt_to_bus(skb->data); @@ -1094,7 +1100,7 @@ wmb(); p->control &= ~CONTROL_EOL; /* Clear EOL on p */ - +out: restore_flags(flags); netif_wake_queue(dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/3c59x.c linux.21pre4-ac6/drivers/net/3c59x.c --- linux.21pre4/drivers/net/3c59x.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/3c59x.c 2003-01-29 17:18:58.000000000 +0000 @@ -166,6 +166,11 @@ - Rename wait_for_completion() to issue_and_wait() to avoid completion.h clash. + LK1.1.18ac 01Jul02 akpm + - Fix for undocumented transceiver power-up bit on some 3c566B's + (Donald Becker, Rahul Karnik) + + - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details. - Also see Documentation/networking/vortex.txt */ @@ -181,8 +186,8 @@ #define DRV_NAME "3c59x" -#define DRV_VERSION "LK1.1.16" -#define DRV_RELDATE "19 July 2001" +#define DRV_VERSION "LK1.1.18-ac" +#define DRV_RELDATE "1 July 2002" @@ -400,7 +405,7 @@ EEPROM_8BIT=0x10, /* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */ HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100, INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800, - EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000 }; + EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000 }; enum vortex_chips { CH_3C590 = 0, @@ -509,7 +514,7 @@ HAS_HWCKSM, 128, }, {"3c556B Laptop Hurricane", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| - HAS_HWCKSM, 128, }, + WNO_XCVR_PWR|HAS_HWCKSM, 128, }, {"3c575 [Megahertz] 10/100 LAN CardBus", PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, @@ -1190,6 +1195,10 @@ if (vp->drv_flags & INVERT_MII_PWR) n |= 0x4000; outw(n, ioaddr + Wn2_ResetOptions); + if (vp->drv_flags & WNO_XCVR_PWR) { + EL3WINDOW(0); + outw(0x0800, ioaddr); + } } /* Extract our information from the EEPROM data. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/82596.c linux.21pre4-ac6/drivers/net/82596.c --- linux.21pre4/drivers/net/82596.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/82596.c 2003-01-06 15:38:15.000000000 +0000 @@ -1066,12 +1066,19 @@ struct i596_private *lp = (struct i596_private *) dev->priv; struct tx_cmd *tx_cmd; struct i596_tbd *tbd; - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; dev->trans_start = jiffies; DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%x) called\n", dev->name, skb->len, (unsigned int)skb->data)); + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } netif_stop_queue(dev); tx_cmd = lp->tx_cmds + lp->next_tx_cmd; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/a2065.c linux.21pre4-ac6/drivers/net/a2065.c --- linux.21pre4/drivers/net/a2065.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/a2065.c 2003-01-12 17:59:12.000000000 +0000 @@ -574,6 +574,15 @@ unsigned long flags; skblen = skb->len; + len = skblen; + + if(len < ETH_ZLEN) + { + len = ETH_ZLEN; + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } save_flags(flags); cli(); @@ -595,7 +604,6 @@ } } #endif - len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; entry = lp->tx_new & lp->tx_ring_mod_mask; ib->btx_ring [entry].length = (-len) | 0xf000; ib->btx_ring [entry].misc = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/am79c961a.c linux.21pre4-ac6/drivers/net/am79c961a.c --- linux.21pre4/drivers/net/am79c961a.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/am79c961a.c 2003-01-06 15:38:16.000000000 +0000 @@ -409,10 +409,19 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; - unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + unsigned int length = skb->len; unsigned int hdraddr, bufaddr; unsigned int head; unsigned long flags; + + /* FIXME: I thought the 79c961 could do padding - RMK ??? */ + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } head = priv->txhead; hdraddr = priv->txhdr + (head << 3); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/amd8111e.c linux.21pre4-ac6/drivers/net/amd8111e.c --- linux.21pre4/drivers/net/amd8111e.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/amd8111e.c 2003-02-06 22:34:59.000000000 +0000 @@ -953,7 +953,7 @@ reg_buff = kmalloc( AMD8111E_REG_DUMP_LEN,GFP_KERNEL); if(NULL == reg_buff) return NULL; - for( i=0; i< AMD8111E_REG_DUMP_LEN;i+=4); + for( i=0; i< AMD8111E_REG_DUMP_LEN;i+=4) reg_buff[i]= readl(mmio + i); return reg_buff; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/ariadne.c linux.21pre4-ac6/drivers/net/ariadne.c --- linux.21pre4/drivers/net/ariadne.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/ariadne.c 2003-01-06 15:38:15.000000000 +0000 @@ -577,6 +577,7 @@ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; int entry; unsigned long flags; + int len = skb->len; #if 0 if (ariadne_debug > 3) { @@ -587,6 +588,15 @@ } #endif + /* FIXME: is the 79C960 new enough to do its own padding right ? */ + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + len = ETH_ZLEN; + } + /* Fill in a Tx ring entry */ #if 0 @@ -617,8 +627,7 @@ priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); priv->tx_ring[entry]->TMD3 = 0x0000; - memcpyw(priv->tx_buff[entry], (u_short *)skb->data, - skb->len <= ETH_ZLEN ? ETH_ZLEN : skb->len); + memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); #if 0 { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/atarilance.c linux.21pre4-ac6/drivers/net/atarilance.c --- linux.21pre4/drivers/net/atarilance.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/atarilance.c 2003-01-06 15:38:15.000000000 +0000 @@ -786,6 +786,22 @@ DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name, DREG )); + + /* The old LANCE chips doesn't automatically pad buffers to min. size. */ + len = skb->len; + if(len < ETH_ZLEN) + len = ETH_ZLEN; + /* PAM-Card has a bug: Can only send packets with even number of bytes! */ + else if (lp->cardtype == PAM_CARD && (len & 1)) + ++len; + + if(len > skb->len) + { + skb = skb_padto(skb, len); + if(skb == NULL) + return 0; + } + netif_stop_queue (dev); /* Fill in a Tx ring entry */ @@ -815,11 +831,6 @@ * last. */ - /* The old LANCE chips doesn't automatically pad buffers to min. size. */ - len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; - /* PAM-Card has a bug: Can only send packets with even number of bytes! */ - if (lp->cardtype == PAM_CARD && (len & 1)) - ++len; head->length = -len; head->misc = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/bagetlance.c linux.21pre4-ac6/drivers/net/bagetlance.c --- linux.21pre4/drivers/net/bagetlance.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/bagetlance.c 2003-01-06 15:38:18.000000000 +0000 @@ -835,6 +835,19 @@ struct lance_tx_head *head; unsigned long flags; + /* The old LANCE chips doesn't automatically pad buffers to min. size. */ + len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + /* PAM-Card has a bug: Can only send packets with even number of bytes! */ + if (lp->cardtype == PAM_CARD && (len & 1)) + ++len; + + if (len > skb->len) + { + skb = skb_padto(skb, len); + if(skb == NULL) + return 0; + } + /* Transmitter timeout, serious problems. */ if (dev->tbusy) { int tickssofar = jiffies - dev->trans_start; @@ -921,12 +934,6 @@ * last. */ - /* The old LANCE chips doesn't automatically pad buffers to min. size. */ - len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; - /* PAM-Card has a bug: Can only send packets with even number of bytes! */ - if (lp->cardtype == PAM_CARD && (len & 1)) - ++len; - head->length = -len; head->misc = 0; lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/Config.in linux.21pre4-ac6/drivers/net/Config.in --- linux.21pre4/drivers/net/Config.in 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/Config.in 2003-02-19 16:01:10.000000000 +0000 @@ -100,6 +100,9 @@ if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX fi + if [ "$CONFIG_PCI" = "y" ]; then + tristate ' 3cr990 series "Typhoon" support' CONFIG_TYPHOON + fi fi dep_tristate ' AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE $CONFIG_ISA bool ' Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC @@ -250,7 +253,7 @@ dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate 'Realtek 8169 Gigabit Ethernet support' CONFIG_R8169 $CONFIG_PCI -dep_tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN $CONFIG_PCI +dep_tristate 'SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support' CONFIG_SK98LIN $CONFIG_PCI dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/declance.c linux.21pre4-ac6/drivers/net/declance.c --- linux.21pre4/drivers/net/declance.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/declance.c 2003-01-06 15:38:18.000000000 +0000 @@ -870,7 +870,15 @@ skblen = skb->len; - len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; + len = skblen; + + if(len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + len = ETH_ZLEN; + } lp->stats.tx_bytes += len; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/depca.c linux.21pre4-ac6/drivers/net/depca.c --- linux.21pre4/drivers/net/depca.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/depca.c 2003-01-06 15:38:15.000000000 +0000 @@ -862,6 +862,13 @@ if (skb->len < 1) goto out; + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + goto out; + } + netif_stop_queue(dev); if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/e100/e100_vendor.h linux.21pre4-ac6/drivers/net/e100/e100_vendor.h --- linux.21pre4/drivers/net/e100/e100_vendor.h 2003-01-29 16:26:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/e100/e100_vendor.h 2003-02-21 15:43:35.000000000 +0000 @@ -303,6 +303,7 @@ {0x8086, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, {0x8086, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET}, {0x8086, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, + {0x8086, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, {0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82562}, {0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82562}, {0,} /* This has to be the last entry*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/e2100.c linux.21pre4-ac6/drivers/net/e2100.c --- linux.21pre4/drivers/net/e2100.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/e2100.c 2003-01-28 19:16:46.000000000 +0000 @@ -72,12 +72,12 @@ #define E21_SAPROM 0x10 /* Offset to station address data. */ #define E21_IO_EXTENT 0x20 -static inline void mem_on(short port, volatile char *mem_base, +static inline void mem_on(short port, unsigned long mem_base, unsigned char start_page ) { /* This is a little weird: set the shared memory window by doing a read. The low address bits specify the starting page. */ - readb(mem_base+start_page); + isa_readb(mem_base+start_page); inb(port + E21_MEM_ENABLE); outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON); } @@ -300,15 +300,15 @@ { short ioaddr = dev->base_addr; - char *shared_mem = (char *)dev->mem_start; + unsigned long shared_mem = dev->mem_start; mem_on(ioaddr, shared_mem, ring_page); #ifdef notdef /* Officially this is what we are doing, but the readl() is faster */ - memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr)); #else - ((unsigned int*)hdr)[0] = readl(shared_mem); + ((unsigned int*)hdr)[0] = isa_readl(shared_mem); #endif /* Turn off memory access: we would need to reprogram the window anyway. */ @@ -323,12 +323,11 @@ e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { short ioaddr = dev->base_addr; - char *shared_mem = (char *)dev->mem_start; - mem_on(ioaddr, shared_mem, (ring_offset>>8)); + mem_on(ioaddr, dev->mem_start, (ring_offset>>8)); /* Packet is always in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0); + isa_eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0); mem_off(ioaddr); } @@ -338,14 +337,14 @@ int start_page) { short ioaddr = dev->base_addr; - volatile char *shared_mem = (char *)dev->mem_start; + unsigned long shared_mem = dev->mem_start; /* Set the shared memory window start by doing a read, with the low address bits specifying the starting page. */ - readb(shared_mem + start_page); + isa_readb(shared_mem + start_page); mem_on(ioaddr, shared_mem, start_page); - memcpy_toio(shared_mem, buf, count); + isa_memcpy_toio(shared_mem, buf, count); mem_off(ioaddr); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/eepro.c linux.21pre4-ac6/drivers/net/eepro.c --- linux.21pre4/drivers/net/eepro.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/eepro.c 2003-01-06 15:38:15.000000000 +0000 @@ -1128,17 +1128,24 @@ struct eepro_local *lp = (struct eepro_local *)dev->priv; unsigned long flags; int ioaddr = dev->base_addr; + short length = skb->len; if (net_debug > 5) printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name); + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } netif_stop_queue (dev); eepro_dis_int(ioaddr); spin_lock_irqsave(&lp->lock, flags); { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; if (hardware_send_packet(dev, buf, length)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/eexpress.c linux.21pre4-ac6/drivers/net/eexpress.c --- linux.21pre4/drivers/net/eexpress.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/eexpress.c 2003-01-06 15:38:15.000000000 +0000 @@ -640,6 +640,7 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; + short length = buf->len; #ifdef CONFIG_SMP unsigned long flags; #endif @@ -648,6 +649,14 @@ printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name); #endif + if(buf->len < ETH_ZLEN) + { + buf = skb_padto(buf, ETH_ZLEN); + if(buf == NULL) + return 0; + length = buf->len; + } + disable_irq(dev->irq); /* @@ -660,8 +669,6 @@ #endif { - unsigned short length = (ETH_ZLEN < buf->len) ? buf->len : - ETH_ZLEN; unsigned short *data = (unsigned short *)buf->data; lp->stats.tx_bytes += length; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/epic100.c linux.21pre4-ac6/drivers/net/epic100.c --- linux.21pre4/drivers/net/epic100.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/epic100.c 2003-01-06 15:38:16.000000000 +0000 @@ -975,6 +975,13 @@ int entry, free_count; u32 ctrl_word; long flags; + + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } /* Caution: the write order is important here, set the field with the "ownership" bit last. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/eth16i.c linux.21pre4-ac6/drivers/net/eth16i.c --- linux.21pre4/drivers/net/eth16i.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/eth16i.c 2003-01-06 15:38:15.000000000 +0000 @@ -1056,10 +1056,17 @@ struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; int status = 0; - ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + ushort length = skb->len; unsigned char *buf = skb->data; unsigned long flags; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } netif_stop_queue(dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/fmv18x.c linux.21pre4-ac6/drivers/net/fmv18x.c --- linux.21pre4/drivers/net/fmv18x.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/fmv18x.c 2003-01-06 15:38:15.000000000 +0000 @@ -369,7 +369,7 @@ { struct net_local *lp = dev->priv; int ioaddr = dev->base_addr; - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; unsigned char *buf = skb->data; unsigned long flags; @@ -381,6 +381,15 @@ dev->name, length); return 1; } + + if (length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + if (net_debug > 4) printk("%s: Transmitting a packet of length %lu.\n", dev->name, (unsigned long)skb->len); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/hp100.c linux.21pre4-ac6/drivers/net/hp100.c --- linux.21pre4/drivers/net/hp100.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/hp100.c 2003-01-06 15:38:15.000000000 +0000 @@ -1542,6 +1542,13 @@ if (skb->len <= 0) return 0; + + if (skb->len < ETH_ZLEN && lp->chip == HP100_CHIPID_SHASTA) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } /* Get Tx ring tail pointer */ if (lp->txrtail->next == lp->txrhead) { @@ -2099,6 +2106,7 @@ struct hp100_private *lp = (struct hp100_private *) dev->priv; #ifdef HP100_DEBUG_B + int ioaddr = dev->base_addr; hp100_outw(0x4216, TRACE); printk("hp100: %s: misc_interrupt\n", dev->name); #endif @@ -2538,6 +2546,11 @@ return HP100_LAN_10; if (val_10 & HP100_AUI_ST) { /* have we BNC or AUI onboard? */ + /* + * This can be overriden by dos utility, so if this has no effect, + * perhaps you need to download that utility from HP and set card + * back to "auto detect". + */ val_10 |= HP100_AUI_SEL | HP100_LOW_TH; hp100_page(MAC_CTRL); hp100_outb(val_10, 10_LAN_CFG_1); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/lance.c linux.21pre4-ac6/drivers/net/lance.c --- linux.21pre4/drivers/net/lance.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/lance.c 2003-01-06 15:38:15.000000000 +0000 @@ -893,8 +893,15 @@ /* The old LANCE chips doesn't automatically pad buffers to min. size. */ if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) { - lp->tx_ring[entry].length = - -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + goto out; + lp->tx_ring[entry].length = -ETH_ZLEN; + } + else + lp->tx_ring[entry].length = -skb->len; } else lp->tx_ring[entry].length = -skb->len; @@ -927,6 +934,7 @@ if ((lp->cur_tx - lp->dirty_tx) >= TX_RING_SIZE) netif_stop_queue(dev); +out: spin_unlock_irqrestore(&lp->devlock, flags); return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/lasi_82596.c linux.21pre4-ac6/drivers/net/lasi_82596.c --- linux.21pre4/drivers/net/lasi_82596.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/lasi_82596.c 2003-01-06 15:38:19.000000000 +0000 @@ -1084,12 +1084,20 @@ struct i596_private *lp = (struct i596_private *) dev->priv; struct tx_cmd *tx_cmd; struct i596_tbd *tbd; - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; dev->trans_start = jiffies; DEB(DEB_STARTTX,printk("%s: i596_start_xmit(%x,%p) called\n", dev->name, skb->len, skb->data)); + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + netif_stop_queue(dev); tx_cmd = lp->tx_cmds + lp->next_tx_cmd; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/lp486e.c linux.21pre4-ac6/drivers/net/lp486e.c --- linux.21pre4/drivers/net/lp486e.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/lp486e.c 2003-01-06 15:38:18.000000000 +0000 @@ -886,7 +886,16 @@ if (skb->len <= 0) return 0; - length = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + length = skb->len; + + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + dev->trans_start = jiffies; tx_cmd = (struct tx_cmd *) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/Makefile linux.21pre4-ac6/drivers/net/Makefile --- linux.21pre4/drivers/net/Makefile 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/Makefile 2003-02-19 16:01:10.000000000 +0000 @@ -70,6 +70,7 @@ obj-$(CONFIG_DGRS) += dgrs.o obj-$(CONFIG_RCPCI) += rcpci.o obj-$(CONFIG_VORTEX) += 3c59x.o mii.o +obj-$(CONFIG_TYPHOON) += typhoon.o obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o obj-$(CONFIG_PCNET32) += pcnet32.o mii.o obj-$(CONFIG_EEPRO100) += eepro100.o mii.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/pci-skeleton.c linux.21pre4-ac6/drivers/net/pci-skeleton.c --- linux.21pre4/drivers/net/pci-skeleton.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/pci-skeleton.c 2003-02-19 16:07:08.000000000 +0000 @@ -1348,6 +1348,16 @@ void *ioaddr = tp->mmio_addr; int entry; + /* If we don't have auto-pad remember not to send random + memory! */ + + if (skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + /* Calculate the next Tx descriptor entry. */ entry = atomic_read (&tp->cur_tx) % NUM_TX_DESC; @@ -1358,9 +1368,8 @@ /* tp->tx_info[entry].mapping = 0; */ memcpy (tp->tx_buf[entry], skb->data, skb->len); - /* Note: the chip doesn't have auto-pad! */ NETDRV_W32 (TxStatus0 + (entry * sizeof(u32)), - tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + tp->tx_flag | skb->len); dev->trans_start = jiffies; atomic_inc (&tp->cur_tx); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/pcmcia/fmvj18x_cs.c linux.21pre4-ac6/drivers/net/pcmcia/fmvj18x_cs.c --- linux.21pre4/drivers/net/pcmcia/fmvj18x_cs.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/pcmcia/fmvj18x_cs.c 2003-01-06 15:38:19.000000000 +0000 @@ -952,11 +952,19 @@ { struct local_info_t *lp = (struct local_info_t *)dev->priv; ioaddr_t ioaddr = dev->base_addr; + short length = skb->len; + + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } netif_stop_queue(dev); { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; if (length > ETH_FRAME_LEN) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/pcmcia/ray_cs.c linux.21pre4-ac6/drivers/net/pcmcia/ray_cs.c --- linux.21pre4/drivers/net/pcmcia/ray_cs.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/pcmcia/ray_cs.c 2003-01-06 15:38:19.000000000 +0000 @@ -1054,7 +1054,7 @@ { ray_dev_t *local = dev->priv; dev_link_t *link = local->finder; - short length; + short length = skb->len; if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_dev_start_xmit - device not present\n"); @@ -1070,7 +1070,13 @@ } } - length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) { case XMIT_NO_CCS: case XMIT_NEED_AUTH: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/pcmcia/xirc2ps_cs.c linux.21pre4-ac6/drivers/net/pcmcia/xirc2ps_cs.c --- linux.21pre4/drivers/net/pcmcia/xirc2ps_cs.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/pcmcia/xirc2ps_cs.c 2003-01-06 15:38:19.000000000 +0000 @@ -1548,7 +1548,6 @@ DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n", skb, dev, pktlen); - netif_stop_queue(dev); /* adjust the packet length to min. required * and hope that the buffer is large enough @@ -1558,8 +1557,14 @@ * pad this in his buffer with random bytes */ if (pktlen < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; pktlen = ETH_ZLEN; + } + netif_stop_queue(dev); SelectPage(0); PutWord(XIRCREG0_TRS, (u_short)pktlen+2); freespace = GetWord(XIRCREG0_TSO); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/pcmcia/xircom_tulip_cb.c linux.21pre4-ac6/drivers/net/pcmcia/xircom_tulip_cb.c --- linux.21pre4/drivers/net/pcmcia/xircom_tulip_cb.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/pcmcia/xircom_tulip_cb.c 2003-01-06 15:38:19.000000000 +0000 @@ -923,6 +923,14 @@ /* Calculate the next Tx descriptor entry. */ entry = tp->cur_tx % TX_RING_SIZE; + /* Seems to be needed even though the docs disagree */ + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + tp->tx_skbuff[entry] = skb; #ifdef CARDBUS if (tp->chip_id == X3201_3) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/pcnet32.c linux.21pre4-ac6/drivers/net/pcnet32.c --- linux.21pre4/drivers/net/pcnet32.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/pcnet32.c 2003-02-05 17:25:58.000000000 +0000 @@ -1,5 +1,5 @@ -/* pcnet32.c: An AMD PCnet32 ethernet driver for linux. */ -/* +/* pcnet32.c: An AMD PCnet32 ethernet driver for linux. + * * Copyright 1996-1999 Thomas Bogendoerfer * * Derived from the lance driver written 1993,1994,1995 by Donald Becker. @@ -549,7 +549,7 @@ /* initialize variables */ fdx = mii = fset = dxsuflo = ltint = 0; chip_version = (chip_version >> 12) & 0xffff; - + switch (chip_version) { case 0x2420: chipname = "PCnet/PCI 79C970"; /* PCI */ @@ -1194,19 +1194,12 @@ if (err_status & 0x04000000) lp->stats.tx_aborted_errors++; if (err_status & 0x08000000) lp->stats.tx_carrier_errors++; if (err_status & 0x10000000) lp->stats.tx_window_errors++; -#ifndef DO_DXSUFLO if (err_status & 0x40000000) { lp->stats.tx_fifo_errors++; - /* Ackk! On FIFO errors the Tx unit is turned off! */ - /* Remove this verbosity later! */ - printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n", - dev->name, csr0); - must_restart = 1; - } -#else - if (err_status & 0x40000000) { - lp->stats.tx_fifo_errors++; - if (! lp->dxsuflo) { /* If controller doesn't recover ... */ +#ifdef DO_DXSUFLO + if (! lp->dxsuflo) +#endif + { /* If controller doesn't recover ... */ /* Ackk! On FIFO errors the Tx unit is turned off! */ /* Remove this verbosity later! */ printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n", @@ -1214,7 +1207,6 @@ must_restart = 1; } } -#endif } else { if (status & 0x1800) lp->stats.collisions++; @@ -1486,7 +1478,9 @@ crc = ether_crc_le(6, addrs); crc = crc >> 26; - mcast_table [crc >> 4] |= 1 << (crc & 0xf); + mcast_table [crc >> 4] = le16_to_cpu( + le16_to_cpu(mcast_table [crc >> 4]) | (1 << (crc & 0xf)) + ); } return; } @@ -1754,12 +1748,13 @@ } } + module_init(pcnet32_init_module); module_exit(pcnet32_cleanup_module); /* * Local variables: - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c pcnet32.c" + * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include/linux -Wall -Wstrict-prototypes -O2 -m486 -c pcnet32.c" * c-indent-level: 4 * tab-width: 8 * End: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/r8169.c linux.21pre4-ac6/drivers/net/r8169.c --- linux.21pre4/drivers/net/r8169.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/r8169.c 2003-02-11 17:44:25.000000000 +0000 @@ -41,6 +41,8 @@ #include #include #include +#include +#include #define RTL8169_VERSION "1.2" #define MODULENAME "r8169" @@ -819,6 +821,13 @@ void *ioaddr = tp->mmio_addr; int entry = tp->cur_tx % NUM_TX_DESC; + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + spin_lock_irq(&tp->lock); if ((tp->TxDescArray[entry].status & OWNbit) == 0) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/saa9730.c linux.21pre4-ac6/drivers/net/saa9730.c --- linux.21pre4/drivers/net/saa9730.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/saa9730.c 2003-02-06 16:04:53.000000000 +0000 @@ -265,7 +265,7 @@ lp->NextRcvPacketIndex = 0; lp->NextRcvToUseIsA = 1; - /* Set current buffer index & next availble packet index */ + /* Set current buffer index & next available packet index */ lp->NextTxmPacketIndex = 0; lp->NextTxmBufferIndex = 0; lp->PendingTxmPacketIndex = 0; @@ -520,7 +520,7 @@ lp->NextRcvPacketIndex = 0; lp->NextRcvToUseIsA = 1; - /* Set current buffer index & next availble packet index */ + /* Set current buffer index & next available packet index */ lp->NextTxmPacketIndex = 0; lp->NextTxmBufferIndex = 0; lp->PendingTxmPacketIndex = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/seeq8005.c linux.21pre4-ac6/drivers/net/seeq8005.c --- linux.21pre4/drivers/net/seeq8005.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/seeq8005.c 2003-01-06 15:38:15.000000000 +0000 @@ -378,9 +378,16 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; unsigned char *buf = skb->data; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } /* Block a timer-based transmit from overlapping */ netif_stop_queue(dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/build_no.c linux.21pre4-ac6/drivers/net/sk98lin/build_no.c --- linux.21pre4/drivers/net/sk98lin/build_no.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/net/sk98lin/build_no.c 2003-01-06 15:38:18.000000000 +0000 @@ -0,0 +1,10 @@ +/****************************************************************************** + * + * Name: Build_No.c + * Version: 1.01 + * + */ + +static const char SysKonnectBuildNumber[] = + "@(#)SK-BUILD: 6.02 (20021219) PL: ALL.01"; + \ No newline at end of file diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/lm80.h linux.21pre4-ac6/drivers/net/sk98lin/h/lm80.h --- linux.21pre4/drivers/net/sk98lin/h/lm80.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/lm80.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: lm80.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.3 $ - * Date: $Date: 1999/11/22 13:41:19 $ + * Version: $Revision: 1.4 $ + * Date: $Date: 2002/04/25 11:04:10 $ * Purpose: Contains all defines for the LM80 Chip * (National Semiconductor). * @@ -11,8 +11,7 @@ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -27,6 +26,9 @@ * * History: * $Log: lm80.h,v $ + * Revision 1.4 2002/04/25 11:04:10 rschmidt + * Editorial changes + * * Revision 1.3 1999/11/22 13:41:19 cgoos * Changed license header to GPL. * @@ -53,23 +55,23 @@ * * All registers are 8 bit wide */ -#define LM80_CFG 0x00 /* Configuration Register */ -#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */ -#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */ -#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */ -#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */ +#define LM80_CFG 0x00 /* Configuration Register */ +#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */ +#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */ +#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */ +#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */ #define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */ #define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */ /* 0x07 - 0x1f reserved */ /* current values */ -#define LM80_VT0_IN 0x20 /* current Voltage 0 value */ -#define LM80_VT1_IN 0x21 /* current Voltage 1 value */ -#define LM80_VT2_IN 0x22 /* current Voltage 2 value */ -#define LM80_VT3_IN 0x23 /* current Voltage 3 value */ -#define LM80_VT4_IN 0x24 /* current Voltage 4 value */ -#define LM80_VT5_IN 0x25 /* current Voltage 5 value */ -#define LM80_VT6_IN 0x26 /* current Voltage 6 value */ -#define LM80_TEMP_IN 0x27 /* current temperature value */ +#define LM80_VT0_IN 0x20 /* current Voltage 0 value */ +#define LM80_VT1_IN 0x21 /* current Voltage 1 value */ +#define LM80_VT2_IN 0x22 /* current Voltage 2 value */ +#define LM80_VT3_IN 0x23 /* current Voltage 3 value */ +#define LM80_VT4_IN 0x24 /* current Voltage 4 value */ +#define LM80_VT5_IN 0x25 /* current Voltage 5 value */ +#define LM80_VT6_IN 0x26 /* current Voltage 6 value */ +#define LM80_TEMP_IN 0x27 /* current Temperature value */ #define LM80_FAN1_IN 0x28 /* current Fan 1 count */ #define LM80_FAN2_IN 0x29 /* current Fan 2 count */ /* limit values */ @@ -111,23 +113,23 @@ /* LM80_ISRC_1 Interrupt Status Register 1 */ /* LM80_IMSK_1 Interrupt Mask Register 1 */ -#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */ -#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */ -#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */ -#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */ -#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */ -#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */ -#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */ +#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */ +#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */ +#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */ +#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */ +#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */ +#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */ +#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */ #define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */ /* LM80_ISRC_2 Interrupt Status Register 2 */ /* LM80_IMSK_2 Interrupt Mask Register 2 */ #define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */ -#define LM80_IS_BTI (1<<1) /* state of BTI# pin */ +#define LM80_IS_BTI (1<<1) /* state of BTI# pin */ #define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */ #define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */ -#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */ -#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */ +#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */ +#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */ /* bit 6 and 7 are reserved in LM80_ISRC_2 */ #define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */ #define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */ @@ -181,7 +183,7 @@ /* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */ /* 0x3e - 0x3f reserved */ -#define LM80_ADDR 0x28 /* LM80 default addr */ +#define LM80_ADDR 0x28 /* LM80 default addr */ /* typedefs *******************************************************************/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skaddr.h linux.21pre4-ac6/drivers/net/sk98lin/h/skaddr.h --- linux.21pre4/drivers/net/sk98lin/h/skaddr.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skaddr.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skaddr.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.24 $ - * Date: $Date: 2001/01/22 13:41:34 $ + * Version: $Revision: 1.26 $ + * Date: $Date: 2002/11/15 07:24:42 $ * Purpose: Header file for Address Management (MC, UC, Prom). * ******************************************************************************/ @@ -26,6 +26,14 @@ * History: * * $Log: skaddr.h,v $ + * Revision 1.26 2002/11/15 07:24:42 tschilli + * SK_ADDR_EQUAL macro fixed. + * + * Revision 1.25 2002/06/10 13:55:18 tschilli + * Changes for handling YUKON. + * All changes are internally and not visible to the programmer + * using this module. + * * Revision 1.24 2001/01/22 13:41:34 rassmann * Supporting two nets on dual-port adapters. * @@ -144,7 +152,7 @@ /* ----- Common return values ----- */ #define SK_ADDR_SUCCESS 0 /* Function returned successfully. */ -#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */ +#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */ #define SK_ADDR_TOO_EARLY 101 /* Function called too early. */ /* ----- Clear/Add flag bits ----- */ @@ -198,6 +206,7 @@ /* Macros */ +#if 0 #ifndef SK_ADDR_EQUAL /* * "&" instead of "&&" allows better optimization on IA-64. @@ -217,6 +226,23 @@ (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0]))) #endif /* SK_ADDR_DWORD_COMPARE */ #endif /* SK_ADDR_EQUAL */ +#endif /* 0 */ + +#ifndef SK_ADDR_EQUAL +#ifndef SK_ADDR_DWORD_COMPARE +#define SK_ADDR_EQUAL(A1,A2) ( \ + (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \ + (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \ + (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \ + (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \ + (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \ + (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0])) +#else /* SK_ADDR_DWORD_COMPARE */ +#define SK_ADDR_EQUAL(A1,A2) ( \ + (*(SK_U16 *)&(((SK_U8 *)(A1))[4]) == *(SK_U16 *)&(((SK_U8 *)(A2))[4])) && \ + (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0]))) +#endif /* SK_ADDR_DWORD_COMPARE */ +#endif /* SK_ADDR_EQUAL */ /* typedefs *******************************************************************/ @@ -239,13 +265,13 @@ /* ----- Public part (read-only) ----- */ - SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */ + SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */ SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */ - int PromMode; /* Promiscuous Mode. */ + int PromMode; /* Promiscuous Mode. */ /* ----- Private part ----- */ - SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */ + SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */ SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */ SK_U8 Align01; @@ -255,18 +281,20 @@ SK_U32 NextExactMatchDrv; SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES]; SK_FILTER64 InexactFilter; /* For 64-bit hash register. */ + SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */ + SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */ } SK_ADDR_PORT; struct s_AddrNet { /* ----- Public part (read-only) ----- */ - SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */ + SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */ SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */ /* ----- Private part ----- */ - SK_U32 ActivePort; /* View of module ADDR. */ + SK_U32 ActivePort; /* View of module ADDR. */ SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */ SK_U8 Align01; SK_U16 Align02; @@ -294,38 +322,86 @@ extern int SkAddrInit( SK_AC *pAC, SK_IOC IoC, - int Level); + int Level); extern int SkAddrMcClear( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); + int Flags); + +extern int SkAddrXmacMcClear( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int Flags); + +extern int SkAddrGmacMcClear( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int Flags); extern int SkAddrMcAdd( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, SK_MAC_ADDR *pMc, - int Flags); + int Flags); + +extern int SkAddrXmacMcAdd( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + SK_MAC_ADDR *pMc, + int Flags); + +extern int SkAddrGmacMcAdd( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + SK_MAC_ADDR *pMc, + int Flags); extern int SkAddrMcUpdate( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +extern int SkAddrXmacMcUpdate( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber); + +extern int SkAddrGmacMcUpdate( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber); + extern int SkAddrOverride( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, SK_MAC_ADDR *pNewAddr, - int Flags); + int Flags); extern int SkAddrPromiscuousChange( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int NewPromMode); + int NewPromMode); + +extern int SkAddrXmacPromiscuousChange( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int NewPromMode); + +extern int SkAddrGmacPromiscuousChange( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int NewPromMode); extern int SkAddrSwap( SK_AC *pAC, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skdebug.h linux.21pre4-ac6/drivers/net/sk98lin/h/skdebug.h --- linux.21pre4/drivers/net/sk98lin/h/skdebug.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skdebug.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: skdebug.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.10 $ - * Date: $Date: 1999/11/22 13:47:40 $ + * Version: $Revision: 1.12 $ + * Date: $Date: 2002/07/15 15:37:13 $ * Purpose: SK specific DEBUG support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +25,13 @@ * * History: * $Log: skdebug.h,v $ + * Revision 1.12 2002/07/15 15:37:13 rschmidt + * Power Management support + * Editorial changes + * + * Revision 1.11 2002/04/25 11:04:39 rschmidt + * Editorial changes + * * Revision 1.10 1999/11/22 13:47:40 cgoos * Changed license header to GPL. * @@ -89,26 +95,25 @@ #define SK_DBGMOD_MERR 0x00000001L /* general module error indication */ #define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */ -#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */ -#define SK_DBGMOD_VPD 0x00000008L /* VPD module */ -#define SK_DBGMOD_I2C 0x00000010L /* I2C module */ -#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */ -#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */ -#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ +#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */ +#define SK_DBGMOD_VPD 0x00000008L /* VPD module */ +#define SK_DBGMOD_I2C 0x00000010L /* I2C module */ +#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */ +#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */ +#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ #define SK_DBGMOD_PECP 0x00000100L /* PECP module */ +#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */ /* Debug events */ -#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */ -#define SK_DBGCAT_CTRL 0x00000002L /* controlling: add/rmv MCA/MAC - * and other controls (IOCTL) - */ -#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */ -#define SK_DBGCAT_TX 0x00000008L /* transmit path */ -#define SK_DBGCAT_RX 0x00000010L /* receive path */ -#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */ -#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */ -#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */ -#define SK_DBGCAT_FATAL 0x00000100L /* large data output e.g. hex dump */ +#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */ +#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */ +#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */ +#define SK_DBGCAT_TX 0x00000008L /* transmit path */ +#define SK_DBGCAT_RX 0x00000010L /* receive path */ +#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */ +#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */ +#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */ +#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */ #endif /* __INC_SKDEBUG_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skdrv1st.h linux.21pre4-ac6/drivers/net/sk98lin/h/skdrv1st.h --- linux.21pre4/drivers/net/sk98lin/h/skdrv1st.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skdrv1st.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skdrv1st.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.9.2.1 $ - * Date: $Date: 2001/03/12 16:50:59 $ + * Version: $Revision: 1.9.2.2 $ + * Date: $Date: 2001/12/07 12:06:42 $ * Purpose: First header file for driver and all other modules * ******************************************************************************/ @@ -27,6 +27,9 @@ * History: * * $Log: skdrv1st.h,v $ + * Revision 1.9.2.2 2001/12/07 12:06:42 mlindner + * Fix: malloc -> slab changes + * * Revision 1.9.2.1 2001/03/12 16:50:59 mlindner * chg: kernel 2.4 adaption * @@ -84,6 +87,10 @@ #ifndef __INC_SKDRV1ST_H #define __INC_SKDRV1ST_H +/* Check kernel version */ +#include +#if (LINUX_VERSION_CODE > 0x020300) +#endif typedef struct s_AC SK_AC; @@ -116,7 +123,6 @@ #include #include #include -#include #include #include #include @@ -140,6 +146,8 @@ #define SK_BIG_ENDIAN #endif +#define SK_NET_DEVICE net_device + /* we use gethrtime(), return unit: nanoseconds */ #define SK_TICKS_PER_SEC HZ @@ -161,17 +169,17 @@ #define SK_MEMCPY(dest,src,size) memcpy(dest,src,size) #define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size) #define SK_MEMSET(dest,val,size) memset(dest,val,size) -#define SK_STRLEN(pStr) strlen((char*)pStr) -#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)pDest,(char*)pSrc,size) -#define SK_STRCMP(pStr1,pStr2) strcmp((char*)pStr1,(char*)pStr2) +#define SK_STRLEN(pStr) strlen((char*)(pStr)) +#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size) +#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2)) /* macros to access the adapter */ -#define SK_OUT8(b,a,v) writeb(v, (b+a)) -#define SK_OUT16(b,a,v) writew(v, (b+a)) -#define SK_OUT32(b,a,v) writel(v, (b+a)) -#define SK_IN8(b,a,pv) (*(pv) = readb(b+a)) -#define SK_IN16(b,a,pv) (*(pv) = readw(b+a)) -#define SK_IN32(b,a,pv) (*(pv) = readl(b+a)) +#define SK_OUT8(b,a,v) writeb((v), ((b)+(a))) +#define SK_OUT16(b,a,v) writew((v), ((b)+(a))) +#define SK_OUT32(b,a,v) writel((v), ((b)+(a))) +#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a))) +#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a))) +#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a))) #define int8_t char #define int16_t short @@ -222,11 +230,11 @@ #define SK_DBGCAT_DRV_INT_SRC 0x04000000 #define SK_DBGCAT_DRV_EVENT 0x08000000 -#endif /* DEBUG */ +#endif #define SK_ERR_LOG SkErrorLog extern void SkErrorLog(SK_AC*, int, int, char*); -#endif /* __INC_SKDRV1ST_H */ +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skdrv2nd.h linux.21pre4-ac6/drivers/net/sk98lin/h/skdrv2nd.h --- linux.21pre4/drivers/net/sk98lin/h/skdrv2nd.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skdrv2nd.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skdrv2nd.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.12.2.1 $ - * Date: $Date: 2001/03/12 16:50:59 $ + * Version: $Revision: 1.12.2.2 $ + * Date: $Date: 2001/09/05 12:14:50 $ * Purpose: Second header file for driver and all other modules * ******************************************************************************/ @@ -27,6 +27,9 @@ * History: * * $Log: skdrv2nd.h,v $ + * Revision 1.12.2.2 2001/09/05 12:14:50 mlindner + * add: New hardware revision int + * * Revision 1.12.2.1 2001/03/12 16:50:59 mlindner * chg: kernel 2.4 adaption * @@ -202,7 +205,7 @@ SK_U32 VDataLow; /* Receive buffer Addr, low dword */ SK_U32 VDataHigh; /* Receive buffer Addr, high dword */ SK_U32 FrameStat; /* Receive Frame Status word */ - SK_U32 TimeStamp; /* Time stamp from XMAX */ + SK_U32 TimeStamp; /* Time stamp from XMAC */ SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */ SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */ RXD *pNextRxd; /* Pointer to next Rxd */ @@ -218,7 +221,8 @@ SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */ SK_U32 FrameStat; /* Transmit Frame Status Word */ SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */ - SK_U32 TcpSumStWr; /* TCP Sum Start / TCP Sum Write */ + SK_U16 TcpSumSt; /* TCP Sum Start */ + SK_U16 TcpSumWr; /* TCP Sum Write */ SK_U32 TcpReserved; /* not used */ TXD *pNextTxd; /* Pointer to next Txd */ struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ @@ -445,11 +449,11 @@ int BoardLevel; /* level of active hw init (0-2) */ char DeviceStr[80]; /* adapter string from vpd */ SK_U32 AllocFlag; /* flag allocation of resources */ - struct pci_dev PciDev; /* for access to pci config space */ + struct pci_dev *PciDev; /* for access to pci config space */ SK_U32 PciDevId; /* pci device id */ - struct net_device *dev[2]; /* pointer to device struct */ + struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ char Name[30]; /* driver name */ - struct net_device *Next; /* link all devices (for clearing) */ + struct SK_NET_DEVICE *Next; /* link all devices (for clearing) */ int RxBufSize; /* length of receive buffers */ struct net_device_stats stats; /* linux 'netstat -i' statistics */ int Index; /* internal board index number */ @@ -465,12 +469,12 @@ /* addresses for this board */ /* (may be more than HW can)*/ + int HWRevision; /* Hardware revision */ int ActivePort; /* the active XMAC port */ int MaxPorts; /* number of activated ports */ int TxDescrPerRing; /* # of descriptors per tx ring */ int RxDescrPerRing; /* # of descriptors per rx ring */ - caddr_t pDescrMem; /* Pointer to the descriptor area */ dma_addr_t pDescrMemDMA; /* PCI DMA address of area */ @@ -483,6 +487,11 @@ SK_U32 CsOfs; /* for checksum calculation */ SK_BOOL CheckQueue; /* check event queue soon */ + + /* Only for tests */ + int PortUp; + int PortDown; + }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skerror.h linux.21pre4-ac6/drivers/net/sk98lin/h/skerror.h --- linux.21pre4/drivers/net/sk98lin/h/skerror.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skerror.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: skerror.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.4 $ - * Date: $Date: 1999/11/22 13:51:59 $ + * Version: $Revision: 1.5 $ + * Date: $Date: 2002/04/25 11:05:10 $ * Purpose: SK specific Error log support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +25,9 @@ * * History: * $Log: skerror.h,v $ + * Revision 1.5 2002/04/25 11:05:10 rschmidt + * Editorial changes + * * Revision 1.4 1999/11/22 13:51:59 cgoos * Changed license header to GPL. * @@ -49,29 +51,29 @@ #define _INC_SKERROR_H_ /* - * Define the Error Classes + * Define Error Classes */ -#define SK_ERRCL_OTHER (0) /* Other error */ +#define SK_ERRCL_OTHER (0) /* Other error */ #define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */ #define SK_ERRCL_INIT (1L<<1) /* Initialization error */ -#define SK_ERRCL_NORES (1L<<2) /* Out of resources error */ -#define SK_ERRCL_SW (1L<<3) /* internal Software error */ -#define SK_ERRCL_HW (1L<<4) /* Hardware failure */ +#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */ +#define SK_ERRCL_SW (1L<<3) /* Internal Software error */ +#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */ #define SK_ERRCL_COMM (1L<<5) /* Communication error */ /* - * Define Error code bases + * Define Error Code Bases */ -#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */ -#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */ -#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */ -#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */ -#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */ -#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */ -#define SK_ERRBASE_I2C 700 /* Base Error number for i2C module */ -#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */ -#define SK_ERRBASE_ADDR 900 /* Base Error number for Address mod. */ +#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */ +#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */ +#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */ +#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */ +#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */ +#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */ +#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */ +#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */ +#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */ #define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */ #define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgedrv.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgedrv.h --- linux.21pre4/drivers/net/sk98lin/h/skgedrv.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgedrv.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: skgedrv.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.4 $ - * Date: $Date: 1999/11/22 13:52:46 $ + * Version: $Revision: 1.6 $ + * Date: $Date: 2002/07/15 15:38:01 $ * Purpose: Interface with the driver * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -27,6 +26,13 @@ * History: * * $Log: skgedrv.h,v $ + * Revision 1.6 2002/07/15 15:38:01 rschmidt + * Power Management support + * Editorial changes + * + * Revision 1.5 2002/04/25 11:05:47 rschmidt + * Editorial changes + * * Revision 1.4 1999/11/22 13:52:46 cgoos * Changed license header to GPL. * @@ -49,17 +55,18 @@ /* * Define the driver events. - * Usually the events are defined by the destination module. In case of the - * driver we put the definition of the events here. + * Usually the events are defined by the destination module. + * In case of the driver we put the definition of the events here. */ -#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */ -#define SK_DRV_NET_UP 2 /* The net is now operational */ -#define SK_DRV_NET_DOWN 3 /* The net is now down */ -#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links conn */ -#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */ -#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */ -#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */ -#define SK_DRV_PORT_FAIL 8 /* One port fails */ -#define SK_DRV_SWITCH_INTERN 9 /* Port switch from driver to itself */ +#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */ +#define SK_DRV_NET_UP 2 /* The net is operational */ +#define SK_DRV_NET_DOWN 3 /* The net is down */ +#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */ +#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */ +#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */ +#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */ +#define SK_DRV_PORT_FAIL 8 /* One port fails */ +#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */ +#define SK_DRV_POWER_DOWN 10 /* Power down mode */ #endif /* __INC_SKGEDRV_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgehw.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgehw.h --- linux.21pre4/drivers/net/sk98lin/h/skgehw.h 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgehw.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: skgehw.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.36 $ - * Date: $Date: 2000/11/09 12:32:49 $ - * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product - * Family + * Version: $Revision: 1.48 $ + * Date: $Date: 2002/12/05 10:25:11 $ + * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2000 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +25,61 @@ * * History: * $Log: skgehw.h,v $ + * Revision 1.48 2002/12/05 10:25:11 rschmidt + * Added defines for Half Duplex Burst Mode On/Off + * Added defines for Rx GMAC FIFO Flush feature + * Editorial changes + * + * Revision 1.47 2002/11/12 17:01:31 rschmidt + * Added defines for WOL_CTL_DEFAULT + * Editorial changes + * + * Revision 1.46 2002/10/14 14:47:57 rschmidt + * Corrected bit mask for HW self test results + * Added defines for WOL Registers + * Editorial changes + * + * Revision 1.45 2002/10/11 09:25:22 mkarl + * Added bit mask for HW self test results. + * + * Revision 1.44 2002/08/16 14:44:36 rschmidt + * Added define GPC_HWCFG_GMII_FIB for YUKON Fiber + * + * Revision 1.43 2002/08/12 13:31:50 rschmidt + * Corrected macros for GMAC Address Registers: GM_INADDR(), + * GM_OUTADDR(), GM_INHASH, GM_OUTHASH. + * Editorial changes + * + * Revision 1.42 2002/08/08 15:37:56 rschmidt + * Added defines for Power Management Capabilities + * Editorial changes + * + * Revision 1.41 2002/07/23 16:02:25 rschmidt + * Added macro WOL_REG() to access WOL reg. (HW-Bug in YUKON 1st rev.) + * + * Revision 1.40 2002/07/15 15:41:37 rschmidt + * Added new defines for Power Management Cap. & Control + * Editorial changes + * + * Revision 1.39 2002/06/10 09:37:07 rschmidt + * Added macros for the ADDR-Modul + * + * Revision 1.38 2002/06/05 08:15:19 rschmidt + * Added defines for WOL Registers + * Editorial changes + * + * Revision 1.37 2002/04/25 11:39:23 rschmidt + * Added new defines for PCI Our Register 1 + * Added new registers and defines for YUKON (Rx FIFO, Tx FIFO, + * Time Stamp Timer, GMAC Control, GPHY Control,Link Control, + * GMAC IRQ Source and Mask, Wake-up Frame Pattern Match); + * Added new defines for Control/Status (VAUX available) + * Added Chip ID for YUKON + * Added define for descriptors with UDP ext. for YUKON + * Added macros to access the GMAC + * Added new Phy Type for Marvell 88E1011S (GPHY) + * Editorial changes + * * Revision 1.36 2000/11/09 12:32:49 rassmann * Renamed variables. * @@ -36,7 +90,7 @@ * Changed license header to GPL. * * Revision 1.33 1999/08/27 11:17:10 malthoff - * It's more savely to put bracket around marco parameters. + * It's more savely to put brackets around macro parameters. * Brackets added for PHY_READ and PHY_WRITE. * * Revision 1.32 1999/05/19 07:31:01 cgoos @@ -50,7 +104,7 @@ * Add PCI_ERRBITS. * * Revision 1.29 1999/01/26 08:55:48 malthoff - * Bugfix: The 16 bit field releations inside the descriptor are + * Bugfix: The 16 bit field relations inside the descriptor are * endianess dependend if the descriptor reversal feature * (PCI_REV_DESC bit in PCI_OUR_REG_2) is enabled. * Drivers which use this feature has to set the define @@ -91,7 +145,7 @@ * fix: typo B0_XM_IMSK regs * * Revision 1.18 1998/10/16 09:46:54 malthoff - * Remove temp defines for ML diag prototyp. + * Remove temp defines for ML diag prototype. * Fix register definition for B0_XM1_PHY_DATA, B0_XM1_PHY_DATA * B0_XM2_PHY_DATA, B0_XM2_PHY_ADDR, B0_XA1_CSR, B0_XS1_CSR, * B0_XS2_CSR, and B0_XA2_CSR. @@ -133,7 +187,7 @@ * * Revision 1.10 1998/09/02 11:16:39 malthoff * Temporary modify B2_I2C_SW to make tests with - * the GE/ML prototyp. + * the GE/ML prototype. * * Revision 1.9 1998/08/19 09:11:49 gklug * fix: struct are removed from c-source (see CCC) @@ -145,7 +199,7 @@ * * Revision 1.7 1998/07/03 14:42:26 malthoff * bug fix: Correct macro XMA(). - * Add temporary workaround to access the PCI config space over IO + * Add temporary workaround to access the PCI config space over I/O * * Revision 1.6 1998/06/23 11:30:36 malthoff * Remove ';' with ',' in macors. @@ -174,38 +228,120 @@ /* defines ********************************************************************/ +#define BIT_31 (1UL << 31) +#define BIT_30 (1L << 30) +#define BIT_29 (1L << 29) +#define BIT_28 (1L << 28) +#define BIT_27 (1L << 27) +#define BIT_26 (1L << 26) +#define BIT_25 (1L << 25) +#define BIT_24 (1L << 24) +#define BIT_23 (1L << 23) +#define BIT_22 (1L << 22) +#define BIT_21 (1L << 21) +#define BIT_20 (1L << 20) +#define BIT_19 (1L << 19) +#define BIT_18 (1L << 18) +#define BIT_17 (1L << 17) +#define BIT_16 (1L << 16) +#define BIT_15 (1L << 15) +#define BIT_14 (1L << 14) +#define BIT_13 (1L << 13) +#define BIT_12 (1L << 12) +#define BIT_11 (1L << 11) +#define BIT_10 (1L << 10) +#define BIT_9 (1L << 9) +#define BIT_8 (1L << 8) +#define BIT_7 (1L << 7) +#define BIT_6 (1L << 6) +#define BIT_5 (1L << 5) +#define BIT_4 (1L << 4) +#define BIT_3 (1L << 3) +#define BIT_2 (1L << 2) +#define BIT_1 (1L << 1) +#define BIT_0 1L + +#define BIT_15S (1U << 15) +#define BIT_14S (1 << 14) +#define BIT_13S (1 << 13) +#define BIT_12S (1 << 12) +#define BIT_11S (1 << 11) +#define BIT_10S (1 << 10) +#define BIT_9S (1 << 9) +#define BIT_8S (1 << 8) +#define BIT_7S (1 << 7) +#define BIT_6S (1 << 6) +#define BIT_5S (1 << 5) +#define BIT_4S (1 << 4) +#define BIT_3S (1 << 3) +#define BIT_2S (1 << 2) +#define BIT_1S (1 << 1) +#define BIT_0S 1 + +#define SHIFT31(x) ((x) << 31) +#define SHIFT30(x) ((x) << 30) +#define SHIFT29(x) ((x) << 29) +#define SHIFT28(x) ((x) << 28) +#define SHIFT27(x) ((x) << 27) +#define SHIFT26(x) ((x) << 26) +#define SHIFT25(x) ((x) << 25) +#define SHIFT24(x) ((x) << 24) +#define SHIFT23(x) ((x) << 23) +#define SHIFT22(x) ((x) << 22) +#define SHIFT21(x) ((x) << 21) +#define SHIFT20(x) ((x) << 20) +#define SHIFT19(x) ((x) << 19) +#define SHIFT18(x) ((x) << 18) +#define SHIFT17(x) ((x) << 17) +#define SHIFT16(x) ((x) << 16) +#define SHIFT15(x) ((x) << 15) +#define SHIFT14(x) ((x) << 14) +#define SHIFT13(x) ((x) << 13) +#define SHIFT12(x) ((x) << 12) +#define SHIFT11(x) ((x) << 11) +#define SHIFT10(x) ((x) << 10) +#define SHIFT9(x) ((x) << 9) +#define SHIFT8(x) ((x) << 8) +#define SHIFT7(x) ((x) << 7) +#define SHIFT6(x) ((x) << 6) +#define SHIFT5(x) ((x) << 5) +#define SHIFT4(x) ((x) << 4) +#define SHIFT3(x) ((x) << 3) +#define SHIFT2(x) ((x) << 2) +#define SHIFT1(x) ((x) << 1) +#define SHIFT0(x) ((x) << 0) + /* * Configuration Space header * Since this module is used for different OS', those may be * duplicate on some of them (e.g. Linux). But to keep the * common source, we have to live with this... */ -#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */ -#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */ -#define PCI_COMMAND 0x04 /* 16 bit Command */ -#define PCI_STATUS 0x06 /* 16 bit Status */ -#define PCI_REV_ID 0x08 /* 8 bit Revision ID */ -#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */ -#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */ -#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */ -#define PCI_HEADER_T 0x0e /* 8 bit Header Type */ -#define PCI_BIST 0x0f /* 8 bit Built-in selftest */ -#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */ -#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */ - /* Byte 18..2b: reserved */ -#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */ -#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */ -#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */ - /* Byte 34..33: reserved */ +#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */ +#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */ +#define PCI_COMMAND 0x04 /* 16 bit Command */ +#define PCI_STATUS 0x06 /* 16 bit Status */ +#define PCI_REV_ID 0x08 /* 8 bit Revision ID */ +#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */ +#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */ +#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */ +#define PCI_HEADER_T 0x0e /* 8 bit Header Type */ +#define PCI_BIST 0x0f /* 8 bit Built-in selftest */ +#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */ +#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */ + /* Byte 0x18..0x2b: reserved */ +#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */ +#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */ +#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */ #define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */ /* Byte 35..3b: reserved */ -#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */ -#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */ -#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */ -#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */ +#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */ +#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */ +#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */ +#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */ /* Device Dependent Region */ -#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */ -#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */ +#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */ +#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */ /* Power Management Region */ #define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */ #define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */ @@ -214,11 +350,11 @@ /* Byte 0x4e: reserved */ #define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */ /* VPD Region */ -#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */ +#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */ #define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */ #define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */ #define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */ - /* Byte 58..ff: reserved */ + /* Byte 0x58..0xff: reserved */ /* * I2C Address (PCI Config) @@ -231,38 +367,38 @@ /* * Define Bits and Values of the registers */ -/* PCI_VENDOR_ID 16 bit Vendor ID */ -/* PCI_DEVICE_ID 16 bit Device ID */ -/* Values for Vendor ID and Device ID shall be patched into the code */ /* PCI_COMMAND 16 bit Command */ /* Bit 15..10: reserved */ -#define PCI_FBTEN (1<<9) /* Bit 9: Fast Back-To-Back enable */ -#define PCI_SERREN (1<<8) /* Bit 8: SERR enable */ -#define PCI_ADSTEP (1<<7) /* Bit 7: Address Stepping */ -#define PCI_PERREN (1<<6) /* Bit 6: Parity Report Response enable */ -#define PCI_VGA_SNOOP (1<<5) /* Bit 5: VGA palette snoop */ -#define PCI_MWIEN (1<<4) /* Bit 4: Memory write an inv cycl ena */ -#define PCI_SCYCEN (1<<3) /* Bit 3: Special Cycle enable */ -#define PCI_BMEN (1<<2) /* Bit 2: Bus Master enable */ -#define PCI_MEMEN (1<<1) /* Bit 1: Memory Space Access enable */ -#define PCI_IOEN (1<<0) /* Bit 0: IO Space Access enable */ +#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */ +#define PCI_SERREN BIT_8S /* SERR enable */ +#define PCI_ADSTEP BIT_7S /* Address Stepping */ +#define PCI_PERREN BIT_6S /* Parity Report Response enable */ +#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */ +#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */ +#define PCI_SCYCEN BIT_3S /* Special Cycle enable */ +#define PCI_BMEN BIT_2S /* Bus Master enable */ +#define PCI_MEMEN BIT_1S /* Memory Space Access enable */ +#define PCI_IOEN BIT_0S /* I/O Space Access enable */ + +#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\ + PCI_BMEN | PCI_MEMEN | PCI_IOEN) /* PCI_STATUS 16 bit Status */ -#define PCI_PERR (1<<15) /* Bit 15: Parity Error */ -#define PCI_SERR (1<<14) /* Bit 14: Signaled SERR */ -#define PCI_RMABORT (1<<13) /* Bit 13: Received Master Abort */ -#define PCI_RTABORT (1<<12) /* Bit 12: Received Target Abort */ +#define PCI_PERR BIT_15S /* Parity Error */ +#define PCI_SERR BIT_14S /* Signaled SERR */ +#define PCI_RMABORT BIT_13S /* Received Master Abort */ +#define PCI_RTABORT BIT_12S /* Received Target Abort */ /* Bit 11: reserved */ -#define PCI_DEVSEL (3<<9) /* Bit 10..9: DEVSEL Timing */ -#define PCI_DEV_FAST (0<<9) /* fast */ -#define PCI_DEV_MEDIUM (1<<9) /* medium */ -#define PCI_DEV_SLOW (2<<9) /* slow */ -#define PCI_DATAPERR (1<<8) /* Bit 8: DATA Parity error detected */ -#define PCI_FB2BCAP (1<<7) /* Bit 7: Fast Back-to-Back Capability */ -#define PCI_UDF (1<<6) /* Bit 6: User Defined Features */ -#define PCI_66MHZCAP (1<<5) /* Bit 5: 66 MHz PCI bus clock capable */ -#define PCI_NEWCAP (1<<4) /* Bit 4: New cap. list implemented */ - /* Bit 3..0: reserved */ +#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */ +#define PCI_DEV_FAST (0<<9) /* fast */ +#define PCI_DEV_MEDIUM (1<<9) /* medium */ +#define PCI_DEV_SLOW (2<<9) /* slow */ +#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */ +#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */ +#define PCI_UDF BIT_6S /* User Defined Features */ +#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */ +#define PCI_NEWCAP BIT_4S /* New cap. list implemented */ + /* Bit 3.. 0: reserved */ #define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\ PCI_DATAPERR) @@ -276,159 +412,167 @@ /* Possible values: 0,2,4,8,16,32,64,128 */ /* PCI_HEADER_T 8 bit Header Type */ -#define PCI_HD_MF_DEV (1<<7) /* Bit 7: 0= single, 1= multi-func dev */ -#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */ +#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */ +#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */ /* PCI_BIST 8 bit Built-in selftest */ /* Built-in Self test not supported (optional) */ /* PCI_BASE_1ST 32 bit 1st Base address */ -#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */ -#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */ -#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */ -#define PCI_PREFEN (1L<<3) /* Bit 3: Prefetchable */ -#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */ -#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */ -#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */ -#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */ -#define PCI_MEMSPACE (1L<<0) /* Bit 0: Memory Space Indic. */ +#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */ +#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */ +#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */ +#define PCI_PREFEN BIT_3 /* Prefetchable */ +#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */ +#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */ +#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */ +#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */ +#define PCI_MEMSPACE BIT_0 /* Memory Space Indic. */ /* PCI_BASE_2ND 32 bit 2nd Base address */ -#define PCI_IOBASE 0xffffff00L /* Bit 31..8: I/O Base address */ -#define PCI_IOSIZE 0x000000fcL /* Bit 7..2: I/O Size Requirements */ +#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */ +#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */ /* Bit 1: reserved */ -#define PCI_IOSPACE (1L<<0) /* Bit 0: I/O Space Indicator */ +#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */ /* PCI_BASE_ROM 32 bit Expansion ROM Base Address */ -#define PCI_ROMBASE (0xfffeL<<17) /* Bit 31..17: ROM BASE address (1st)*/ -#define PCI_ROMBASZ (0x1cL<<14) /* Bit 16..14: Treat as BASE or SIZE */ -#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */ +#define PCI_ROMBASE 0xfffe0000L /* Bit 31..17: ROM BASE address (1st)*/ +#define PCI_ROMBASZ (0x1cL<<14) /* Bit 16..14: Treat as BASE or SIZE */ +#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */ /* Bit 10.. 1: reserved */ -#define PCI_ROMEN (0x1L<<0) /* Bit 0: Address Decode enable */ +#define PCI_ROMEN BIT_0 /* Address Decode enable */ /* Device Dependent Region */ /* PCI_OUR_REG_1 32 bit Our Register 1 */ - /* Bit 31..26: reserved */ -#define PCI_VIO (1L<<25) /* Bit 25: PCI IO Voltage, */ - /* 0 = 3.3V / 1 = 5V */ -#define PCI_EN_BOOT (1L<<24) /* Bit 24: Enable BOOT via ROM */ - /* 1 = Don't boot wth ROM*/ - /* 0 = Boot with ROM */ -#define PCI_EN_IO (1L<<23) /* Bit 23: Mapping to IO space */ -#define PCI_EN_FPROM (1L<<22) /* Bit 22: FLASH mapped to mem? */ + /* Bit 31..29: reserved */ +#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode */ +#define PCI_EN_CAL BIT_27 /* Enable PCI buffer strength calibr. */ +#define PCI_DIS_CAL BIT_26 /* Disable PCI buffer strength calibr. */ +#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */ +#define PCI_EN_BOOT BIT_24 /* Enable BOOT via ROM */ +#define PCI_EN_IO BIT_23 /* Mapping to I/O space */ +#define PCI_EN_FPROM BIT_22 /* FLASH mapped to mem? */ /* 1 = Map Flash to Mem */ /* 0 = Disable addr. dec*/ -#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */ -#define PCI_PAGE_16 (0L<<20) /* 16 k pages */ -#define PCI_PAGE_32K (1L<<20) /* 32 k pages */ -#define PCI_PAGE_64K (2L<<20) /* 64 k pages */ -#define PCI_PAGE_128K (3L<<20) /* 128 k pages */ +#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */ +#define PCI_PAGE_16 (0L<<20) /* 16 k pages */ +#define PCI_PAGE_32K (1L<<20) /* 32 k pages */ +#define PCI_PAGE_64K (2L<<20) /* 64 k pages */ +#define PCI_PAGE_128K (3L<<20) /* 128 k pages */ /* Bit 19: reserved */ -#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */ -#define PCI_NOTAR (1L<<15) /* Bit 15: No turnaround cycle */ -#define PCI_FORCE_BE (1L<<14) /* Bit 14: Assert all BEs on MR */ -#define PCI_DIS_MRL (1L<<13) /* Bit 13: Disable Mem R Line */ -#define PCI_DIS_MRM (1L<<12) /* Bit 12: Disable Mem R multip */ -#define PCI_DIS_MWI (1L<<11) /* Bit 11: Disable Mem W & inv */ -#define PCI_DISC_CLS (1L<<10) /* Bit 10: Disc: cacheLsz bound */ -#define PCI_BURST_DIS (1L<<9) /* Bit 9: Burst Disable */ -#define PCI_DIS_PCI_CLK (1L<<8) /* Bit 8: Disable PCI clock driv*/ -#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7..4: Skew Ctrl, DAS Ext */ -#define PCI_SKEW_BASE (0xfL<<0) /* Bit 3..0: Skew Ctrl, Base */ +#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */ +#define PCI_NOTAR BIT_15 /* No turnaround cycle */ +#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */ +#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */ +#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */ +#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */ +#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */ +#define PCI_BURST_DIS BIT_9 /* Burst Disable */ +#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */ +#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */ +#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */ /* PCI_OUR_REG_2 32 bit Our Register 2 */ #define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */ -#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */ -#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */ +#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */ +#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */ /* Bit 13..12: reserved */ -#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patchs dir 3..0 */ -#define PCI_PATCH_DIR_0 (1L<<8) -#define PCI_PATCH_DIR_1 (1L<<9) -#define PCI_PATCH_DIR_2 (1L<<10) -#define PCI_PATCH_DIR_3 (1L<<11) -#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7..4: Extended Patches 3..0 */ -#define PCI_EXT_PATCH_0 (1L<<4) -#define PCI_EXT_PATCH_1 (1L<<5) -#define PCI_EXT_PATCH_2 (1L<<6) -#define PCI_EXT_PATCH_3 (1L<<7) -#define PCI_EN_DUMMY_RD (1L<<3) /* Bit 3: Enable Dummy Read */ -#define PCI_REV_DESC (1L<<2) /* Bit 2: Reverse Desc. Bytes */ +#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */ +#define PCI_PATCH_DIR_3 BIT_11 +#define PCI_PATCH_DIR_2 BIT_10 +#define PCI_PATCH_DIR_1 BIT_9 +#define PCI_PATCH_DIR_0 BIT_8 +#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */ +#define PCI_EXT_PATCH_3 BIT_7 +#define PCI_EXT_PATCH_2 BIT_6 +#define PCI_EXT_PATCH_1 BIT_5 +#define PCI_EXT_PATCH_0 BIT_4 +#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */ +#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */ /* Bit 1: reserved */ -#define PCI_USEDATA64 (1L<<0) /* Bit 0: Use 64Bit Data bus ext*/ +#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */ /* Power Management Region */ /* PCI_PM_CAP_REG 16 bit Power Management Capabilities */ -#define PCI_PME_SUP (0x1f<<11) /* Bit 15..11: PM Manag. Event Sup */ -#define PCI_PM_D2_SUB (1<<10) /* Bit 10: D2 Support Bit */ -#define PCI_PM_D1_SUB (1<<9) /* Bit 9: D1 Support Bit */ - /* Bit 8..6: reserved */ -#define PCI_PM_DSI (1<<5) /* Bit 5: Device Specific Init.*/ -#define PCI_PM_APS (1<<4) /* Bit 4: Auxialiary Power Src */ -#define PCI_PME_CLOCK (1<<3) /* Bit 3: PM Event Clock */ -#define PCI_PM_VER (7<<0) /* Bit 2..0: PM PCI Spec. version */ - -/* PCI_PM_CTL_STS 16 bit Power Manag. Control/Status */ -#define PCI_PME_STATUS (1<<15) /* Bit 15: PGA doesn't sup. PME# */ -#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: dat reg Scaling factor*/ -#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field*/ -#define PCI_PME_EN (1<<8) /* Bit 8: PGA doesn't sup. PME# */ +#define PCI_PME_SUP (0x1f<<11) /* Bit 15..11: PM Event Support */ +#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */ +#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */ +#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */ +#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */ +#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */ +#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */ +#define PCI_PM_D1_SUP BIT_9S /* D1 Support */ + /* Bit 8.. 6: reserved */ +#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */ +#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */ +#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */ +#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */ + +/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */ +#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */ +#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */ +#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */ +#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */ /* Bit 7.. 2: reserved */ -#define PCI_PM_STATE (3<<0) /* Bit 1.. 0: Power Management State*/ -#define PCI_PM_STATE_D0 (0<<0) /* D0: Operational (default) */ -#define PCI_PM_STATE_D1 (1<<0) /* D1: not supported */ -#define PCI_PM_STATE_D2 (2<<0) /* D2: not supported */ -#define PCI_PM_STATE_D3 (3<<0) /* D3: HOT, Power Down and Reset */ +#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */ + +#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */ +#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */ +#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */ +#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */ /* VPD Region */ /* PCI_VPD_ADR_REG 16 bit VPD Address Register */ -#define PCI_VPD_FLAG (1L<<15) /* Bit 15: starts VPD rd/wd cycle*/ +#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wd cycle*/ +#define PCI_VPD_ADDR 0x3fffL /* Bit 14.. 0: VPD address */ + +/* Control Register File (Address Map) */ /* - * Control Register File: * Bank 0 */ -#define B0_RAP 0x0000 /* 8 bit Register Address Port */ +#define B0_RAP 0x0000 /* 8 bit Register Address Port */ /* 0x0001 - 0x0003: reserved */ -#define B0_CTST 0x0004 /* 16 bit Control/Status register */ -#define B0_LED 0x0006 /* 8 Bit LED register */ - /* 0x0007: reserved */ -#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */ -#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */ +#define B0_CTST 0x0004 /* 16 bit Control/Status register */ +#define B0_LED 0x0006 /* 8 Bit LED register */ +#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */ +#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */ +#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */ #define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */ #define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */ #define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */ /* 0x001c: reserved */ -/* B0 XMAC 1 registers */ -#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/ - /* 0x0022 - 0x0027 reserved */ +/* B0 XMAC 1 registers (GENESIS only) */ +#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/ + /* 0x0022 - 0x0027: reserved */ #define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */ - /* 0x002a - 0x002f reserved */ + /* 0x002a - 0x002f: reserved */ #define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */ - /* 0x0032 - 0x0033 reserved */ + /* 0x0032 - 0x0033: reserved */ #define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */ - /* 0x0036 - 0x003f reserved */ + /* 0x0036 - 0x003f: reserved */ -/* B0 XMAC 2 registers */ -#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/ - /* 0x0042 - 0x0047 reserved */ +/* B0 XMAC 2 registers (GENESIS only) */ +#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/ + /* 0x0042 - 0x0047: reserved */ #define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */ - /* 0x004a - 0x004f reserved */ + /* 0x004a - 0x004f: reserved */ #define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */ - /* 0x0052 - 0x0053 reserved */ + /* 0x0052 - 0x0053: reserved */ #define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */ - /* 0x0056 - 0x005f reserved */ + /* 0x0056 - 0x005f: reserved */ /* BMU Control Status Registers */ -#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */ -#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */ -#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ -#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/ -#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ -#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/ - /* x0078 - 0x007f reserved */ +#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */ +#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */ +#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ +#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/ +#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ +#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/ + /* 0x0078 - 0x007f: reserved */ /* * Bank 1 @@ -440,20 +584,19 @@ * Bank 2 */ /* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */ - -#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */ - /* 0x0106 - 0x0107 reserved */ -#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */ - /* 0x010e - 0x010f reserved */ -#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */ - /* 0x0116 - 0x0117 reserved */ +#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */ + /* 0x0106 - 0x0107: reserved */ +#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */ + /* 0x010e - 0x010f: reserved */ +#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */ + /* 0x0116 - 0x0117: reserved */ #define B2_CONN_TYP 0x0118 /* 8 bit Connector type */ #define B2_PMD_TYP 0x0119 /* 8 bit PMD type */ -#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration */ -#define B2_CHIP_REV 0x011b /* 8 bit Queen Chip Revision Number */ +#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */ +#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */ /* Eprom registers are currently of no use */ -#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 */ -#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 */ +#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */ +#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */ #define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */ #define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */ #define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */ @@ -462,9 +605,9 @@ #define B2_LD_CRTL 0x0128 /* 8 bit EPROM loader control register */ #define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */ /* 0x012a - 0x012f: reserved */ -#define B2_TI_INI 0x0130 /* 32 bit Timer init value */ -#define B2_TI_VAL 0x0134 /* 32 bit Timer value */ -#define B2_TI_CRTL 0x0138 /* 8 bit Timer control */ +#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */ +#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */ +#define B2_TI_CRTL 0x0138 /* 8 bit Timer Control */ #define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */ /* 0x013a - 0x013f: reserved */ #define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/ @@ -474,14 +617,16 @@ #define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */ #define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */ /* 0x0154 - 0x0157: reserved */ -#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */ +#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */ #define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */ /* 0x015a - 0x015b: reserved */ -#define B2_GP_IO 0x015c /* 32 bit General Purpose IO Register */ +#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */ #define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */ #define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */ #define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */ #define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */ + +/* Blink Source Counter (GENESIS only) */ #define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */ #define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */ #define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */ @@ -492,66 +637,70 @@ /* * Bank 3 */ +/* RAM Random Registers */ #define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */ #define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */ #define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */ /* 0x018c - 0x018f: reserved */ + /* RAM Interface Registers */ /* - * The HW-Spec. call this registers Timeout Value 0..11. But this names are + * The HW-Spec. calls this registers Timeout Value 0..11. But this names are * not usable in SW. Please notice these are NOT real timeouts, these are - * the number of qWords transfered continously. + * the number of qWords transferred continuously. */ -#define B3_RI_WTO_R1 0x0190 /* 8 bit RAM Iface WR Timeout Queue R1 (TO0) */ -#define B3_RI_WTO_XA1 0x0191 /* 8 bit RAM Iface WR Timeout Queue XA1 (TO1) */ -#define B3_RI_WTO_XS1 0x0192 /* 8 bit RAM Iface WR Timeout Queue XS1 (TO2) */ -#define B3_RI_RTO_R1 0x0193 /* 8 bit RAM Iface RD Timeout Queue R1 (TO3) */ -#define B3_RI_RTO_XA1 0x0194 /* 8 bit RAM Iface RD Timeout Queue XA1 (TO4) */ -#define B3_RI_RTO_XS1 0x0195 /* 8 bit RAM Iface RD Timeout Queue XS1 (TO5) */ -#define B3_RI_WTO_R2 0x0196 /* 8 bit RAM Iface WR Timeout Queue R2 (TO6) */ -#define B3_RI_WTO_XA2 0x0197 /* 8 bit RAM Iface WR Timeout Queue XA2 (TO7) */ -#define B3_RI_WTO_XS2 0x0198 /* 8 bit RAM Iface WR Timeout Queue XS2 (TO8) */ -#define B3_RI_RTO_R2 0x0199 /* 8 bit RAM Iface RD Timeout Queue R2 (TO9) */ -#define B3_RI_RTO_XA2 0x019a /* 8 bit RAM Iface RD Timeout Queue XA2 (TO10)*/ -#define B3_RI_RTO_XS2 0x019b /* 8 bit RAM Iface RD Timeout Queue XS2 (TO11)*/ -#define B3_RI_TO_VAL 0x019c /* 8 bit RAM Iface Current Timeout Count Val */ - /* 0x019d - 0x019f reserved */ -#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Iface Control Register */ -#define B3_RI_TEST 0x01a2 /* 8 bit RAM Iface Test Register */ - /* 0x01a3 - 0x01af reserved */ -/* MAC Arbiter Registers */ -/* Please notice these are the number of qWord tranfered continously and */ -/* NOT real timeouts */ -#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Value Rx Path MAC 1 */ -#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Value Rx Path MAC 2 */ -#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Value Tx Path MAC 1 */ -#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Value Tx Path MAC 2 */ -#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */ -#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */ -#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */ -#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */ +#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */ +#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */ +#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */ +#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */ +#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */ +#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */ +#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */ +#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */ +#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */ +#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */ +#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/ +#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/ +#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */ + /* 0x019d - 0x019f: reserved */ +#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */ +#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */ + /* 0x01a3 - 0x01af: reserved */ + +/* MAC Arbiter Registers (GENESIS only) */ +/* these are the no. of qWord transferred continuously and NOT real timeouts */ +#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */ +#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */ +#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */ +#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */ +#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */ +#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */ +#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */ +#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */ #define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */ #define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */ - /* 0x01bc - 0x01bf reserved */ -#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Value Rx Path MAC 1 */ -#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Value Rx Path MAC 2 */ -#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Value Tx Path MAC 1 */ -#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Value Tx Path MAC 2 */ -#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */ -#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */ -#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */ -#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */ + /* 0x01bc - 0x01bf: reserved */ +#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */ +#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */ +#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */ +#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */ +#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */ +#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */ +#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */ +#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */ #define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */ #define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */ - /* 0x01cc - 0x01cf reserved */ -/* Packet Arbiter Registers, This are real timeouts */ -#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1*/ + /* 0x01cc - 0x01cf: reserved */ + +/* Packet Arbiter Registers (GENESIS only) */ +/* these are real timeouts */ +#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */ /* 0x01d2 - 0x01d3: reserved */ -#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2*/ +#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */ /* 0x01d6 - 0x01d7: reserved */ -#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1*/ +#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */ /* 0x01da - 0x01db: reserved */ -#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2*/ +#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */ /* 0x01de - 0x01df: reserved */ #define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */ /* 0x01e2 - 0x01e3: reserved */ @@ -568,8 +717,7 @@ /* * Bank 4 - 5 */ - -/* Transmit Arbiter Registers MAC 1 and 2, user MR_ADDR() to address */ +/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ #define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/ #define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */ #define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */ @@ -578,11 +726,13 @@ #define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */ #define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */ /* 0x0213 - 0x027f: reserved */ + /* 0x0280 - 0x0292: MAC 2 */ + /* 0x0213 - 0x027f: reserved */ /* * Bank 6 */ -/* External registers */ +/* External registers (GENESIS only) */ #define B6_EXT_REG 0x0300 /* @@ -595,7 +745,7 @@ * Bank 8 - 15 */ /* Receive and Transmit Queue Registers, use Q_ADDR() to access */ -#define B8_Q_REGS 0x0400 +#define B8_Q_REGS 0x0400 /* Queue Register Offsets, use Q_ADDR() to access */ #define Q_D 0x00 /* 8*32 bit Current Descriptor */ @@ -619,254 +769,371 @@ * Bank 16 - 23 */ /* RAM Buffer Registers */ -#define B16_RAM_REGS 0x0800 +#define B16_RAM_REGS 0x0800 -/* RAM Buffer Register Offsets */ -/* use RB_ADDR(Queue,Offs) to address */ -#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */ -#define RB_END 0x04 /* 32 bit RAM Buffer End Address */ -#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */ -#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */ -#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack*/ -#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack*/ -#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */ -#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */ - /* 0x10 - 0x1f: reserved for Tx RAM Buffer Registers */ -#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */ -#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */ -#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */ -#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */ -#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */ - /* 0x2c - 0x7f: reserved */ +/* RAM Buffer Register Offsets, use RB_ADDR() to access */ +#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */ +#define RB_END 0x04 /* 32 bit RAM Buffer End Address */ +#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */ +#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */ +#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */ +#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */ +#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */ +#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */ + /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */ +#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */ +#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */ +#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */ +#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */ +#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */ + /* 0x2c - 0x7f: reserved */ /* - * Bank 24 - 25 + * Bank 24 + */ +/* + * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only) + * use MR_ADDR() to access */ -/* Receive MAC FIFO, Receive LED, and Link Sync regs, use MR_ADDR() to address*/ #define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */ -#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer*/ - /* 0x0c08 - 0x0c0b reserved */ +#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */ + /* 0x0c08 - 0x0c0b: reserved */ #define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */ #define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */ #define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */ #define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/ #define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */ -#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Timestamp Timeout */ +#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */ #define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/ #define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */ #define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */ - /* 0x0c1f reserved */ + /* 0x0c1f: reserved */ #define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */ #define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */ #define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */ #define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */ - /* 0x0c2a - 0x0c2f reserved */ + /* 0x0c2a - 0x0c2f: reserved */ #define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */ #define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */ -#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register*/ +#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */ #define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */ - /* 0x0c3a - 0x0c3b reserved */ + /* 0x0c3a - 0x0c3b: reserved */ #define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */ - /* 0x0c3d - 0x0c7f reserved */ + /* 0x0c3d - 0x0c3f: reserved */ + +/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */ +#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */ +#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */ +#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */ +#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */ +#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */ + /* 0x0c54 - 0x0c5f: reserved */ +#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */ + /* 0x0c64 - 0x0c67: reserved */ +#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */ + /* 0x0c6c - 0x0c6f: reserved */ +#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */ + /* 0x0c74 - 0x0c77: reserved */ +#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */ + /* 0x0c7c - 0x0c7f: reserved */ + +/* + * Bank 25 + */ + /* 0x0c80 - 0x0cbf: MAC 2 */ + /* 0x0cc0 - 0x0cff: reserved */ /* - * Bank 26 - 27 + * Bank 26 + */ +/* + * Transmit MAC FIFO and Transmit LED Registers (GENESIS only), + * use MR_ADDR() to access */ -/* Transmit MAC FIFO and Transmit LED Registers, use MR_ADDR() to address */ #define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */ #define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */ -#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Pt*/ +#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */ #define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */ #define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */ #define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */ #define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */ -#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush*/ - /* 0x0c1b reserved */ +#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */ + /* 0x0c1b: reserved */ #define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */ #define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */ #define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */ - /* 0x0d1f reserved */ + /* 0x0d1f: reserved */ #define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */ #define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */ #define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */ -#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Register*/ - /* 0x0d2a - 0x0d7f reserved */ +#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */ + /* 0x0d2a - 0x0d3f: reserved */ + +/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */ +#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */ +#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/ +#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */ + /* 0x0d4c - 0x0d5f: reserved */ +#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */ +#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */ +#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */ + /* 0x0d6c - 0x0d6f: reserved */ +#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */ +#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */ +#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */ + /* 0x0d7c - 0x0d7f: reserved */ + +/* + * Bank 27 + */ + /* 0x0d80 - 0x0dbf: MAC 2 */ + /* 0x0daa - 0x0dff: reserved */ /* * Bank 28 */ /* Descriptor Poll Timer Registers */ -#define B28_DPT_INI 0x0e00 /* 32 bit Descriptor Poll Timer Init Val*/ -#define B28_DPT_VAL 0x0e04 /* 32 bit Descriptor Poll Timer Curr Val*/ -#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg*/ - /* 0x0e09: reserved */ -#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg*/ - /* 0x0e0b - 0x0e8f: reserved */ +#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */ +#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */ +#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */ + /* 0x0e09: reserved */ +#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */ + /* 0x0e0b: reserved */ + +/* Time Stamp Timer Registers (YUKON only) */ + /* 0x0e10: reserved */ +#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */ +#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */ + /* 0x0e19: reserved */ +#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */ + /* 0x0e1b - 0x0e7f: reserved */ + +/* + * Bank 29 + */ + /* 0x0e80 - 0x0efc: reserved */ + +/* + * Bank 30 + */ +/* GMAC and GPHY Control Registers (YUKON only) */ +#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */ +#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */ +#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */ + /* 0x0f09 - 0x0f0b: reserved */ +#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */ + /* 0x0f0d - 0x0f0f: reserved */ +#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */ + /* 0x0f14 - 0x0f1f: reserved */ + +/* Wake-up Frame Pattern Match Control Registers (YUKON only) */ + +#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */ + +#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */ +#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */ +#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */ +#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */ +#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */ +#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */ + +/* use this macro to access above registers */ +#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs)) + + +/* WOL Pattern Length Registers (YUKON only) */ + +#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */ +#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */ + +/* WOL Pattern Counter Registers (YUKON only) */ + +#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */ +#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */ + /* 0x0f40 - 0x0f7f: reserved */ + +/* + * Bank 31 + */ +/* 0x0f80 - 0x0fff: reserved */ /* - * Bank 29 - 31 + * Bank 32 - 33 */ -/* 0x0e90 - 0x0fff: reserved */ +#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */ /* - * Bank 0x20 - 0x3f + * Bank 0x22 - 0x3f */ -/* 0x1000 - 0x1fff: reserved */ +/* 0x1100 - 0x1fff: reserved */ /* * Bank 0x40 - 0x4f */ -/* XMAC 1 registers */ -#define B40_XMAC1 0x2000 +#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */ /* * Bank 0x50 - 0x5f */ -/* 0x2800 - 0x2fff: reserved */ + +#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */ /* * Bank 0x60 - 0x6f */ -/* XMAC 2 registers */ -#define B40_XMAC2 0x3000 +#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */ /* * Bank 0x70 - 0x7f */ -/* 0x3800 - 0x3fff: reserved */ +#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */ /* * Control Register Bit Definitions: */ /* B0_RAP 8 bit Register Address Port */ - /* Bit 7: reserved */ -#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0, .., 6f = block 6f*/ + /* Bit 7: reserved */ +#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ /* B0_CTST 16 bit Control/Status register */ - /* Bit 15..10: reserved */ -#define CS_BUS_CLOCK (1<<9) /* Bit 9: Bus Clock 0/1 = 33/66MHz */ -#define CS_BUS_SLOT_SZ (1<<8) /* Bit 8: Slot Size 0/1 = 32/64 bit slot*/ -#define CS_ST_SW_IRQ (1<<7) /* Bit 7: Set IRQ SW Request */ -#define CS_CL_SW_IRQ (1<<6) /* Bit 6: Clear IRQ SW Request */ -#define CS_STOP_DONE (1<<5) /* Bit 5: Stop Master is finished */ -#define CS_STOP_MAST (1<<4) /* Bit 4: Command Bit to stop the master*/ -#define CS_MRST_CLR (1<<3) /* Bit 3: Clear Master reset */ -#define CS_MRST_SET (1<<2) /* Bit 2: Set Master reset */ -#define CS_RST_CLR (1<<1) /* Bit 1: Clear Software reset */ -#define CS_RST_SET (1<<0) /* Bit 0: Set Software reset */ + /* Bit 15..11: reserved */ +#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */ +#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */ +#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */ +#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */ +#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */ +#define CS_STOP_DONE BIT_5S /* Stop Master is finished */ +#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */ +#define CS_MRST_CLR BIT_3S /* Clear Master reset */ +#define CS_MRST_SET BIT_2S /* Set Master reset */ +#define CS_RST_CLR BIT_1S /* Clear Software reset */ +#define CS_RST_SET BIT_0S /* Set Software reset */ /* B0_LED 8 Bit LED register */ - /* Bit 7..2: reserved */ -#define LED_STAT_ON (1<<1) /* Bit 1: Status LED on */ -#define LED_STAT_OFF (1<<0) /* Bit 0: Status LED off */ + /* Bit 7.. 2: reserved */ +#define LED_STAT_ON BIT_1S /* Status LED on */ +#define LED_STAT_OFF BIT_0S /* Status LED off */ + +/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */ +#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */ +#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */ +#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */ +#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */ +#define PC_VAUX_ON BIT_3 /* Switch VAUX On */ +#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */ +#define PC_VCC_ON BIT_1 /* Switch VCC On */ +#define PC_VCC_OFF BIT_0 /* Switch VCC Off */ /* B0_ISRC 32 bit Interrupt Source Register */ /* B0_IMSK 32 bit Interrupt Mask Register */ /* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ /* B2_IRQM_MSK 32 bit IRQ Moderation Mask */ #define IS_ALL_MSK 0xbfffffffL /* All Interrupt bits */ -#define IS_HW_ERR (1UL<<31) /* Bit 31: Interrupt HW Error */ - /* Bit 30: reserved */ -#define IS_PA_TO_RX1 (1L<<29) /* Bit 29: Packet Arb Timeout Rx1*/ -#define IS_PA_TO_RX2 (1L<<28) /* Bit 28: Packet Arb Timeout Rx2*/ -#define IS_PA_TO_TX1 (1L<<27) /* Bit 27: Packet Arb Timeout Tx1*/ -#define IS_PA_TO_TX2 (1L<<26) /* Bit 26: Packet Arb Timeout Tx2*/ -#define IS_I2C_READY (1L<<25) /* Bit 25: IRQ on end of I2C tx */ -#define IS_IRQ_SW (1L<<24) /* Bit 24: SW forced IRQ */ -#define IS_EXT_REG (1L<<23) /* Bit 23: IRQ from external reg */ -#define IS_TIMINT (1L<<22) /* Bit 22: IRQ from Timer */ -#define IS_MAC1 (1L<<21) /* Bit 21: IRQ from MAC 1 */ -#define IS_LNK_SYNC_M1 (1L<<20) /* Bit 20: Link Sync Cnt wrap M1 */ -#define IS_MAC2 (1L<<19) /* Bit 19: IRQ from MAC 2 */ -#define IS_LNK_SYNC_M2 (1L<<18) /* Bit 18: Link Sync Cnt wrap M2 */ +#define IS_HW_ERR BIT_31 /* Interrupt HW Error */ + /* Bit 30: reserved */ +#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */ +#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */ +#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */ +#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */ +#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */ +#define IS_IRQ_SW BIT_24 /* SW forced IRQ */ +#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */ + /* IRQ from PHY (YUKON only) */ +#define IS_TIMINT BIT_22 /* IRQ from Timer */ +#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */ +#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */ +#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */ +#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */ /* Receive Queue 1 */ -#define IS_R1_B (1L<<17) /* Bit 17: Q_R1 End of Buffer */ -#define IS_R1_F (1L<<16) /* Bit 16: Q_R1 End of Frame */ -#define IS_R1_C (1L<<15) /* Bit 15: Q_R1 Encoding Error */ +#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */ +#define IS_R1_F BIT_16 /* Q_R1 End of Frame */ +#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */ /* Receive Queue 2 */ -#define IS_R2_B (1L<<14) /* Bit 14: Q_R2 End of Buffer */ -#define IS_R2_F (1L<<13) /* Bit 13: Q_R2 End of Frame */ -#define IS_R2_C (1L<<12) /* Bit 12: Q_R2 Encoding Error */ +#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */ +#define IS_R2_F BIT_13 /* Q_R2 End of Frame */ +#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */ /* Synchronous Transmit Queue 1 */ -#define IS_XS1_B (1L<<11) /* Bit 11: Q_XS1 End of Buffer */ -#define IS_XS1_F (1L<<10) /* Bit 10: Q_XS1 End of Frame */ -#define IS_XS1_C (1L<<9) /* Bit 9: Q_XS1 Encoding Error */ +#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */ +#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */ +#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */ /* Asynchronous Transmit Queue 1 */ -#define IS_XA1_B (1L<<8) /* Bit 8: Q_XA1 End of Buffer */ -#define IS_XA1_F (1L<<7) /* Bit 7: Q_XA1 End of Frame */ -#define IS_XA1_C (1L<<6) /* Bit 6: Q_XA1 Encoding Error */ +#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */ +#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */ +#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */ /* Synchronous Transmit Queue 2 */ -#define IS_XS2_B (1L<<5) /* Bit 5: Q_XS2 End of Buffer */ -#define IS_XS2_F (1L<<4) /* Bit 4: Q_XS2 End of Frame */ -#define IS_XS2_C (1L<<3) /* Bit 3: Q_XS2 Encoding Error */ +#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */ +#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */ +#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */ /* Asynchronous Transmit Queue 2 */ -#define IS_XA2_B (1L<<2) /* Bit 2: Q_XA2 End of Buffer */ -#define IS_XA2_F (1L<<1) /* Bit 1: Q_XA2 End of Frame */ -#define IS_XA2_C (1L<<0) /* Bit 0: Q_XA2 Encoding Error */ +#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */ +#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */ +#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */ /* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ /* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ #define IS_ERR_MSK 0x00000fffL /* All Error bits */ - /* Bit 31..12: reserved */ -#define IS_IRQ_MST_ERR (1L<<11) /* Bit 11: IRQ master error */ - /* PERR,RMABORT,RTABORT,DATAPERR */ -#define IS_IRQ_STAT (1L<<10) /* Bit 10: IRQ status execption */ - /* RMABORT, RTABORT, DATAPERR */ -#define IS_NO_STAT_M1 (1L<<9) /* Bit 9: No Rx Status from MAC1*/ -#define IS_NO_STAT_M2 (1L<<8) /* Bit 8: No Rx Status from MAC2*/ -#define IS_NO_TIST_M1 (1L<<7) /* Bit 7: No Timestamp from MAC1*/ -#define IS_NO_TIST_M2 (1L<<6) /* Bit 6: No Timestamp from MAC2*/ -#define IS_RAM_RD_PAR (1L<<5) /* Bit 5: RAM Read Parity Error */ -#define IS_RAM_WR_PAR (1L<<4) /* Bit 4: RAM Write Parity Error*/ -#define IS_M1_PAR_ERR (1L<<3) /* Bit 3: MAC 1 Parity Error */ -#define IS_M2_PAR_ERR (1L<<2) /* Bit 2: MAC 2 Parity Error */ -#define IS_R1_PAR_ERR (1L<<1) /* Bit 1: Queue R1 Parity Error */ -#define IS_R2_PAR_ERR (1L<<0) /* Bit 0: Queue R2 Parity Error */ + /* Bit 31..14: reserved */ +#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */ +#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */ +#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */ +#define IS_IRQ_STAT BIT_10 /* IRQ status exception */ +#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */ +#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */ +#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */ +#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */ +#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */ +#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */ +#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */ +#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */ +#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */ +#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */ /* B2_CONN_TYP 8 bit Connector type */ /* B2_PMD_TYP 8 bit PMD type */ /* Values of connector and PMD type comply to SysKonnect internal std */ -/* B2_MAC_CFG 8 bit MAC Configuration */ - /* Bit 7..2: reserved */ -#define CFG_DIS_M2_CLK (1<<1) /* Bit 1: Disable Clock for 2nd MAC */ -#define CFG_SNG_MAC (1<<0) /* Bit 0: MAC Config: 1=2 MACs / 0=1 MAC*/ - -/* B2_CHIP_REV 8 bit Queen Chip Revision Number */ -#define FIRST_CHIP_REV 0x0a /* Initial Revision Value */ +/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ +#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */ + /* Bit 3.. 2: reserved */ +#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */ +#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/ + +/* B2_CHIP_ID 8 bit Chip Identification Number */ +#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ +#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ /* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ -#define FAR_ADDR 0x1ffffL /* Bit 16..0: FPROM Address mask */ +#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */ /* B2_LD_CRTL 8 bit EPROM loader control register */ /* Bits are currently reserved */ /* B2_LD_TEST 8 bit EPROM loader test register */ - /* Bit 7..4: reserved */ -#define LD_T_ON (1<<3) /* Bit 3: Loader Testmode on */ -#define LD_T_OFF (1<<2) /* Bit 2: Loader Testmode off */ -#define LD_T_STEP (1<<1) /* Bit 1: Decrement FPROM addr. Counter */ -#define LD_START (1<<0) /* Bit 0: Start loading FPROM */ + /* Bit 7.. 4: reserved */ +#define LD_T_ON BIT_3S /* Loader Test mode on */ +#define LD_T_OFF BIT_2S /* Loader Test mode off */ +#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */ +#define LD_START BIT_0S /* Start loading FPROM */ /* * Timer Section */ /* B2_TI_CRTL 8 bit Timer control */ /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ - /* Bit 7..3: reserved */ -#define TIM_START (1<<2) /* Bit 2: Start Timer */ -#define TIM_STOP (1<<1) /* Bit 1: Stop Timer */ -#define TIM_CLR_IRQ (1<<0) /* Bit 0: Clear Timer IRQ, (!IRQM) */ + /* Bit 7.. 3: reserved */ +#define TIM_START BIT_2S /* Start Timer */ +#define TIM_STOP BIT_1S /* Stop Timer */ +#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */ /* B2_TI_TEST 8 Bit Timer Test */ /* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */ /* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */ - /* Bit 7..3: reserved */ -#define TIM_T_ON (1<<2) /* Bit 2: Test mode on */ -#define TIM_T_OFF (1<<1) /* Bit 1: Test mode off */ -#define TIM_T_STEP (1<<0) /* Bit 0: Test step */ + /* Bit 7.. 3: reserved */ +#define TIM_T_ON BIT_2S /* Test mode on */ +#define TIM_T_OFF BIT_1S /* Test mode off */ +#define TIM_T_STEP BIT_0S /* Test step */ /* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */ /* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */ @@ -874,100 +1141,101 @@ #define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */ /* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */ - /* Bit 7..2: reserved */ -#define DPT_START (1<<1) /* Bit 1: Start Desciptor Poll Timer */ -#define DPT_STOP (1<<0) /* Bit 0: Stop Desciptor Poll Timer */ + /* Bit 7.. 2: reserved */ +#define DPT_START BIT_1S /* Start Descriptor Poll Timer */ +#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */ +/* B2_E_3 8 bit lower 4 bits used for HW self test result */ +#define B2_E3_RES_MASK 0x0f /* B2_TST_CTRL1 8 bit Test Control Register 1 */ -#define TST_FRC_DPERR_MR (1<<7) /* Bit 7: force DATAPERR on MST RD */ -#define TST_FRC_DPERR_MW (1<<6) /* Bit 6: force DATAPERR on MST WR */ -#define TST_FRC_DPERR_TR (1<<5) /* Bit 5: force DATAPERR on TRG RD */ -#define TST_FRC_DPERR_TW (1<<4) /* Bit 4: force DATAPERR on TRG WR */ -#define TST_FRC_APERR_M (1<<3) /* Bit 3: force ADDRPERR on MST */ -#define TST_FRC_APERR_T (1<<2) /* Bit 2: force ADDRPERR on TRG */ -#define TST_CFG_WRITE_ON (1<<1) /* Bit 1: Enable Config Reg WR */ -#define TST_CFG_WRITE_OFF (1<<0) /* Bit 0: Disable Config Reg WR */ +#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */ +#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */ +#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */ +#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */ +#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */ +#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */ +#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */ +#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */ /* B2_TST_CTRL2 8 bit Test Control Register 2 */ - /* Bit 7..4: reserved */ - /* force the following error on */ - /* the next master read/write */ -#define TST_FRC_DPERR_MR64 (1<<3) /* Bit 3: DataPERR RD 64 */ -#define TST_FRC_DPERR_MW64 (1<<2) /* Bit 2: DataPERR WR 64 */ -#define TST_FRC_APERR_1M64 (1<<1) /* Bit 1: AddrPERR on 1. phase */ -#define TST_FRC_APERR_2M64 (1<<0) /* Bit 0: AddrPERR on 2. phase */ - -/* B2_GP_IO 32 bit General Purpose IO Register */ - /* Bit 31..26: reserved */ -#define GP_DIR_9 (1L<<25) /* Bit 25: IO_9 direct, 0=I/1=O */ -#define GP_DIR_8 (1L<<24) /* Bit 24: IO_8 direct, 0=I/1=O */ -#define GP_DIR_7 (1L<<23) /* Bit 23: IO_7 direct, 0=I/1=O */ -#define GP_DIR_6 (1L<<22) /* Bit 22: IO_6 direct, 0=I/1=O */ -#define GP_DIR_5 (1L<<21) /* Bit 21: IO_5 direct, 0=I/1=O */ -#define GP_DIR_4 (1L<<20) /* Bit 20: IO_4 direct, 0=I/1=O */ -#define GP_DIR_3 (1L<<19) /* Bit 19: IO_3 direct, 0=I/1=O */ -#define GP_DIR_2 (1L<<18) /* Bit 18: IO_2 direct, 0=I/1=O */ -#define GP_DIR_1 (1L<<17) /* Bit 17: IO_1 direct, 0=I/1=O */ -#define GP_DIR_0 (1L<<16) /* Bit 16: IO_0 direct, 0=I/1=O */ - /* Bit 15..10: reserved */ -#define GP_IO_9 (1L<<9) /* Bit 9: IO_9 pin */ -#define GP_IO_8 (1L<<8) /* Bit 8: IO_8 pin */ -#define GP_IO_7 (1L<<7) /* Bit 7: IO_7 pin */ -#define GP_IO_6 (1L<<6) /* Bit 6: IO_6 pin */ -#define GP_IO_5 (1L<<5) /* Bit 5: IO_5 pin */ -#define GP_IO_4 (1L<<4) /* Bit 4: IO_4 pin */ -#define GP_IO_3 (1L<<3) /* Bit 3: IO_3 pin */ -#define GP_IO_2 (1L<<2) /* Bit 2: IO_2 pin */ -#define GP_IO_1 (1L<<1) /* Bit 1: IO_1 pin */ -#define GP_IO_0 (1L<<0) /* Bit 0: IO_0 pin */ + /* Bit 7.. 4: reserved */ + /* force the following error on the next master read/write */ +#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */ +#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */ +#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */ +#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */ + +/* B2_GP_IO 32 bit General Purpose I/O Register */ + /* Bit 31..26: reserved */ +#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=I/1=O */ +#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=I/1=O */ +#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=I/1=O */ +#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=I/1=O */ +#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=I/1=O */ +#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=I/1=O */ +#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=I/1=O */ +#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=I/1=O */ +#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=I/1=O */ +#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=I/1=O */ + /* Bit 15..10: reserved */ +#define GP_IO_9 BIT_9 /* IO_9 pin */ +#define GP_IO_8 BIT_8 /* IO_8 pin */ +#define GP_IO_7 BIT_7 /* IO_7 pin */ +#define GP_IO_6 BIT_6 /* IO_6 pin */ +#define GP_IO_5 BIT_5 /* IO_5 pin */ +#define GP_IO_4 BIT_4 /* IO_4 pin */ +#define GP_IO_3 BIT_3 /* IO_3 pin */ +#define GP_IO_2 BIT_2 /* IO_2 pin */ +#define GP_IO_1 BIT_1 /* IO_1 pin */ +#define GP_IO_0 BIT_0 /* IO_0 pin */ /* B2_I2C_CTRL 32 bit I2C HW Control Register */ -#define I2C_FLAG (1UL<<31) /* Bit 31: Start read/write if WR*/ -#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */ -#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */ - /* Bit 8.. 5: reserved */ -#define I2C_BURST_LEN (1L<<4) /* Bit 4: Burst Len, 1/4 bytes */ +#define I2C_FLAG BIT_31 /* Start read/write if WR */ +#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */ +#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */ + /* Bit 8.. 5: reserved */ +#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */ #define I2C_DEV_SIZE (7L<<1) /* Bit 3.. 1: I2C Device Size */ #define I2C_025K_DEV (0L<<1) /* 0: 256 Bytes or smal. */ #define I2C_05K_DEV (1L<<1) /* 1: 512 Bytes */ -#define I2C_1K_DEV (2L<<1) /* 2: 1024 Bytes */ +#define I2C_1K_DEV (2L<<1) /* 2: 1024 Bytes */ #define I2C_2K_DEV (3L<<1) /* 3: 2048 Bytes */ -#define I2C_4K_DEV (4L<<1) /* 4: 4096 Bytes */ -#define I2C_8K_DEV (5L<<1) /* 5: 8192 Bytes */ -#define I2C_16K_DEV (6L<<1) /* 6: 16384 Bytes */ -#define I2C_32K_DEV (7L<<1) /* 7: 32768 Bytes */ -#define I2C_STOP (1L<<0) /* Bit 0: Interrupt I2C transfer*/ +#define I2C_4K_DEV (4L<<1) /* 4: 4096 Bytes */ +#define I2C_8K_DEV (5L<<1) /* 5: 8192 Bytes */ +#define I2C_16K_DEV (6L<<1) /* 6: 16384 Bytes */ +#define I2C_32K_DEV (7L<<1) /* 7: 32768 Bytes */ +#define I2C_STOP BIT_0 /* Interrupt I2C transfer */ /* B2_I2C_IRQ 32 bit I2C HW IRQ Register */ - /* Bit 31..1 reserved */ -#define I2C_CLR_IRQ (1<<0) /* Bit 0: Clear I2C IRQ */ + /* Bit 31.. 1 reserved */ +#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */ -/* B2_I2C_SW 32 bit I2C HW SW Port Register */ - /* Bit 7..3: reserved */ -#define I2C_DATA_DIR (1<<2) /* Bit 2: direction of I2C_DATA */ -#define I2C_DATA (1<<1) /* Bit 1: I2C Data Port */ -#define I2C_CLK (1<<0) /* Bit 0: I2C Clock Port */ +/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ + /* Bit 7.. 3: reserved */ +#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */ +#define I2C_DATA BIT_1S /* I2C Data Port */ +#define I2C_CLK BIT_0S /* I2C Clock Port */ /* * I2C Address */ -#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/ +#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/ /* B2_BSC_CTRL 8 bit Blink Source Counter Control */ - /* Bit 7..2: reserved */ -#define BSC_START (1<<1) /* Bit 1: Start Blink Source Counter */ -#define BSC_STOP (1<<0) /* Bit 0: Stop Blink Source Counter */ + /* Bit 7.. 2: reserved */ +#define BSC_START BIT_1S /* Start Blink Source Counter */ +#define BSC_STOP BIT_0S /* Stop Blink Source Counter */ /* B2_BSC_STAT 8 bit Blink Source Counter Status */ - /* Bit 7..1: reserved */ -#define BSC_SRC (1<<0) /* Bit 0: Blink Source, 0=Off / 1=On */ + /* Bit 7.. 1: reserved */ +#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */ /* B2_BSC_TST 16 bit Blink Source Counter Test Reg */ -#define BSC_T_ON (1<<2) /* Bit 2: Test mode on */ -#define BSC_T_OFF (1<<1) /* Bit 1: Test mode off */ -#define BSC_T_STEP (1<<0) /* Bit 0: Test step */ +#define BSC_T_ON BIT_2S /* Test mode on */ +#define BSC_T_OFF BIT_1S /* Test mode off */ +#define BSC_T_STEP BIT_0S /* Test step */ /* B3_RAM_ADDR 32 bit RAM Address, to read or write */ @@ -977,55 +1245,55 @@ /* RAM Interface Registers */ /* B3_RI_CTRL 16 bit RAM Iface Control Register */ /* Bit 15..10: reserved */ -#define RI_CLR_RD_PERR (1<<9) /* Bit 9: Clear IRQ RAM Read Parity Err */ -#define RI_CLR_WR_PERR (1<<8) /* Bit 8: Clear IRQ RAM Write Parity Err*/ - /* Bit 7..2: reserved */ -#define RI_RST_CLR (1<<1) /* Bit 1: Clear RAM Interface Reset */ -#define RI_RST_SET (1<<0) /* Bit 0: Set RAM Interface Reset */ +#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */ +#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/ + /* Bit 7.. 2: reserved */ +#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */ +#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */ /* B3_RI_TEST 8 bit RAM Iface Test Register */ - /* Bit 15..4: reserved */ -#define RI_T_EV (1<<3) /* Bit 3: Timeout Event occured */ -#define RI_T_ON (1<<2) /* Bit 2: Timeout Timer Test On */ -#define RI_T_OFF (1<<1) /* Bit 1: Timeout Timer Test Off */ -#define RI_T_STEP (1<<0) /* Bit 0: Timeout Timer Step */ + /* Bit 15.. 4: reserved */ +#define RI_T_EV BIT_3S /* Timeout Event occured */ +#define RI_T_ON BIT_2S /* Timeout Timer Test On */ +#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */ +#define RI_T_STEP BIT_0S /* Timeout Timer Step */ /* MAC Arbiter Registers */ /* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */ - /* Bit 15..4: reserved */ -#define MA_FOE_ON (1<<3) /* Bit 3: XMAC Fast Output Enable ON */ -#define MA_FOE_OFF (1<<2) /* Bit 2: XMAC Fast Output Enable OFF */ -#define MA_RST_CLR (1<<1) /* Bit 1: Clear MAC Arbiter Reset */ -#define MA_RST_SET (1<<0) /* Bit 0: Set MAC Arbiter Reset */ + /* Bit 15.. 4: reserved */ +#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */ +#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */ +#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */ +#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */ /* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */ - /* Bit 15..8: reserved */ -#define MA_ENA_REC_TX2 (1<<7) /* Bit 7: Enable Recovery Timer TX2 */ -#define MA_DIS_REC_TX2 (1<<6) /* Bit 6: Disable Recovery Timer TX2 */ -#define MA_ENA_REC_TX1 (1<<5) /* Bit 5: Enable Recovery Timer TX1 */ -#define MA_DIS_REC_TX1 (1<<4) /* Bit 4: Disable Recovery Timer TX1 */ -#define MA_ENA_REC_RX2 (1<<3) /* Bit 3: Enable Recovery Timer RX2 */ -#define MA_DIS_REC_RX2 (1<<2) /* Bit 2: Disable Recovery Timer RX2 */ -#define MA_ENA_REC_RX1 (1<<1) /* Bit 1: Enable Recovery Timer RX1 */ -#define MA_DIS_REC_RX1 (1<<0) /* Bit 0: Disable Recovery Timer RX1 */ + /* Bit 15.. 8: reserved */ +#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */ +#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */ +#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */ +#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */ +#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */ +#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */ +#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */ +#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */ /* Packet Arbiter Registers */ /* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ /* Bit 15..14: reserved */ -#define PA_CLR_TO_TX2 (1<<13) /* Bit 13: Clear IRQ Packet Timeout TX2 */ -#define PA_CLR_TO_TX1 (1<<12) /* Bit 12: Clear IRQ Packet Timeout TX1 */ -#define PA_CLR_TO_RX2 (1<<11) /* Bit 11: Clear IRQ Packet Timeout RX2 */ -#define PA_CLR_TO_RX1 (1<<10) /* Bit 10: Clear IRQ Packet Timeout RX1 */ -#define PA_ENA_TO_TX2 (1<<9) /* Bit 9: Enable Timeout Timer TX2 */ -#define PA_DIS_TO_TX2 (1<<8) /* Bit 8: Disable Timeout Timer TX2 */ -#define PA_ENA_TO_TX1 (1<<7) /* Bit 7: Enable Timeout Timer TX1 */ -#define PA_DIS_TO_TX1 (1<<6) /* Bit 6: Disable Timeout Timer TX1 */ -#define PA_ENA_TO_RX2 (1<<5) /* Bit 5: Enable Timeout Timer RX2 */ -#define PA_DIS_TO_RX2 (1<<4) /* Bit 4: Disable Timeout Timer RX2 */ -#define PA_ENA_TO_RX1 (1<<3) /* Bit 3: Enable Timeout Timer RX1 */ -#define PA_DIS_TO_RX1 (1<<2) /* Bit 2: Disable Timeout Timer RX1 */ -#define PA_RST_CLR (1<<1) /* Bit 1: Clear MAC Arbiter Reset */ -#define PA_RST_SET (1<<0) /* Bit 0: Set MAC Arbiter Reset */ +#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */ +#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */ +#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */ +#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */ +#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */ +#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */ +#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */ +#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */ +#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */ +#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */ +#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */ +#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */ +#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */ +#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */ #define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\ PA_ENA_TO_TX1 | PA_ENA_TO_TX2) @@ -1035,57 +1303,57 @@ /* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ /* B3_PA_TEST 16 bit Packet Arbiter Test Register */ /* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ -#define TX2_T_EV (1<<15) /* Bit 15: TX2 Timeout/Recv Event occured*/ -#define TX2_T_ON (1<<14) /* Bit 14: TX2 Timeout/Recv Timer Test On*/ -#define TX2_T_OFF (1<<13) /* Bit 13: TX2 Timeout/Recv Timer Tst Off*/ -#define TX2_T_STEP (1<<12) /* Bit 12: TX2 Timeout/Recv Timer Step */ -#define TX1_T_EV (1<<11) /* Bit 11: TX1 Timeout/Recv Event occured*/ -#define TX1_T_ON (1<<10) /* Bit 10: TX1 Timeout/Recv Timer Test On*/ -#define TX1_T_OFF (1<<9) /* Bit 9: TX1 Timeout/Recv Timer Tst Off*/ -#define TX1_T_STEP (1<<8) /* Bit 8: TX1 Timeout/Recv Timer Step */ -#define RX2_T_EV (1<<7) /* Bit 7: RX2 Timeout/Recv Event occured*/ -#define RX2_T_ON (1<<6) /* Bit 6: RX2 Timeout/Recv Timer Test On*/ -#define RX2_T_OFF (1<<5) /* Bit 5: RX2 Timeout/Recv Timer Tst Off*/ -#define RX2_T_STEP (1<<4) /* Bit 4: RX2 Timeout/Recv Timer Step */ -#define RX1_T_EV (1<<3) /* Bit 3: RX1 Timeout/Recv Event occured*/ -#define RX1_T_ON (1<<2) /* Bit 2: RX1 Timeout/Recv Timer Test On*/ -#define RX1_T_OFF (1<<1) /* Bit 1: RX1 Timeout/Recv Timer Tst Off*/ -#define RX1_T_STEP (1<<0) /* Bit 0: RX1 Timeout/Recv Timer Step */ +#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */ +#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */ +#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */ +#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */ +#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */ +#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */ +#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */ +#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */ +#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */ +#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */ +#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */ +#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */ +#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */ +#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */ +#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */ +#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */ -/* Transmit Arbiter Registers MAC 1 and 2, user MR_ADDR() to address */ +/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ /* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ /* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ /* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ /* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */ /* Bit 31..24: reserved */ -#define TXA_MAX_VAL 0x00ffffffL /* Bit 23.. 0: Max TXA Timer/Cnt Val */ +#define TXA_MAX_VAL 0x00ffffffL /* Bit 23.. 0: Max TXA Timer/Cnt Val */ /* TXA_CTRL 8 bit Tx Arbiter Control Register */ -#define TXA_ENA_FSYNC (1<<7) /* Bit 7: Enable force of sync tx queue */ -#define TXA_DIS_FSYNC (1<<6) /* Bit 6: Disable force of sync tx queue*/ -#define TXA_ENA_ALLOC (1<<5) /* Bit 5: Enable alloc of free bandwidth*/ -#define TXA_DIS_ALLOC (1<<4) /* Bit 4: Disabl alloc of free bandwidth*/ -#define TXA_START_RC (1<<3) /* Bit 3: Start sync Rate Control */ -#define TXA_STOP_RC (1<<2) /* Bit 2: Stop sync Rate Control */ -#define TXA_ENA_ARB (1<<1) /* Bit 1: Enable Tx Arbiter */ -#define TXA_DIS_ARB (1<<0) /* Bit 0: Disable Tx Arbiter */ +#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */ +#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */ +#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */ +#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */ +#define TXA_START_RC BIT_3S /* Start sync Rate Control */ +#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */ +#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */ +#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */ /* TXA_TEST 8 bit Tx Arbiter Test Register */ - /* Bit 7..6: reserved */ -#define TXA_INT_T_ON (1<<5) /* Bit 5: Tx Arb Interval Timer Test On */ -#define TXA_INT_T_OFF (1<<4) /* Bit 4: Tx Arb Interval Timer Test Off*/ -#define TXA_INT_T_STEP (1<<3) /* Bit 3: Tx Arb Interval Timer Step */ -#define TXA_LIM_T_ON (1<<2) /* Bit 2: Tx Arb Limit Timer Test On */ -#define TXA_LIM_T_OFF (1<<1) /* Bit 1: Tx Arb Limit Timer Test Off */ -#define TXA_LIM_T_STEP (1<<0) /* Bit 0: Tx Arb Limit Timer Step */ + /* Bit 7.. 6: reserved */ +#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */ +#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */ +#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */ +#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */ +#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */ +#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */ /* TXA_STAT 8 bit Tx Arbiter Status Register */ - /* Bit 7..1: reserved */ -#define TXA_PRIO_XS (1<<0) /* Bit 0: sync queue has prio to send */ + /* Bit 7.. 1: reserved */ +#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */ /* Q_BC 32 bit Current Byte Counter */ - /* Bit 31..16: reserved */ + /* Bit 31..16: reserved */ #define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */ /* BMU Control Status Registers */ @@ -1095,94 +1363,95 @@ /* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */ /* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ /* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */ -/* Q_CSR 32 bit BMU Control/Status Register */ - /* Bit 31..25: reserved */ -#define CSR_SV_IDLE (1L<<24) /* Bit 24: BMU SM Idle */ - /* Bit 23..22: reserved */ -#define CSR_DESC_CLR (1L<<21) /* Bit 21: Clear Reset for Descr */ -#define CSR_DESC_SET (1L<<20) /* Bit 20: Set Reset for Descr */ -#define CSR_FIFO_CLR (1L<<19) /* Bit 19: Clear Reset for FIFO */ -#define CSR_FIFO_SET (1L<<18) /* Bit 18: Set Reset for FIFO */ -#define CSR_HPI_RUN (1L<<17) /* Bit 17: Release HPI SM */ -#define CSR_HPI_RST (1L<<16) /* Bit 16: Reset HPI SM to Idle */ -#define CSR_SV_RUN (1L<<15) /* Bit 15: Release Supervisor SM */ -#define CSR_SV_RST (1L<<14) /* Bit 14: Reset Supervisor SM */ -#define CSR_DREAD_RUN (1L<<13) /* Bit 13: Release Descr Read SM */ -#define CSR_DREAD_RST (1L<<12) /* Bit 12: Reset Descr Read SM */ -#define CSR_DWRITE_RUN (1L<<11) /* Bit 11: Rel. Descr Write SM */ -#define CSR_DWRITE_RST (1L<<10) /* Bit 10: Reset Descr Write SM */ -#define CSR_TRANS_RUN (1L<<9) /* Bit 9: Release Transfer SM */ -#define CSR_TRANS_RST (1L<<8) /* Bit 8: Reset Transfer SM */ -#define CSR_ENA_POL (1L<<7) /* Bit 7: Enable Descr Polling */ -#define CSR_DIS_POL (1L<<6) /* Bit 6: Disable Descr Polling */ -#define CSR_STOP (1L<<5) /* Bit 5: Stop Rx/Tx Queue */ -#define CSR_START (1L<<4) /* Bit 4: Start Rx/Tx Queue */ -#define CSR_IRQ_CL_P (1L<<3) /* Bit 3: (Rx) Clear Parity IRQ */ -#define CSR_IRQ_CL_B (1L<<2) /* Bit 2: Clear EOB IRQ */ -#define CSR_IRQ_CL_F (1L<<1) /* Bit 1: Clear EOF IRQ */ -#define CSR_IRQ_CL_C (1L<<0) /* Bit 0: Clear ERR IRQ */ - -#define CSR_SET_RESET (CSR_DESC_SET|CSR_FIFO_SET|CSR_HPI_RST|CSR_SV_RST|\ - CSR_DREAD_RST|CSR_DWRITE_RST|CSR_TRANS_RST) -#define CSR_CLR_RESET (CSR_DESC_CLR|CSR_FIFO_CLR|CSR_HPI_RUN|CSR_SV_RUN|\ - CSR_DREAD_RUN|CSR_DWRITE_RUN|CSR_TRANS_RUN) - +/* Q_CSR 32 bit BMU Control/Status Register */ + /* Bit 31..25: reserved */ +#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */ + /* Bit 23..22: reserved */ +#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */ +#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */ +#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */ +#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */ +#define CSR_HPI_RUN BIT_17 /* Release HPI SM */ +#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */ +#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */ +#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */ +#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */ +#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */ +#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */ +#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */ +#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */ +#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */ +#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */ +#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */ +#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */ +#define CSR_START BIT_4 /* Start Rx/Tx Queue */ +#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */ +#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */ +#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */ +#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */ + +#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\ + CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\ + CSR_TRANS_RST) +#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\ + CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\ + CSR_TRANS_RUN) /* Q_F 32 bit Flag Register */ - /* Bit 28..31: reserved */ -#define F_ALM_FULL (1L<<27) (Rx) /* Bit 27: (Rx) FIFO almost full */ -#define F_EMPTY (1L<<27) (Tx) /* Bit 27: (Tx) FIFO empty flag */ -#define F_FIFO_EOF (1L<<26) /* Bit 26: Fag bit in FIFO */ -#define F_WM_REACHED (1L<<25) /* Bit 25: Watermark reached */ - /* Bit 24: reserved */ + /* Bit 31..28: reserved */ +#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */ +#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */ +#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */ +#define F_WM_REACHED BIT_25 /* Watermark reached */ + /* reserved */ #define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */ /* Bit 15..11: reserved */ #define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */ /* Q_T1 32 bit Test Register 1 */ /* Holds four State Machine control Bytes */ -#define SM_CRTL_SV (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ -#define SM_CRTL_RD (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ -#define SM_CRTL_WR (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ -#define SM_CRTL_TR (0xffL<<0) /* Bit 7.. 0: Control Transfer SM */ +#define SM_CRTL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ +#define SM_CRTL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ +#define SM_CRTL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ +#define SM_CRTL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */ /* Q_T1_TR 8 bit Test Register 1 Transfer SM */ /* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */ /* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */ /* Q_T1_SV 8 bit Test Register 1 Supervisor SM */ + /* The control status byte of each machine looks like ... */ -#define SM_STATE 0xf0 /* Bit 7..4: State which shall be loaded */ -#define SM_LOAD (1<<3) /* Bit 3: Load the SM with SM_STATE */ -#define SM_TEST_ON (1<<2) /* Bit 2: Switch on SM Test Mode */ -#define SM_TEST_OFF (1<<1) /* Bit 1: Go off the Test Mode */ -#define SM_STEP (1<<0) /* Bit 0: Step the State Machine */ +#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */ +#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */ +#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */ +#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */ +#define SM_STEP BIT_0S /* Step the State Machine */ /* The encoding of the states is not supported by the Diagnostics Tool */ /* Q_T2 32 bit Test Register 2 */ - /* Bit 31..8: reserved */ -#define T2_AC_T_ON (1<<7) /* Bit 7: Address Counter Test Mode on */ -#define T2_AC_T_OFF (1<<6) /* Bit 6: Address Counter Test Mode off*/ -#define T2_BC_T_ON (1<<5) /* Bit 5: Byte Counter Test Mode on */ -#define T2_BC_T_OFF (1<<4) /* Bit 4: Byte Counter Test Mode off */ -#define T2_STEP04 (1<<3) /* Bit 3: Inc AC/Dec BC by 4 */ -#define T2_STEP03 (1<<2) /* Bit 2: Inc AC/Dec BC by 3 */ -#define T2_STEP02 (1<<1) /* Bit 1: Inc AC/Dec BC by 2 */ -#define T2_STEP01 (1<<0) /* Bit 0: Inc AC/Dec BC by 1 */ + /* Bit 31.. 8: reserved */ +#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */ +#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */ +#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */ +#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */ +#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */ +#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */ +#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */ +#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */ /* Q_T3 32 bit Test Register 3 */ - /* Bit 31..7: reserved */ -#define T3_MUX (7<<4) /* Bit 6.. 4: Mux Position */ - /* Bit 3: reserved */ -#define T3_VRAM (7<<0) /* Bit 2.. 0: Virtual RAM Buffer Address */ + /* Bit 31.. 7: reserved */ +#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */ + /* Bit 3: reserved */ +#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */ -/* RAM Buffer Register Offsets */ -/* use RB_ADDR(Queue,Offs) to address */ +/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */ /* RB_START 32 bit RAM Buffer Start Address */ /* RB_END 32 bit RAM Buffer End Address */ /* RB_WP 32 bit RAM Buffer Write Pointer */ /* RB_RP 32 bit RAM Buffer Read Pointer */ /* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */ -/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pasue Pack */ +/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */ /* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */ /* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */ /* RB_PC 32 bit RAM Buffer Packet Counter */ @@ -1190,144 +1459,325 @@ /* Bit 31..19: reserved */ #define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */ -/* RB_TST2 8 bit RAM Buffer Test Register 2 */ - /* Bit 4..7: reserved */ -#define RB_PC_DEC (1<<3) /* Bit 3: Packet Counter Decrem */ -#define RB_PC_T_ON (1<<2) /* Bit 2: Packet Counter Test On */ -#define RB_PC_T_OFF (1<<1) /* Bit 1: Packet Counter Tst Off */ -#define RB_PC_INC (1<<0) /* Bit 0: Packet Counter Increm */ - -/* RB_TST1 8 bit RAM Buffer Test Register 1 */ - /* Bit 7: reserved */ -#define RB_WP_T_ON (1<<6) /* Bit 6: Write Pointer Test On */ -#define RB_WP_T_OFF (1<<5) /* Bit 5: Write Pointer Test Off */ -#define RB_WP_INC (1<<4) /* Bit 4: Write Pointer Increm */ - /* Bit 3: reserved */ -#define RB_RP_T_ON (1<<2) /* Bit 2: Read Pointer Test On */ -#define RB_RP_T_OFF (1<<1) /* Bit 1: Read Pointer Test Off */ -#define RB_RP_DEC (1<<0) /* Bit 0: Read Pointer Decrement */ - -/* RB_CTRL 8 bit RAM Buffer Control Register */ - /* Bit 7..6: reserved */ -#define RB_ENA_STFWD (1<<5) /* Bit 5: Enable Store & Forward */ -#define RB_DIS_STFWD (1<<4) /* Bit 4: Disab. Store & Forward */ -#define RB_ENA_OP_MD (1<<3) /* Bit 3: Enable Operation Mode */ -#define RB_DIS_OP_MD (1<<2) /* Bit 2: Disab. Operation Mode */ -#define RB_RST_CLR (1<<1) /* Bit 1: Clr RAM Buf STM Reset */ -#define RB_RST_SET (1<<0) /* Bit 0: Set RAM Buf STM Reset */ +/* RB_TST2 8 bit RAM Buffer Test Register 2 */ + /* Bit 7.. 4: reserved */ +#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */ +#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */ +#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */ +#define RB_PC_INC BIT_0S /* Packet Counter Increm */ + +/* RB_TST1 8 bit RAM Buffer Test Register 1 */ + /* Bit 7: reserved */ +#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */ +#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */ +#define RB_WP_INC BIT_4S /* Write Pointer Increm */ + /* Bit 3: reserved */ +#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */ +#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */ +#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */ + +/* RB_CTRL 8 bit RAM Buffer Control Register */ + /* Bit 7.. 6: reserved */ +#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */ +#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */ +#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */ +#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */ +#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */ +#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */ + +/* Receive and Transmit MAC FIFO Registers (GENESIS only) */ -/* Receive and Transmit MAC FIFO Registers, use MR_ADDR() to address */ /* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ /* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ /* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ -/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter*/ +/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ /* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ /* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ -/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer*/ -/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pt*/ +/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ +/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ /* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ /* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ /* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */ - /* Bit 31..6: reserved */ -#define MFF_MSK 0x007fL /* Bit 5..0: MAC FIFO Address/Pointer Bits */ + /* Bit 31.. 6: reserved */ +#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */ /* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */ - /* Bit 15..14: reserved */ -#define MFF_ENA_RDY_PAT (1<<13) /* Bit 13: Enable Ready Patch */ -#define MFF_DIS_RDY_PAT (1<<12) /* Bit 12: Disable Ready Patch */ -#define MFF_ENA_TIM_PAT (1<<11) /* Bit 11: Enable Timing Patch */ -#define MFF_DIS_TIM_PAT (1<<10) /* Bit 10: Disable Timing Patch */ -#define MFF_ENA_ALM_FUL (1<<9) /* Bit 9: Enable AlmostFull Sign*/ -#define MFF_DIS_ALM_FUL (1<<8) /* Bit 8: Disab. AlmostFull Sign*/ -#define MFF_ENA_PAUSE (1<<7) /* Bit 7: Enable Pause Signaling*/ -#define MFF_DIS_PAUSE (1<<6) /* Bit 6: Disab. Pause Signaling*/ -#define MFF_ENA_FLUSH (1<<5) /* Bit 5: Enable Frame Flushing */ -#define MFF_DIS_FLUSH (1<<4) /* Bit 4: Disab. Frame Flushing */ -#define MFF_ENA_TIST (1<<3) /* Bit 3: Enable Timestamp Gener*/ -#define MFF_DIS_TIST (1<<2) /* Bit 2: Disab. Timestamp Gener*/ -#define MFF_CLR_INTIST (1<<1) /* Bit 1: Clear IRQ No Timestamp*/ -#define MFF_CLR_INSTAT (1<<0) /* Bit 0: Clear IRQ No Status */ + /* Bit 15..14: reserved */ +#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */ +#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */ +#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */ +#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */ +#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */ +#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */ +#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */ +#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */ +#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */ +#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */ +#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */ +#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */ +#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */ +#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */ #define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT /* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */ -#define MFF_CLR_PERR (1<<15) /* Bit 15: Clear Parity Error IRQ*/ - /* Bit 14: reserved */ -#define MFF_ENA_PKT_REC (1<<13) /* Bit 13: Enable Packet Recovery*/ -#define MFF_DIS_PKT_REC (1<<12) /* Bit 12: Disable Packet Recov. */ -/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1)Bit 11: Enable Timing Patch */ -/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1)Bit 10: Disable Timing Patch */ -/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1)Bit 9: Enable AlmostFull Sign*/ -/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1)Bit 8: Disab. AlmostFull Sign*/ -#define MFF_ENA_W4E (1<<7) /* Bit 7: Enable Wait for Empty */ -#define MFF_DIS_W4E (1<<6) /* Bit 6: Disab. Wait for Empty */ -/* MFF_ENA_FLUSH (see RX_MFF_CTRL1)Bit 5: Enable Frame Flushing */ -/* MFF_DIS_FLUSH (see RX_MFF_CTRL1)Bit 4: Disab. Frame Flushing */ -#define MFF_ENA_LOOPB (1<<3) /* Bit 3: Enable Loopback */ -#define MFF_DIS_LOOPB (1<<2) /* Bit 2: Disable Loopback */ -#define MFF_CLR_MAC_RST (1<<1) /* Bit 1: Clear XMAC Reset */ -#define MFF_SET_MAC_RST (1<<0) /* Bit 0: Set XMAC Reset */ +#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */ + /* Bit 14: reserved */ +#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */ +#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */ +/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */ +/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */ +/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */ +/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */ +#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */ +#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */ +/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */ +/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */ +#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */ +#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */ +#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */ +#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */ #define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH) -/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */ -/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */ +/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */ +/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */ /* Bit 7: reserved */ -#define MFF_WSP_T_ON (1<<6) /* Bit 6: (Tx) Write Shadow Pt TestOn */ -#define MFF_WSP_T_OFF (1<<5) /* Bit 5: (Tx) Write Shadow Pt TstOff */ -#define MFF_WSP_INC (1<<4) /* Bit 4: (Tx) Write Shadow Pt Increm */ -#define MFF_PC_DEC (1<<3) /* Bit 3: Packet Counter Decrem */ -#define MFF_PC_T_ON (1<<2) /* Bit 2: Packet Counter Test On */ -#define MFF_PC_T_OFF (1<<1) /* Bit 1: Packet Counter Tst Off */ -#define MFF_PC_INC (1<<0) /* Bit 0: Packet Counter Increm */ +#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */ +#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */ +#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */ +#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */ +#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */ +#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */ +#define MFF_PC_INC BIT_0S /* Packet Counter Increment */ -/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */ -/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */ +/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */ +/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */ /* Bit 7: reserved */ -#define MFF_WP_T_ON (1<<6) /* Bit 6: Write Pointer Test On */ -#define MFF_WP_T_OFF (1<<5) /* Bit 5: Write Pointer Test Off */ -#define MFF_WP_INC (1<<4) /* Bit 4: Write Pointer Increm */ - /* Bit 3: reserved */ -#define MFF_RP_T_ON (1<<2) /* Bit 2: Read Pointer Test On */ -#define MFF_RP_T_OFF (1<<1) /* Bit 1: Read Pointer Test Off */ -#define MFF_RP_DEC (1<<0) /* Bit 0: Read Pointer Decrement */ +#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */ +#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */ +#define MFF_WP_INC BIT_4S /* Write Pointer Increm */ + /* Bit 3: reserved */ +#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */ +#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */ +#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */ /* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */ /* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */ /* Bit 7..4: reserved */ -#define MFF_ENA_OP_MD (1<<3) /* Bit 3: Enable Operation Mode */ -#define MFF_DIS_OP_MD (1<<2) /* Bit 2: Disab. Operation Mode */ -#define MFF_RST_CLR (1<<1) /* Bit 1: Clear MAC FIFO Reset */ -#define MFF_RST_SET (1<<0) /* Bit 0: Set MAC FIFO Reset */ - - -/* Receive, Transmit, and Link LED Counter Registers */ -/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */ -/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */ -/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */ - /* Bit 7..3: reserved */ -#define LED_START (1<<2) /* Bit 2: Start Timer */ -#define LED_STOP (1<<1) /* Bit 1: Stop Timer */ -#define LED_STATE (1<<0) /* Bit 0:(Rx/Tx)LED State, 1=LED on */ -#define LED_CLR_IRQ (1<<0) /* Bit 0:(Lnk) Clear Link IRQ */ - -/* RX_LED_TST 8 bit Receive LED Cnt Test Register */ -/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */ -/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */ - /* Bit 7..3: reserved */ -#define LED_T_ON (1<<2) /* Bit 2: LED Counter Testmode On */ -#define LED_T_OFF (1<<1) /* Bit 1: LED Counter Testmode Off */ -#define LED_T_STEP (1<<0) /* Bit 0: LED Counter Step */ - -/* LNK_LED_REG 8 bit Link LED Register */ - /* Bit 7..6: reserved */ -#define LED_BLK_ON (1<<5) /* Bit 5: Link LED Blinking On */ -#define LED_BLK_OFF (1<<4) /* Bit 4: Link LED Blinking Off */ -#define LED_SYNC_ON (1<<3) /* Bit 3: Use Sync Wire to switch LED */ -#define LED_SYNC_OFF (1<<2) /* Bit 2: Disable Sync Wire Input */ -#define LED_ON (1<<1) /* Bit 1: switch LED on */ -#define LED_OFF (1<<0) /* Bit 0: switch LED off */ +#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */ +#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */ +#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */ +#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */ + + +/* Link LED Counter Registers (GENESIS only) */ + +/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */ +/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */ +/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */ + /* Bit 7.. 3: reserved */ +#define LED_START BIT_2S /* Start Timer */ +#define LED_STOP BIT_1S /* Stop Timer */ +#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */ +#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */ + +/* RX_LED_TST 8 bit Receive LED Cnt Test Register */ +/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */ +/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */ + /* Bit 7.. 3: reserved */ +#define LED_T_ON BIT_2S /* LED Counter Test mode On */ +#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */ +#define LED_T_STEP BIT_0S /* LED Counter Step */ + +/* LNK_LED_REG 8 bit Link LED Register */ + /* Bit 7.. 6: reserved */ +#define LED_BLK_ON BIT_5S /* Link LED Blinking On */ +#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */ +#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */ +#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */ +#define LED_ON BIT_1S /* switch LED on */ +#define LED_OFF BIT_0S /* switch LED off */ + +/* Receive and Transmit GMAC FIFO Registers (YUKON only) */ + +/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */ +/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */ +/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */ +/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */ +/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */ +/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */ +/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */ +/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/ +/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */ +/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */ +/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */ +/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */ +/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */ +/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */ + +/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */ + /* Bits 31..15: reserved */ +#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */ +#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ +#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */ + /* Bit 11: reserved */ +#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */ +#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */ +#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */ +#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */ +#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */ +#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */ +#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */ +#define GMF_OPER_ON BIT_3 /* Operational Mode On */ +#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */ +#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */ +#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */ + +/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ + /* Bits 31..19: reserved */ +#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */ +#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */ +#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */ + /* Bits 15..7: same as for RX_GMF_CTRL_T */ +#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */ +#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */ +#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */ + /* Bits 3..0: same as for RX_GMF_CTRL_T */ + +#define GMF_RX_CTRL_DEF GMF_OPER_ON +#define GMF_TX_CTRL_DEF GMF_OPER_ON + +/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ + /* Bit 7.. 3: reserved */ +#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */ +#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */ +#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */ + +/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */ + /* Bits 31.. 8: reserved */ +#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */ +#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */ +#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */ +#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */ +#define GMC_PAUSE_ON BIT_3 /* Pause On */ +#define GMC_PAUSE_OFF BIT_2 /* Pause Off */ +#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */ +#define GMC_RST_SET BIT_0 /* Set GMAC Reset */ + +/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */ + /* Bits 31..29: reserved */ +#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */ +#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */ +#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */ +#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */ +#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */ +#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */ +#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */ +#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */ +#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */ +#define GPC_ANEG_0 BIT_19 /* ANEG[0] */ +#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */ +#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */ +#define GPC_ANEG_3 BIT_16 /* ANEG[3] */ +#define GPC_ANEG_2 BIT_15 /* ANEG[2] */ +#define GPC_ANEG_1 BIT_14 /* ANEG[1] */ +#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */ +#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */ +#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */ +#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */ +#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */ +#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */ + /* Bits 7..2: reserved */ +#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */ +#define GPC_RST_SET BIT_0 /* Set GPHY Reset */ + +#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \ + GPC_HWCFG_M_1 | GPC_HWCFG_M_0) + +#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \ + GPC_HWCFG_M_1 | GPC_HWCFG_M_0) + +#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \ + GPC_ANEG_1 | GPC_ANEG_0) + +/* forced speed and duplex mode (don't mix with other ANEG bits) */ +#define GPC_FRC10MBIT_HALF 0 +#define GPC_FRC10MBIT_FULL GPC_ANEG_0 +#define GPC_FRC100MBIT_HALF GPC_ANEG_1 +#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1) + +/* auto-negotiation with limited advertised speeds */ +/* mix only with master/slave settings (for copper) */ +#define GPC_ADV_1000_HALF GPC_ANEG_2 +#define GPC_ADV_1000_FULL GPC_ANEG_3 +#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3) + +/* master/slave settings */ +/* only for copper with 1000 Mbps */ +#define GPC_FORCE_MASTER 0 +#define GPC_FORCE_SLAVE GPC_ANEG_0 +#define GPC_PREF_MASTER GPC_ANEG_1 +#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0) + +/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */ +/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */ +#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */ +#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */ +#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */ +#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */ +#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */ +#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */ + +#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \ + GM_IS_TX_FF_UR) + +/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ + /* Bits 15.. 2: reserved */ +#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */ +#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */ + + +/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ +#define WOL_CTL_LINK_CHG_OCC BIT_15S +#define WOL_CTL_MAGIC_PKT_OCC BIT_14S +#define WOL_CTL_PATTERN_OCC BIT_13S + +#define WOL_CTL_CLEAR_RESULT BIT_12S + +#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S +#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S +#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S +#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S +#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S +#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S + +#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S +#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S +#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S +#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S +#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S +#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S + +#define WOL_CTL_DEFAULT \ + (WOL_CTL_DIS_PME_ON_LINK_CHG | \ + WOL_CTL_DIS_PME_ON_PATTERN | \ + WOL_CTL_DIS_PME_ON_MAGIC_PKT | \ + WOL_CTL_DIS_LINK_CHG_UNIT | \ + WOL_CTL_DIS_PATTERN_UNIT | \ + WOL_CTL_DIS_MAGIC_PKT_UNIT) + +/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ +#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x)) + +#define SK_NUM_WOL_PATTERN 7 +#define SK_PATTERN_PER_WORD 4 +#define SK_BITMASK_PATTERN 7 +#define SK_POW_PATTERN_LENGTH 128 + +#define WOL_LENGTH_MSK 0x7f +#define WOL_LENGTH_SHIFT 8 /* Receive and Transmit Descriptors ******************************************/ @@ -1356,55 +1806,56 @@ /* Receive Descriptor struct */ typedef struct s_HwRxd { SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */ - SK_U32 RxNext; /* Physical Address Pointer to the next TxD */ - SK_U32 RxAdrLo; /* Physical Receive Buffer Address lower dword*/ - SK_U32 RxAdrHi; /* Physical Receive Buffer Address upper dword*/ - SK_U32 RxStat; /* Receive Frame Status Word */ - SK_U32 RxTiSt; /* Receive Timestamp provided by the XMAC */ + SK_U32 RxNext; /* Physical Address Pointer to the next RxD */ + SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */ + SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */ + SK_U32 RxStat; /* Receive Frame Status Word */ + SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */ #ifndef SK_USE_REV_DESC - SK_U16 RxTcpSum1; /* TCP Checksum 1 */ - SK_U16 RxTcpSum2; /* TCP Checksum 2 */ - SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ - SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ + SK_U16 RxTcpSum1; /* TCP Checksum 1 */ + SK_U16 RxTcpSum2; /* TCP Checksum 2 */ + SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ + SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ #else /* SK_USE_REV_DESC */ - SK_U16 RxTcpSum2; /* TCP Checksum 2 */ - SK_U16 RxTcpSum1; /* TCP Checksum 1 */ - SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ - SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ + SK_U16 RxTcpSum2; /* TCP Checksum 2 */ + SK_U16 RxTcpSum1; /* TCP Checksum 1 */ + SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ + SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ #endif /* SK_USE_REV_DESC */ } SK_HWRXD; /* * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2) * should set the define SK_USE_REV_DESC. - * Structures are 'normaly' not endianess dependent. But in + * Structures are 'normaly' not endianess dependent. But in * this case the SK_U16 fields are bound to bit positions inside the * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord. * The bit positions inside a DWord are of course endianess dependent and - * swaps if the DWord is swaped by the hardware. + * swaps if the DWord is swapped by the hardware. */ /* Descriptor Bit Definition */ /* TxCtrl Transmit Buffer Control Field */ -/* RxCtrl Receive Buffer Control Field */ -#define BMU_OWN (1UL<<31) /* Bit 31: OWN bit: 0=host/1=BMU */ -#define BMU_STF (1L<<30) /* Bit 30: Start of Frame ? */ -#define BMU_EOF (1L<<29) /* Bit 29: End of Frame ? */ -#define BMU_IRQ_EOB (1L<<28) /* Bit 28: Req "End of Buff" IRQ */ -#define BMU_IRQ_EOF (1L<<27) /* Bit 27: Req "End of Frame" IRQ*/ +/* RxCtrl Receive Buffer Control Field */ +#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */ +#define BMU_STF BIT_30 /* Start of Frame */ +#define BMU_EOF BIT_29 /* End of Frame */ +#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */ +#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */ /* TxCtrl specific bits */ -#define BMU_STFWD (1L<<26) /* Bit 26: (Tx) Store&Forward Frame */ -#define BMU_NO_FCS (1L<<25) /* Bit 25: (Tx) disable XMAC FCS gener*/ -#define BMU_SW (1L<<24) /* Bit 24: (Tx) 1 bit res. for SW use */ +#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */ +#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */ +#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */ /* RxCtrl specific bits */ -#define BMU_DEV_0 (1L<<26) /* Bit 26: (Rx) transfer data to Dev0 */ -#define BMU_STAT_VAL (1L<<25) /* Bit 25: (Rx) RxStat Valid */ -#define BMU_TIST_VAL (1L<<24) /* Bit 24: (Rx) RxTiSt Valid */ - /* Bit 23..16: BMU Check Opcodes */ -#define BMU_CHECK 0x00550000L /* Default BMU check */ -#define BMU_TCP_CHECK 0x00560000L /* Descr with TCP ext */ -#define BMU_BBC 0x0000FFFFL /* Bit 15..0: Buffer Byte Counter */ +#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */ +#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */ +#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */ + /* Bit 23..16: BMU Check Opcodes */ +#define BMU_CHECK (0x55L<<16) /* Default BMU check */ +#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */ +#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */ +#define BMU_BBC 0xFFFFL /* Bit 15.. 0: Buffer Byte Counter */ /* TxStat Transmit Frame Status Word */ /* RxStat Receive Frame Status Word */ @@ -1420,9 +1871,9 @@ /* * FlashProm specification */ -#define MAX_PAGES 0x20000L /* Every byte has a single page */ -#define MAX_FADDR 1 /* 1 byte per page */ -#define SKFDDI_PSZ 8 /* address PROM size */ +#define MAX_PAGES 0x20000L /* Every byte has a single page */ +#define MAX_FADDR 1 /* 1 byte per page */ +#define SKFDDI_PSZ 8 /* address PROM size */ /* macros ********************************************************************/ @@ -1439,59 +1890,67 @@ /* * Macro Q_ADDR() * - * Use this macro to address the Receive and Transmit Queue Registers. + * Use this macro to access the Receive and Transmit Queue Registers. * - * para Queue Queue to address. - * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 + * para: + * Queue Queue to access. + * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 * Offs Queue register offset. - * Values: Q_D, Q_DA_L ... Q_T2, Q_T3 + * Values: Q_D, Q_DA_L ... Q_T2, Q_T3 * - * usage SK_IN32(pAC,Q_ADDR(Q_R2,Q_BC),pVal) + * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal) */ -#define Q_ADDR(Queue,Offs) (B8_Q_REGS + (Queue) + (Offs)) +#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs)) /* * Macro RB_ADDR() * - * Use this macro to address the RAM Buffer Registers. + * Use this macro to access the RAM Buffer Registers. * - * para Queue Queue to address. - * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 + * para: + * Queue Queue to access. + * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 * Offs Queue register offset. - * Values: RB_START, RB_END ... RB_LEV, RB_CTRL + * Values: RB_START, RB_END ... RB_LEV, RB_CTRL * - * usage SK_IN32(pAC,RB_ADDR(Q_R2,RB_RP),pVal) + * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal) */ -#define RB_ADDR(Queue,Offs) (B16_RAM_REGS + (Queue) + (Offs)) +#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs)) /* * MAC Related Registers */ -#define MAC_1 0 /* belongs to the port near the slot */ +#define MAC_1 0 /* belongs to the port near the slot */ #define MAC_2 1 /* belongs to the port far away from the slot */ /* * Macro MR_ADDR() * - * Use this macro to address a MAC Related Registers in side the ASIC. + * Use this macro to access a MAC Related Registers inside the ASIC. * - * para Queue Queue to address. - * Values: TXA_ITI_INI ... TXA_TEST, - * RX_MFF_EA ... RX_LED_TST, - * LNK_SYNC_INI ... LNK_LED_REG, and - * TX_MFF_EA ... TX_LED_TST - * Mac MAC to address. - * Values: MAC_1, MAC_2 + * para: + * Mac MAC to access. + * Values: MAC_1, MAC_2 + * Offs MAC register offset. + * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG, + * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST * - * usage SK_IN32(pAC,MR_ADDR(MAC_1,TX_MFF_EA),pVal) + * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal) */ -#define MR_ADDR(Mac,Offs) (((Mac) << 7) + (Offs)) +#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs)) +#ifdef SK_LITTLE_ENDIAN +#define XM_WORD_LO 0 +#define XM_WORD_HI 1 +#else /* !SK_LITTLE_ENDIAN */ +#define XM_WORD_LO 1 +#define XM_WORD_HI 0 +#endif /* !SK_LITTLE_ENDIAN */ /* - * macros to access the XMAC + * macros to access the XMAC (GENESIS only) * * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD) * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD) @@ -1502,43 +1961,37 @@ * XM_INHASH(), to read the XM_HSM_CHK register * XM_OUTHASH() to write the XM_HSM_CHK register * - * para: Mac XMAC to address values: MAC_1 or MAC_2 - * IoC I/O context needed for SK IO macros - * Reg XMAC Register to read or write - * (p)Val Value or pointer to the value which should be read or - * written. + * para: + * Mac XMAC to access values: MAC_1 or MAC_2 + * IoC I/O context needed for SK I/O macros + * Reg XMAC Register to read or write + * (p)Val Value or pointer to the value which should be read or written * * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value); */ -#ifdef SK_LITTLE_ENDIAN -#define XM_WORD_LO 0 -#define XM_WORD_HI 1 -#else /* !SK_LITTLE_ENDIAN */ -#define XM_WORD_LO 1 -#define XM_WORD_HI 0 -#endif /* !SK_LITTLE_ENDIAN */ +#define XMA(Mac, Reg) \ + ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1)) -#define XMA(Mac,Reg) (((0x1000 << (Mac)) + 0x1000) | ((Reg) << 1)) +#define XM_IN16(IoC, Mac, Reg, pVal) \ + SK_IN16((IoC), XMA((Mac), (Reg)), (pVal)) -#define XM_IN16(IoC,Mac,Reg,pVal) SK_IN16((IoC), XMA((Mac), (Reg)), (pVal)) -#define XM_OUT16(IoC,Mac,Reg,Val) SK_OUT16((IoC), XMA((Mac), (Reg)), (Val)) +#define XM_OUT16(IoC, Mac, Reg, Val) \ + SK_OUT16((IoC), XMA((Mac), (Reg)), (Val)) -#define XM_IN32(IoC,Mac,Reg,pVal) { \ +#define XM_IN32(IoC, Mac, Reg, pVal) { \ SK_IN16((IoC), XMA((Mac), (Reg)), \ (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]); \ SK_IN16((IoC), XMA((Mac), (Reg+2)), \ (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]); \ } -#define XM_OUT32(IoC,Mac,Reg,Val) { \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0x0000ffffL)); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)),(SK_U16)(((Val)>>16) & 0x0000ffffL)); \ +#define XM_OUT32(IoC, Mac, Reg, Val) { \ + SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \ + SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\ } -/* - * Remember: we are always writing to / reading from LITTLE ENDIAN memory - */ +/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */ #define XM_INADDR(IoC, Mac, Reg, pVal) { \ SK_U16 Word; \ @@ -1605,32 +2058,150 @@ } /* + * macros to access the GMAC (YUKON only) + * + * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT) + * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL) + * GM_IN32(), to read a 32 bit register (e.g. GM_) + * GM_OUT32(), to write a 32 bit register (e.g. GM_) + * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L) + * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L) + * GM_INHASH(), to read the GM_MC_ADDR_H1 register + * GM_OUTHASH() to write the GM_MC_ADDR_H1 register + * + * para: + * Mac GMAC to access values: MAC_1 or MAC_2 + * IoC I/O context needed for SK I/O macros + * Reg GMAC Register to read or write + * (p)Val Value or pointer to the value which should be read or written + * + * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value); + */ + +#define GMA(Mac, Reg) \ + ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg)) + +#define GM_IN16(IoC, Mac, Reg, pVal) \ + SK_IN16((IoC), GMA((Mac), (Reg)), (pVal)) + +#define GM_OUT16(IoC, Mac, Reg, Val) \ + SK_OUT16((IoC), GMA((Mac), (Reg)), (Val)) + +#define GM_IN32(IoC, Mac, Reg, pVal) { \ + SK_IN16((IoC), GMA((Mac), (Reg)), \ + (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]); \ + SK_IN16((IoC), GMA((Mac), (Reg+4)), \ + (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]); \ +} + +#define GM_OUT32(IoC, Mac, Reg, Val) { \ + SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \ + SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\ +} + +#define GM_INADDR(IoC, Mac, Reg, pVal) { \ + SK_U16 Word; \ + SK_U8 *pByte; \ + pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ + pByte[0] = (SK_U8)(Word & 0x00ff); \ + pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \ + pByte[2] = (SK_U8)(Word & 0x00ff); \ + pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \ + pByte[4] = (SK_U8)(Word & 0x00ff); \ + pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ +} + +#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \ + SK_U8 *pByte; \ + pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ + (((SK_U16)(pByte[0]) & 0x00ff) | \ + (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ + SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \ + (((SK_U16)(pByte[2]) & 0x00ff) | \ + (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ + SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \ + (((SK_U16)(pByte[4]) & 0x00ff) | \ + (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ +} + +#define GM_INHASH(IoC, Mac, Reg, pVal) { \ + SK_U16 Word; \ + SK_U8 *pByte; \ + pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ + pByte[0] = (SK_U8)(Word & 0x00ff); \ + pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \ + pByte[2] = (SK_U8)(Word & 0x00ff); \ + pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \ + pByte[4] = (SK_U8)(Word & 0x00ff); \ + pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \ + pByte[6] = (SK_U8)(Word & 0x00ff); \ + pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ +} + +#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \ + SK_U8 *pByte; \ + pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ + (((SK_U16)(pByte[0]) & 0x00ff)| \ + (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ + SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \ + (((SK_U16)(pByte[2]) & 0x00ff)| \ + (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ + SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \ + (((SK_U16)(pByte[4]) & 0x00ff)| \ + (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ + SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \ + (((SK_U16)(pByte[6]) & 0x00ff)| \ + (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ +} + +/* + * Different MAC Types + */ +#define SK_MAC_XMAC 0 /* Xaqti XMAC II */ +#define SK_MAC_GMAC 1 /* Marvell GMAC */ + +/* * Different PHY Types */ -#define SK_PHY_XMAC 0 /* integrated in Xmac II*/ -#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */ -#define SK_PHY_LONE 2 /* Level One LXT1000 */ -#define SK_PHY_NAT 3 /* National DP83891 */ +#define SK_PHY_XMAC 0 /* integrated in XMAC II */ +#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */ +#define SK_PHY_LONE 2 /* Level One LXT1000 */ +#define SK_PHY_NAT 3 /* National DP83891 */ +#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */ +#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */ /* - * PHY addresses (bits 8..12 of PHY address reg) + * PHY addresses (bits 12..8 of PHY address reg) */ #define PHY_ADDR_XMAC (0<<8) #define PHY_ADDR_BCOM (1<<8) #define PHY_ADDR_LONE (3<<8) #define PHY_ADDR_NAT (0<<8) + +/* GPHY address (bits 15..11 of SMI control reg) */ +#define PHY_ADDR_MARV 0 /* * macros to access the PHY * * PHY_READ() read a 16 bit value from the PHY - * PHY_WIRTE() write a 16 bit value to the PHY + * PHY_WRITE() write a 16 bit value to the PHY * - * para: IoC I/O context needed for SK IO macros - * pPort Pointer to port struct for PhyAddr - * Mac XMAC to address values: MAC_1 or MAC_2 - * PhyReg PHY Register to read or write - * (p)Val Value or pointer to the value which should be read or + * para: + * IoC I/O context needed for SK I/O macros + * pPort Pointer to port struct for PhyAddr + * Mac XMAC to access values: MAC_1 or MAC_2 + * PhyReg PHY Register to read or write + * (p)Val Value or pointer to the value which should be read or * written. * * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value); @@ -1671,7 +2242,7 @@ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ } \ } -#endif +#endif /* DEBUG */ #define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \ SK_U16 Mmu; \ @@ -1693,48 +2264,52 @@ /* * Macro PCI_C() * - * Use this macro to address PCI config register from the IO space. + * Use this macro to access PCI config register from the I/O space. * - * para Addr PCI configuration register to address. + * para: + * Addr PCI configuration register to access. * Values: PCI_VENDOR_ID ... PCI_VPD_ADDR, * - * usage SK_IN16(pAC,PCI_C(PCI_VENDOR_ID),pVal); + * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal); */ #define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */ /* - * Macro SK_ADDR(Base,Addr) + * Macro SK_HW_ADDR(Base, Addr) * * Calculates the effective HW address * - * para Base IO- or memory base address + * para: + * Base I/O or memory base address * Addr Address offset * * usage: May be used in SK_INxx and SK_OUTxx macros - * #define SK_IN8(pAC,Addr,pVal) ...\ - * *pVal = (SK_U8) inp(SK_ADDR(pAC->Hw.Iop,Addr))) + * #define SK_IN8(pAC, Addr, pVal) ...\ + * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr))) */ #ifdef SK_MEM_MAPPED_IO -#define SK_HW_ADDR(Base,Addr) ((Base)+(Addr)) +#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr)) #else /* SK_MEM_MAPPED_IO */ -#define SK_HW_ADDR(Base,Addr) ((Base)+(((Addr)&0x7F)|((Addr)>>7 ? 0x80:0))) +#define SK_HW_ADDR(Base, Addr) \ + ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0))) #endif /* SK_MEM_MAPPED_IO */ -#define SZ_LONG (sizeof(SK_U32)) +#define SZ_LONG (sizeof(SK_U32)) /* * Macro SK_HWAC_LINK_LED() * * Use this macro to set the link LED mode. - * para pAC Pointer to adapter context struct - * IoC I/O context needed for SK IO macros - * Port Port number + * para: + * pAC Pointer to adapter context struct + * IoC I/O context needed for SK I/O macros + * Port Port number * Mode Mode to set for this LED */ #define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \ - SK_OUT8(IoC, MR_ADDR(Port,LNK_LED_REG), Mode); + SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode); + - /* typedefs *******************************************************************/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgehwt.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgehwt.h --- linux.21pre4/drivers/net/sk98lin/h/skgehwt.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgehwt.h 2003-01-06 15:38:18.000000000 +0000 @@ -1,32 +1,23 @@ /****************************************************************************** * * Name: skhwt.h - * Project: Genesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.4 $ - * Date: $Date: 1998/08/19 09:50:58 $ + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.5 $ + * Date: $Date: 1999/11/22 13:54:24 $ * Purpose: Defines for the hardware timer functions * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1989-1998 SysKonnect, + * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. - * All Rights Reserved * - * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT - * The copyright notice above does not evidence any - * actual or intended publication of such source code. - * - * This Module contains Proprietary Information of SysKonnect - * and should be treated as Confidential. - * - * The information in this file is provided for the exclusive use of - * the licensees of SysKonnect. - * Such users have the right to use, modify, and incorporate this code - * into products for purposes authorized by the license agreement - * provided they include this notice and the associated copyright notice - * with any such product. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -36,6 +27,9 @@ * History: * * $Log: skgehwt.h,v $ + * Revision 1.5 1999/11/22 13:54:24 cgoos + * Changed license header to GPL. + * * Revision 1.4 1998/08/19 09:50:58 gklug * fix: remove struct keyword from c-code (see CCC) add typedefs * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgei2c.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgei2c.h --- linux.21pre4/drivers/net/sk98lin/h/skgei2c.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgei2c.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,17 +2,15 @@ * * Name: skgei2c.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.17 $ - * Date: $Date: 1999/11/22 13:55:25 $ - * Purpose: Special genesis defines for I2C - * (taken from Monalisa (taken from Concentrator)) + * Version: $Revision: 1.23 $ + * Date: $Date: 2002/12/19 14:34:27 $ + * Purpose: Special GEnesis defines for TWSI * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -28,6 +26,28 @@ * History: * * $Log: skgei2c.h,v $ + * Revision 1.23 2002/12/19 14:34:27 rschmidt + * Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT() + * Editorial changes (TWSI) + * + * Revision 1.22 2002/10/14 16:45:56 rschmidt + * Editorial changes (TWSI) + * + * Revision 1.21 2002/08/13 08:42:24 rschmidt + * Changed define for SK_MIN_SENSORS back to 5 + * Merged defines for PHY PLL 3V3 voltage (A and B) + * Editorial changes + * + * Revision 1.20 2002/08/06 09:43:56 jschmalz + * Extensions and changes for Yukon + * + * Revision 1.19 2002/08/02 12:00:08 rschmidt + * Added defines for YUKON sensors + * Editorial changes + * + * Revision 1.18 2001/08/16 12:44:33 afischer + * LM80 sensor init values corrected + * * Revision 1.17 1999/11/22 13:55:25 cgoos * Changed license header to GPL. * @@ -70,7 +90,7 @@ * * Revision 1.5 1998/08/17 06:52:21 malthoff * Remove unrequired macros. - * Add macros for accessing I2C SW register. + * Add macros for accessing TWSI SW register. * * Revision 1.4 1998/08/13 08:30:18 gklug * add: conversion factors for read values @@ -81,8 +101,8 @@ * * Revision 1.2 1998/08/11 07:54:38 gklug * add: sensor states for GE sensors - * add: Macro to access I2c hardware register - * chg: Error messages for I2c errors + * add: Macro to access TWSI hardware register + * chg: Error messages for TWSI errors * * Revision 1.1 1998/07/17 11:27:56 gklug * Created. @@ -92,7 +112,7 @@ ******************************************************************************/ /* - * SKGEI2C.H contains all SK-98xx specific defines for the I2C handling + * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling */ #ifndef _INC_SKGEI2C_H_ @@ -101,12 +121,12 @@ /* * Macros to access the B2_I2C_CTRL */ -#define SK_I2C_CTL(IoC,flag,dev,reg,burst) \ - SK_OUT32(IoC,B2_I2C_CTRL,\ - (flag ? 0x80000000UL : 0x0L ) | \ +#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \ + SK_OUT32(IoC, B2_I2C_CTRL,\ + (flag ? 0x80000000UL : 0x0L) | \ (((SK_U32) reg << 16) & I2C_ADDR) | \ (((SK_U32) dev << 9) & I2C_DEV_SEL) | \ - (( burst << 4) & I2C_BURST_LEN) ) + (( burst << 4) & I2C_BURST_LEN)) #define SK_I2C_STOP(IoC) { \ SK_U32 I2cCtrl; \ @@ -114,29 +134,29 @@ SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \ } -#define SK_I2C_GET_CTL(Ioc,pI2cCtrl) SK_IN32(Ioc,B2_I2C_CTRL,pI2cCtrl) +#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl) /* - * Macros to access the I2C SW Registers + * Macros to access the TWSI SW Registers */ #define SK_I2C_SET_BIT(IoC, SetBits) { \ SK_U8 OrgBits; \ SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ - SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SetBits)); \ + SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \ } -#define SK_I2C_CLR_BIT(IoC,ClrBits) { \ +#define SK_I2C_CLR_BIT(IoC, ClrBits) { \ SK_U8 OrgBits; \ SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ - SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~(ClrBits)); \ + SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \ } -#define SK_I2C_GET_SW(IoC,pI2cSw) SK_IN8(IoC,B2_I2C_SW,pI2cSw) +#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw) /* * define the possible sensor states */ -#define SK_SEN_IDLE 0 /* Idle: sensor not read */ +#define SK_SEN_IDLE 0 /* Idle: sensor not read */ #define SK_SEN_VALUE 1 /* Value Read cycle */ #define SK_SEN_VALEXT 2 /* Extended Value Read cycle */ @@ -147,7 +167,7 @@ #define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */ #define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */ #define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for the - * extension value + * extension value */ #define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) /* formula: counter = (22500*60)/(rpm * divisor * pulses/2) @@ -163,20 +183,27 @@ #define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */ /* + * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto + */ +#define SK_TIMER_WATCH_STATEMACHINE 0 /* Watch the statemachine to finish in a specific time */ +#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ + + +/* * Defines for the individual Thresholds */ /* Temperature sensor */ -#define SK_SEN_ERRHIGH0 800 /* Temperature High Err Threshold */ -#define SK_SEN_WARNHIGH0 700 /* Temperature High Warn Threshold */ -#define SK_SEN_WARNLOW0 100 /* Temperature Low Err Threshold */ -#define SK_SEN_ERRLOW0 0 /* Temperature Low Warn Threshold */ +#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ +#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */ +#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */ +#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ /* VCC which should be 5 V */ -#define SK_SEN_ERRHIGH1 5588 /* Voltage PCI High Err Threshold */ -#define SK_SEN_WARNHIGH1 5346 /* Voltage PCI High Warn Threshold */ -#define SK_SEN_WARNLOW1 4664 /* Voltage PCI Low Err Threshold */ -#define SK_SEN_ERRLOW1 4422 /* Voltage PCI Low Warn Threshold */ +#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ +#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ +#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */ +#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */ /* * VIO may be 5 V or 3.3 V. Initialization takes two parts: @@ -187,49 +214,66 @@ * Warning limits are +-5% of the exepected voltage. * Error limits are +-10% of the expected voltage. */ -#define SK_SEN_ERRHIGH2 5588 /* Voltage PCI-IO High Err Threshold */ -#define SK_SEN_WARNHIGH2 5346 /* Voltage PCI-IO High Warn Threshold */ -#define SK_SEN_WARNLOW2 3146 /* Voltage PCI-IO Low Err Threshold */ -#define SK_SEN_ERRLOW2 2970 /* Voltage PCI-IO Low Warn Threshold */ + +/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */ + +#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */ +#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */ + /* 5000 mVolt */ +#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */ + +#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */ /* correction values for the second pass */ -#define SK_SEN_ERRHIGH2C 3630 /* Voltage PCI-IO High Err Threshold */ -#define SK_SEN_WARNHIGH2C 3476 /* Voltage PCI-IO High Warn Threshold */ -#define SK_SEN_WARNLOW2C 4664 /* Voltage PCI-IO Low Err Threshold */ -#define SK_SEN_ERRLOW2C 4422 /* Voltage PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */ +#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */ + /* 3300 mVolt */ +#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ + /* * VDD voltage */ -#define SK_SEN_ERRHIGH3 3630 /* Voltage ASIC High Err Threshold */ -#define SK_SEN_WARNHIGH3 3476 /* Voltage ASIC High Warn Threshold */ -#define SK_SEN_WARNLOW3 3146 /* Voltage ASIC Low Err Threshold */ -#define SK_SEN_ERRLOW3 2970 /* Voltage ASIC Low Warn Threshold */ +#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ +#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ +#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ +#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ + +/* + * PHY PLL 3V3 voltage + */ +#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */ +#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */ +#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */ +#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */ /* - * PLC_3V3 voltage - * PHY_PLL_A_3V3 voltage + * VAUX (YUKON only) */ -#define SK_SEN_ERRHIGH4 3630 /* Voltage PMA High Err Threshold */ -#define SK_SEN_WARNHIGH4 3476 /* Voltage PMA High Warn Threshold */ -#define SK_SEN_WARNLOW4 3146 /* Voltage PMA Low Err Threshold */ -#define SK_SEN_ERRLOW4 2970 /* Voltage PMA Low Warn Threshold */ +#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */ +#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */ +#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */ +#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ +#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ +#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ /* - * PHY_2V5 voltage + * PHY 2V5 voltage */ -#define SK_SEN_ERRHIGH5 2750 /* Voltage PHY High Err Threshold */ -#define SK_SEN_WARNHIGH5 2640 /* Voltage PHY High Warn Threshold */ -#define SK_SEN_WARNLOW5 2376 /* Voltage PHY Low Err Threshold */ -#define SK_SEN_ERRLOW5 2222 /* Voltage PHY Low Warn Threshold */ +#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */ +#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */ +#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */ +#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */ /* - * PHY_PLL_B_3V3 voltage + * ASIC Core 1V5 voltage (YUKON only) */ -#define SK_SEN_ERRHIGH6 3630 /* Voltage PMA High Err Threshold */ -#define SK_SEN_WARNHIGH6 3476 /* Voltage PMA High Warn Threshold */ -#define SK_SEN_WARNLOW6 3146 /* Voltage PMA Low Err Threshold */ -#define SK_SEN_ERRLOW6 2970 /* Voltage PMA Low Warn Threshold */ +#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ +#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */ +#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */ +#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */ /* * FAN 1 speed @@ -239,10 +283,17 @@ * error at: 70 % * no upper limit */ -#define SK_SEN_ERRHIGH 20000 /* FAN Speed High Err Threshold */ -#define SK_SEN_WARNHIGH 20000 /* FAN Speed High Warn Threshold */ -#define SK_SEN_WARNLOW 5200 /* FAN Speed Low Err Threshold */ -#define SK_SEN_ERRLOW 4550 /* FAN Speed Low Warn Threshold */ +#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */ +#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */ +#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ +#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ + +/* + * Some Voltages need dynamic thresholds + */ +#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */ +#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */ +#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */ extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); #endif /* n_INC_SKGEI2C_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgeinit.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgeinit.h --- linux.21pre4/drivers/net/sk98lin/h/skgeinit.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgeinit.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skgeinit.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.51 $ - * Date: $Date: 2001/02/09 12:26:38 $ + * Version: $Revision: 1.73 $ + * Date: $Date: 2002/11/15 12:47:25 $ * Purpose: Structures and prototypes for the GE Init Module * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,115 @@ * History: * * $Log: skgeinit.h,v $ + * Revision 1.73 2002/11/15 12:47:25 rschmidt + * Replaced error message SKERR_HWI_E024 for Cable Diagnostic with + * Rx queue error in SkGeStopPort(). + * + * Revision 1.72 2002/11/12 17:08:35 rschmidt + * Added entries for Cable Diagnostic to Port structure + * Added entries GIPciSlot64 and GIPciClock66 in s_GeInit structure + * Added error message for Cable Diagnostic + * Added prototypes for SkGmCableDiagStatus() + * Editorial changes + * + * Revision 1.71 2002/10/21 11:26:10 mkarl + * Changed interface of SkGeInitAssignRamToQueues(). + * + * Revision 1.70 2002/10/14 08:21:32 rschmidt + * Changed type of GICopperType, GIVauxAvail to SK_BOOL + * Added entry PRxOverCnt to Port structure + * Added entry GIYukon32Bit in s_GeInit structure + * Editorial changes + * + * Revision 1.69 2002/10/09 16:57:15 mkarl + * Added some constants and macros for SkGeInitAssignRamToQueues(). + * + * Revision 1.68 2002/09/12 08:58:51 rwahl + * Retrieve counters needed for XMAC errata workarounds directly because + * PNMI returns corrected counter values (e.g. #10620). + * + * Revision 1.67 2002/08/16 14:40:30 rschmidt + * Added entries GIGenesis and GICopperType in s_GeInit structure + * Added prototypes for SkMacHashing() + * Editorial changes + * + * Revision 1.66 2002/08/12 13:27:21 rschmidt + * Added defines for Link speed capabilities + * Added entry PLinkSpeedCap to Port structure + * Added entry GIVauxAvail in s_GeInit structure + * Added prototypes for SkMacPromiscMode() + * Editorial changes + * + * Revision 1.65 2002/08/08 15:46:18 rschmidt + * Added define SK_PHY_ACC_TO for PHY access timeout + * Added define SK_XM_RX_HI_WM for XMAC Rx High Watermark + * Added define SK_MIN_TXQ_SIZE for Min RAM Buffer Tx Queue Size + * Added entry PhyId1 to Port structure + * + * Revision 1.64 2002/07/23 16:02:56 rschmidt + * Added entry GIWolOffs in s_GeInit struct (HW-Bug in YUKON 1st rev.) + * Added prototypes for: SkGePhyRead(), SkGePhyWrite() + * + * Revision 1.63 2002/07/18 08:17:38 rwahl + * Corrected definitions for SK_LSPEED_xxx & SK_LSPEED_STAT_xxx. + * + * Revision 1.62 2002/07/17 18:21:55 rwahl + * Added SK_LSPEED_INDETERMINATED define. + * + * Revision 1.61 2002/07/17 17:16:03 rwahl + * - MacType now member of GIni struct. + * - Struct alignment to 32bit. + * - Editorial change. + * + * Revision 1.60 2002/07/15 18:23:39 rwahl + * Added GeMacFunc to GE Init structure. + * Added prototypes for SkXmUpdateStats(), SkGmUpdateStats(), + * SkXmMacStatistic(), SkGmMacStatistic(), SkXmResetCounter(), + * SkGmResetCounter(), SkXmOverflowStatus(), SkGmOverflowStatus(). + * Added defines for current link speed state. + * Added ERRMSG defintions for MacUpdateStat() & MacStatistics(). + * + * Revision 1.59 2002/07/15 15:40:22 rschmidt + * Added entry PLinkSpeedUsed to Port structure + * Editorial changes + * + * Revision 1.58 2002/06/10 09:36:30 rschmidt + * Editorial changes. + * + * Revision 1.57 2002/06/05 08:18:00 rschmidt + * Corrected alignment in Port Structure + * Added new prototypes for GMAC + * Editorial changes + * + * Revision 1.56 2002/04/25 11:38:12 rschmidt + * Added defines for Link speed values + * Added defines for Loopback parameters for MAC and PHY + * Removed entry PRxCmd from Port structure + * Added entry PLinkSpeed to Port structure + * Added entries GIChipId and GIChipRev to GE Init structure + * Removed entry GIAnyPortAct from GE Init structure + * Added prototypes for: SkMacInit(), SkMacInitPhy(), + * SkMacRxTxDisable(), SkMacSoftRst(), SkMacHardRst(), SkMacIrq(), + * SkMacIrqDisable(), SkMacFlushTxFifo(), SkMacFlushRxFifo(), + * SkMacAutoNegDone(), SkMacAutoNegLipaPhy(), SkMacSetRxTxEn(), + * SkXmPhyRead(), SkXmPhyRead(), SkGmPhyWrite(), SkGmPhyWrite(); + * Removed prototypes for static functions in SkXmac2.c + * Editorial changes + * + * Revision 1.55 2002/02/26 15:24:53 rwahl + * Fix: no link with manual configuration (#10673). The previous fix for + * #10639 was removed. So for RLMT mode = CLS the RLMT may switch to + * misconfigured port. It should not occur for the other RLMT modes. + * + * Revision 1.54 2002/01/18 16:52:52 rwahl + * Editorial corrections. + * + * Revision 1.53 2001/11/20 09:19:58 rwahl + * Reworked bugfix #10639 (no dependency to RLMT mode). + * + * Revision 1.52 2001/10/26 07:52:23 afischer + * Port switching bug in `check local link` mode + * * Revision 1.51 2001/02/09 12:26:38 cgoos * Inserted #ifdef DIAG for half duplex workaround timer. * @@ -130,7 +239,7 @@ * Add GIRamOffs. * * Revision 1.20 1998/10/19 07:28:37 malthoff - * Add prototyp for SkGeInitRamIface(). + * Add prototype for SkGeInitRamIface(). * * Revision 1.19 1998/10/14 14:47:48 malthoff * SK_TIMER should not be defined for Diagnostics. @@ -156,7 +265,7 @@ * Add some error log messages. * * Revision 1.13 1998/10/06 14:13:14 malthoff - * Add prototyp for SkGeLoadLnkSyncCnt(). + * Add prototype for SkGeLoadLnkSyncCnt(). * * Revision 1.12 1998/10/05 11:29:53 malthoff * bug fix: A comment was not closed. @@ -194,7 +303,7 @@ * Revision 1.4 1998/09/03 09:55:31 malthoff * Add constants for parameters Dir and RstMode * when calling SkGeStopPort(). - * Rework the prototyp section. + * Rework the prototype section. * Add Queue Address offsets PRxQOff, PXsQOff, and PXaQOff. * Remove Ioc with IoC. * @@ -208,7 +317,6 @@ * Revision 1.1 1998/07/23 09:50:24 malthoff * Created. * - * ******************************************************************************/ #ifndef __INC_SKGEINIT_H_ @@ -220,53 +328,49 @@ /* defines ********************************************************************/ -/* - * defines for modifying Link LED behaviour (has been used with SkGeLinkLED()) - */ -#define SK_LNK_OFF LED_OFF -#define SK_LNK_ON (LED_ON | LED_BLK_OFF| LED_SYNC_OFF) -#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON) -#define SK_LNK_PERM (LED_ON | LED_BLK_OFF| LED_SYNC_ON) -#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF) - -/* - * defines for parameter 'Mode' when calling SK_HWAC_LINK_LED() - */ -#define SK_LED_OFF LED_OFF -#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF| LED_SYNC_OFF) -#define SK_LED_STANDBY (LED_ON | LED_BLK_ON| LED_SYNC_OFF) +/* modifying Link LED behaviour (used with SkGeLinkLED()) */ +#define SK_LNK_OFF LED_OFF +#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF) +#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON) +#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON) +#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF) + +/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */ +#define SK_LED_OFF LED_OFF +#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF) +#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF) + +/* addressing LED Registers in SkGeXmitLED() */ +#define XMIT_LED_INI 0 +#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI) +#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI) +#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI) -/* - * defines for parameter 'Mode' when calling SkGeXmitLED() - */ +/* parameter 'Mode' when calling SkGeXmitLED() */ #define SK_LED_DIS 0 #define SK_LED_ENA 1 #define SK_LED_TST 2 -/* - * Counter and Timer constants, for a host clock of 62.5 MHz - */ -#define SK_XMIT_DUR 0x002faf08L /* 50 ms */ -#define SK_BLK_DUR 0x01dcd650L /* 500 ms */ +/* Counter and Timer constants, for a host clock of 62.5 MHz */ +#define SK_XMIT_DUR 0x002faf08L /* 50 ms */ +#define SK_BLK_DUR 0x01dcd650L /* 500 ms */ #define SK_DPOLL_DEF 0x00EE6B28L /* 250 ms */ #define SK_DPOLL_MAX 0x00FFFFFFL /* ca. 268ms */ -#define SK_FACT_62 100 /* is given in percent */ -#define SK_FACT_53 85 +#define SK_FACT_62 100 /* is given in percent */ +#define SK_FACT_53 85 -/* - * Timeout values - */ -#define SK_MAC_TO_53 72 /* MAC arbiter timeout */ +/* Timeout values */ +#define SK_MAC_TO_53 72 /* MAC arbiter timeout */ #define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */ #define SK_PKT_TO_MAX 0xffff /* Maximum value */ -#define SK_RI_TO_53 36 /* RAM interface timeout */ +#define SK_RI_TO_53 36 /* RAM interface timeout */ -/* - * RAM Buffer High Pause Threshold values - */ -#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */ +#define SK_PHY_ACC_TO 600000 /* PHY access timeout */ + +/* RAM Buffer High Pause Threshold values */ +#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */ #define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */ #define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */ @@ -274,9 +378,12 @@ #define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ #endif #ifndef SK_BMU_TX_WM -#define SK_BMU_TX_WM 0x600 /* BMU Rx Watermark */ +#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ #endif +/* XMAC II Rx High Watermark */ +#define SK_XM_RX_HI_WM 0x05aa /* 1450 */ + /* XMAC II Tx Threshold */ #define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */ #define SK_XM_THR_SL 0x01fb /* .. for single link adapters */ @@ -284,184 +391,218 @@ #define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */ /* values for GIPortUsage */ -#define SK_RED_LINK 1 /* redundant link usage */ -#define SK_MUL_LINK 2 /* multiple link usage */ +#define SK_RED_LINK 1 /* redundant link usage */ +#define SK_MUL_LINK 2 /* multiple link usage */ #define SK_JUMBO_LINK 3 /* driver uses jumbo frames */ -/* Minimum RAM Buffer Receive Queue Size */ -#define SK_MIN_RXQ_SIZE 16 /* 16 kB */ -/* - * defines for parameter 'Dir' when calling SkGeStopPort() - */ -#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */ +/* Minimum RAM Buffer Rx Queue Size */ +#define SK_MIN_RXQ_SIZE 16 /* 16 kB */ + +/* Minimum RAM Buffer Tx Queue Size */ +#define SK_MIN_TXQ_SIZE 16 /* 16 kB */ + +/* Queue Size units */ +#define QZ_UNITS 0x7 +#define QZ_STEP 8 + +/* Percentage of queue size from whole memory */ +/* 80 % for receive */ +#define RAM_QUOTA_RX 80L +/* 0% for sync transfer */ +#define RAM_QUOTA_SYNC 0L +/* the rest (20%) is taken for async transfer */ + +/* Get the rounded queue size in Bytes in 8k steps */ +#define ROUND_QUEUE_SIZE(SizeInBytes) \ + ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \ + ~(QZ_STEP-1)) + +/* Get the rounded queue size in KBytes in 8k steps */ +#define ROUND_QUEUE_SIZE_KB(Kilobytes) \ + ROUND_QUEUE_SIZE((Kilobytes) * 1024L) + +/* Types of RAM Buffer Queues */ +#define SK_RX_SRAM_Q 1 /* small receive queue */ +#define SK_RX_BRAM_Q 2 /* big receive queue */ +#define SK_TX_RAM_Q 3 /* small or big transmit queue */ + +/* parameter 'Dir' when calling SkGeStopPort() */ +#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */ #define SK_STOP_RX 2 /* Stops the receive path */ -#define SK_STOP_ALL 3 /* Stops rx and tx path, resets the XMAC */ +#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */ -/* - * defines for parameter 'RstMode' when calling SkGeStopPort() - */ +/* parameter 'RstMode' when calling SkGeStopPort() */ #define SK_SOFT_RST 1 /* perform a software reset */ #define SK_HARD_RST 2 /* perform a hardware reset */ -/* - * Define Init Levels - */ -#define SK_INIT_DATA 0 /* Init level 0: init data structures */ -#define SK_INIT_IO 1 /* Init level 1: init with IOs */ -#define SK_INIT_RUN 2 /* Init level 2: init for run time */ - -/* - * Set Link Mode Parameter - */ -#define SK_LMODE_HALF 1 /* Half Duplex Mode */ -#define SK_LMODE_FULL 2 /* Full Duplex Mode */ -#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */ -#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */ -#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */ -#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */ +/* Init Levels */ +#define SK_INIT_DATA 0 /* Init level 0: init data structures */ +#define SK_INIT_IO 1 /* Init level 1: init with IOs */ +#define SK_INIT_RUN 2 /* Init level 2: init for run time */ + +/* Link Mode Parameter */ +#define SK_LMODE_HALF 1 /* Half Duplex Mode */ +#define SK_LMODE_FULL 2 /* Full Duplex Mode */ +#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */ +#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */ +#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */ +#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */ #define SK_LMODE_INDETERMINATED 7 /* Return value for virtual port if - * multiple ports are differently - * configured. + * multiple ports are differently configured. + */ + +/* Auto-negotiation timeout in 100ms granularity */ +#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */ + +/* Auto-negotiation error codes */ +#define SK_AND_OK 0 /* no error */ +#define SK_AND_OTHER 1 /* other error than below */ +#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */ + + +/* Link Speed Capabilities */ +#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */ +#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */ +#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */ +#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */ +#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* Return value for virtual port if + * multiple ports are differently configured. + */ + +/* Link Speed Parameter */ +#define SK_LSPEED_AUTO 1 /* Automatic resolution */ +#define SK_LSPEED_10MBPS 2 /* 10 Mbps */ +#define SK_LSPEED_100MBPS 3 /* 100 Mbps */ +#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */ +#define SK_LSPEED_INDETERMINATED 5 /* Return value for virtual port if + * multiple ports are differently configured. */ -/* - * Autonegotiation timeout in 100ms granularity. - */ -#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */ +/* Link Speed Current State */ +#define SK_LSPEED_STAT_UNKNOWN 1 +#define SK_LSPEED_STAT_10MBPS 2 +#define SK_LSPEED_STAT_100MBPS 3 +#define SK_LSPEED_STAT_1000MBPS 4 +#define SK_LSPEED_STAT_INDETERMINATED 5 /* Return value for virtual port if + * multiple ports are differently configured. + */ -/* - * Define Autonegotiation error codes here - */ -#define SK_AND_OK 0 /* no error */ -#define SK_AND_OTHER 1 /* other error than below */ -#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */ -/* - * Link Capability value - */ -#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */ -#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */ -#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */ -#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */ +/* Link Capability Parameter */ +#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */ +#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */ +#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */ +#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */ #define SK_LMODE_CAP_INDETERMINATED (1<<4) /* Return value for virtual port if - * multiple ports are differently - * configured. + * multiple ports are differently configured. */ -/* - * Link mode current state - */ -#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */ -#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */ -#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */ +/* Link Mode Current State */ +#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */ +#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */ +#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */ #define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by AutoNeg */ -#define SK_LMODE_STAT_AUTOFULL 5 /* Half Duplex Mode obtained by AutoNeg */ +#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by AutoNeg */ #define SK_LMODE_STAT_INDETERMINATED 6 /* Return value for virtual port if - * multiple ports are differently - * configured. + * multiple ports are differently configured. */ -/* - * Set Flow Control Mode Parameter (and capabilities) - */ -#define SK_FLOW_MODE_NONE 1 /* No Flow Control */ -#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */ -#define SK_FLOW_MODE_SYMMETRIC 3 /* Both station may send PAUSE */ -#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both station may send PAUSE or - * just the remote station may send - * PAUSE +/* Flow Control Mode Parameter (and capabilities) */ +#define SK_FLOW_MODE_NONE 1 /* No Flow Control */ +#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */ +#define SK_FLOW_MODE_SYMMETRIC 3 /* Both station may send PAUSE */ +#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both station may send PAUSE or + * just the remote station may send PAUSE */ #define SK_FLOW_MODE_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently - * configured. + * multiple ports are differently configured. */ -/* - * Flow Control Status Parameter - */ -#define SK_FLOW_STAT_NONE 1 /* No Flow Control */ -#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */ -#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */ -#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */ +/* Flow Control Status Parameter */ +#define SK_FLOW_STAT_NONE 1 /* No Flow Control */ +#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */ +#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */ +#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */ #define SK_FLOW_STAT_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently - * configured. + * multiple ports are differently configured. */ -/* - * Master/Slave Mode capabilities - */ -#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */ -#define SK_MS_CAP_MASTER (1<<1) /* This station is master */ -#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */ -#define SK_MS_CAP_INDETERMINATED (1<<3) /* Return value for virtual port if - * multiple ports are differently - * configured. +/* Master/Slave Mode Capabilities */ +#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */ +#define SK_MS_CAP_MASTER (1<<1) /* This station is master */ +#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */ +#define SK_MS_CAP_INDETERMINATED (1<<3) /* Return value for virtual port if + * multiple ports are differently configured. */ -/* - * Set Master/Slave Mode Parameter (and capabilities) - */ -#define SK_MS_MODE_AUTO 1 /* Automatic resolution */ -#define SK_MS_MODE_MASTER 2 /* This station is master */ -#define SK_MS_MODE_SLAVE 3 /* This station is slave */ -#define SK_MS_MODE_INDETERMINATED 4 /* Return value for virtual port if +/* Set Master/Slave Mode Parameter (and capabilities) */ +#define SK_MS_MODE_AUTO 1 /* Automatic resolution */ +#define SK_MS_MODE_MASTER 2 /* This station is master */ +#define SK_MS_MODE_SLAVE 3 /* This station is slave */ +#define SK_MS_MODE_INDETERMINATED 4 /* Return value for virtual port if * multiple ports are differently */ -/* - * Master/Slave Status Parameter - */ -#define SK_MS_STAT_UNSET 1 /* The MS status is never been determ*/ -#define SK_MS_STAT_MASTER 2 /* This station is master */ -#define SK_MS_STAT_SLAVE 3 /* This station is slave */ -#define SK_MS_STAT_FAULT 4 /* MS resolution failed */ +/* Master/Slave Status Parameter */ +#define SK_MS_STAT_UNSET 1 /* The MS status is never been determ*/ +#define SK_MS_STAT_MASTER 2 /* This station is master */ +#define SK_MS_STAT_SLAVE 3 /* This station is slave */ +#define SK_MS_STAT_FAULT 4 /* MS resolution failed */ #define SK_MS_STAT_INDETERMINATED 5 /* Return value for virtual port if * multiple ports are differently */ -/* - * defines for parameter 'Mode' when calling SkXmSetRxCmd() - */ -#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of rx frames */ -#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of rx frames */ -#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of rx f */ -#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of rx f */ -#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error*/ -#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error*/ +/* parameter 'Mode' when calling SkXmSetRxCmd() */ +#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */ +#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */ +#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */ +#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */ +#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */ +#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */ #define SK_BIG_PK_OK_ON (1<<6) /* Don't set rcvError bit for big fr */ #define SK_BIG_PK_OK_OFF (1<<7) /* Set rcvError bit for big frames */ +#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */ +#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */ -/* - * States of PState - */ +/* parameter 'Para' when calling SkMacSetRxTxEn() */ +#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */ +#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */ +#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */ +#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */ +#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */ +#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */ + +/* States of PState */ #define SK_PRT_RESET 0 /* the port is reset */ -#define SK_PRT_STOP 1 /* the port is stopped (similar to sw reset) */ -#define SK_PRT_INIT 2 /* the port is initialized */ -#define SK_PRT_RUN 3 /* the port has an active link */ +#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */ +#define SK_PRT_INIT 2 /* the port is initialized */ +#define SK_PRT_RUN 3 /* the port has an active link */ + +/* Default receive frame limit for Workaround of XMAC Errata */ +#define SK_DEF_RX_WA_LIM SK_CONSTU64(100) + +/* Link Partner Status */ +#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */ +#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */ +#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */ -/* - * Default receive frame limit for Workaround of XMAC Errata - */ -#define SK_DEF_RX_WA_LIM SK_CONSTU64(100) +/* Maximum Restarts before restart is ignored (3Com WA) */ +#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */ -/* - * Define link partner Status - */ -#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */ -#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */ -#define SK_LIPA_AUTO 2 /* Link partner is in autonegotiation state */ +/* Max. Auto-neg. timeouts before link detection in sense mode is reset */ +#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */ -/* - * Define Maximum Restarts before restart is ignored (3com WA) - */ -#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */ +/* structures *****************************************************************/ /* - * define max. autonegotiation timeouts before link detection in sense mode is - * reset. + * MAC specific functions */ -#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */ - -/* structures *****************************************************************/ +typedef struct s_GeMacFunc { + int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); + int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, + SK_U16 StatAddr, SK_U32 *pVal); + int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); + int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, + SK_U16 IStatus, SK_U64 *pVal); +} SK_GEMACFUNC; /* * Port Structure @@ -469,37 +610,35 @@ typedef struct s_GePort { #ifndef SK_DIAG SK_TIMER PWaTimer; /* Workaround Timer */ -#endif - SK_U64 PPrevShorts; /* Previous short Counter checking */ + SK_TIMER HalfDupChkTimer; +#endif /* SK_DIAG */ + SK_U32 PPrevShorts; /* Previous short Counter checking */ + SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */ SK_U64 PPrevRx; /* Previous RxOk Counter checking */ - SK_U64 PPrevFcs; /* Previous FCS Error Counter checking */ SK_U64 PRxLim; /* Previous RxOk Counter checking */ SK_U64 LastOctets; /* For half duplex hang check */ -#ifndef SK_DIAG - SK_TIMER HalfDupChkTimer; -#endif int PLinkResCt; /* Link Restart Counter */ - int PAutoNegTimeOut;/* AutoNegotiation timeout current value */ - int PAutoNegTOCt; /* AutoNeg Timeout Counter */ + int PAutoNegTimeOut;/* Auto-negotiation timeout current value */ + int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */ int PRxQSize; /* Port Rx Queue Size in kB */ - int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */ - int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB*/ + int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */ + int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */ SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */ SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */ SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */ SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */ SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */ SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */ + SK_U32 PRxOverCnt; /* Receive Overflow Counter */ int PRxQOff; /* Rx Queue Address Offset */ int PXsQOff; /* Synchronous Tx Queue Address Offset */ int PXaQOff; /* Asynchronous Tx Queue Address Offset */ int PhyType; /* PHY used on this port */ + SK_U16 PhyId1; /* PHY Id1 on this port */ SK_U16 PhyAddr; /* MDIO/MDC PHY address */ - SK_U16 PRxCmd; /* Port Receive Command Configuration Value */ SK_U16 PIsave; /* Saved Interrupt status word */ SK_U16 PSsave; /* Saved PHY status word */ - SK_U16 Align01; - SK_BOOL PHWLinkUp; /* The hardware Link is up (wireing) */ + SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */ SK_BOOL PState; /* Is port initialized ? */ SK_BOOL PLinkBroken; /* Is Link broken ? */ SK_BOOL PCheckPar; /* Do we check for parity errors ? */ @@ -508,77 +647,102 @@ SK_U8 PLinkModeConf; /* Link Mode configured */ SK_U8 PLinkMode; /* Link Mode currently used */ SK_U8 PLinkModeStatus;/* Link Mode Status */ + SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */ + SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */ + SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */ SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */ SK_U8 PFlowCtrlMode; /* Flow Control Mode */ SK_U8 PFlowCtrlStatus;/* Flow Control Status */ SK_U8 PMSCap; /* Master/Slave Capabilities */ SK_U8 PMSMode; /* Master/Slave Mode */ SK_U8 PMSStatus; /* Master/Slave Status */ - SK_U8 PAutoNegFail; /* Autonegotiation fail flag */ - SK_U8 PLipaAutoNeg; /* Autonegotiation possible with Link Partner */ - SK_U8 Align02; + SK_U8 PAutoNegFail; /* Auto-negotiation fail flag */ + SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */ + SK_U8 PCableLen; /* Cable Length */ + SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */ + SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */ } SK_GEPORT; /* - * Gigabit Ethernet Initalization Struct + * Gigabit Ethernet Initialization Struct * (has to be included in the adapter context) */ typedef struct s_GeInit { + SK_U8 GIPciHwRev; /* PCI HW Revision Number */ + SK_U8 GIChipId; /* Chip Identification Number */ + SK_U8 GIChipRev; /* Chip Revision Number */ + SK_BOOL GIGenesis; /* Genesis adapter ? */ + SK_BOOL GICopperType; /* Copper Type adapter ? */ + SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */ + SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */ + SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */ + SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */ int GIMacsFound; /* Number of MACs found on this adapter */ - int GIPciHwRev; /* PCI HW Revision Number */ - SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */ - int GIRamSize; /* The RAM size of the adapter in kB */ + int GIMacType; /* MAC Type used on this adapter */ int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */ - int GIPortUsage; /* driver port usage: SK_RED_LINK/SK_MUL_LINK */ + int GIPortUsage; /* Driver Port Usage: SK_RED_LINK/SK_MUL_LINK */ + int GILevel; /* Initialization Level completed */ + int GIRamSize; /* The RAM size of the adapter in kB */ + int GIWolOffs; /* WOL Register Offset (HW-Bug in 1st revision) */ + SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */ SK_U32 GIPollTimerVal; /* Descriptor Poll Timer Init Val in clk ticks*/ - int GILevel; /* Initialization Level Completed */ SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */ - SK_BOOL GIAnyPortAct; /* Is True if one or more port is initialized */ - SK_U8 Align01; - SK_U16 Align02; + SK_GEMACFUNC GIFunc; /* MAC depedent functions */ } SK_GEINIT; /* - * Define the error numbers and messages for xmac_ii.c and skgeinit.c + * Error numbers and messages for skxmac2.c and skgeinit.c */ -#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT) -#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters" -#define SKERR_HWI_E002 (SKERR_HWI_E001+1) -#define SKERR_HWI_E002MSG "SkGeInit() Level 1 call missing" -#define SKERR_HWI_E003 (SKERR_HWI_E002+1) -#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level" -#define SKERR_HWI_E004 (SKERR_HWI_E003+1) -#define SKERR_HWI_E004MSG "SkGeInitPort() Queue size illegal configured" -#define SKERR_HWI_E005 (SKERR_HWI_E004+1) -#define SKERR_HWI_E005MSG "SkGeInitPort() cannot init running ports" -#define SKERR_HWI_E006 (SKERR_HWI_E005+1) -#define SKERR_HWI_E006MSG "SkGeXmInit(): PState does not match HW state" -#define SKERR_HWI_E007 (SKERR_HWI_E006+1) -#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode" -#define SKERR_HWI_E008 (SKERR_HWI_E007+1) -#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode" -#define SKERR_HWI_E009 (SKERR_HWI_E008+1) -#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero" -#define SKERR_HWI_E010 (SKERR_HWI_E009+1) -#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters" -#define SKERR_HWI_E011 (SKERR_HWI_E010+1) -#define SKERR_HWI_E011MSG "SkGeInitPort() Receive Queue Size to small" -#define SKERR_HWI_E012 (SKERR_HWI_E011+1) -#define SKERR_HWI_E012MSG "SkGeInitPort() invalid Queue Size specified" -#define SKERR_HWI_E013 (SKERR_HWI_E012+1) -#define SKERR_HWI_E013MSG "SkGeInitPort() cfg changed for running queue" -#define SKERR_HWI_E014 (SKERR_HWI_E013+1) -#define SKERR_HWI_E014MSG "SkGeInitPort() unknown GIPortUsage specified" -#define SKERR_HWI_E015 (SKERR_HWI_E014+1) -#define SKERR_HWI_E015MSG "Illegal Link mode parameter" -#define SKERR_HWI_E016 (SKERR_HWI_E015+1) -#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter" -#define SKERR_HWI_E017 (SKERR_HWI_E016+1) -#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal" -#define SKERR_HWI_E018 (SKERR_HWI_E017+1) -#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate" -#define SKERR_HWI_E019 (SKERR_HWI_E018+1) -#define SKERR_HWI_E019MSG "" +#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT) +#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters" +#define SKERR_HWI_E002 (SKERR_HWI_E001+1) +#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing" +#define SKERR_HWI_E003 (SKERR_HWI_E002+1) +#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level" +#define SKERR_HWI_E004 (SKERR_HWI_E003+1) +#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured" +#define SKERR_HWI_E005 (SKERR_HWI_E004+1) +#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports" +#define SKERR_HWI_E006 (SKERR_HWI_E005+1) +#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state" +#define SKERR_HWI_E007 (SKERR_HWI_E006+1) +#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode" +#define SKERR_HWI_E008 (SKERR_HWI_E007+1) +#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode" +#define SKERR_HWI_E009 (SKERR_HWI_E008+1) +#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero" +#define SKERR_HWI_E010 (SKERR_HWI_E009+1) +#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters" +#define SKERR_HWI_E011 (SKERR_HWI_E010+1) +#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size to small" +#define SKERR_HWI_E012 (SKERR_HWI_E011+1) +#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified" +#define SKERR_HWI_E013 (SKERR_HWI_E012+1) +#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue" +#define SKERR_HWI_E014 (SKERR_HWI_E013+1) +#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified" +#define SKERR_HWI_E015 (SKERR_HWI_E014+1) +#define SKERR_HWI_E015MSG "Illegal Link mode parameter" +#define SKERR_HWI_E016 (SKERR_HWI_E015+1) +#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter" +#define SKERR_HWI_E017 (SKERR_HWI_E016+1) +#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal" +#define SKERR_HWI_E018 (SKERR_HWI_E017+1) +#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)" +#define SKERR_HWI_E019 (SKERR_HWI_E018+1) +#define SKERR_HWI_E019MSG "Illegal Speed parameter" +#define SKERR_HWI_E020 (SKERR_HWI_E019+1) +#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter" +#define SKERR_HWI_E021 (SKERR_HWI_E020+1) +#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter" +#define SKERR_HWI_E022 (SKERR_HWI_E021+1) +#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address" +#define SKERR_HWI_E023 (SKERR_HWI_E022+1) +#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size to small" +#define SKERR_HWI_E024 (SKERR_HWI_E023+1) +#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)" +#define SKERR_HWI_E025 (SKERR_HWI_E024+1) +#define SKERR_HWI_E025MSG "" /* function prototypes ********************************************************/ @@ -588,146 +752,301 @@ * public functions in skgeinit.c */ extern void SkGePollRxD( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_BOOL PollRxD); + SK_BOOL PollRxD); extern void SkGePollTxD( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_BOOL PollTxD); + SK_BOOL PollTxD); extern void SkGeYellowLED( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int State); extern int SkGeCfgSync( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_U32 IntTime, - SK_U32 LimCount, + SK_U32 IntTime, + SK_U32 LimCount, int SyncMode); extern void SkGeLoadLnkSyncCnt( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_U32 CntVal); + SK_U32 CntVal); extern void SkGeStopPort( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port, int Dir, int RstMode); extern int SkGeInit( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Level); extern void SkGeDeInit( - SK_AC *pAC, - SK_IOC IoC); + SK_AC *pAC, + SK_IOC IoC); extern int SkGeInitPort( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port); extern void SkGeXmitLED( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Led, int Mode); extern void SkGeInitRamIface( - SK_AC *pAC, - SK_IOC IoC); + SK_AC *pAC, + SK_IOC IoC); + +extern int SkGeInitAssignRamToQueues( + SK_AC *pAC, + int ActivePort, + SK_BOOL DualNet); /* * public functions in skxmac2.c */ -extern void SkXmSetRxCmd( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Mode); +extern void SkMacRxTxDisable( + SK_AC *pAC, + SK_IOC IoC, + int Port); -extern void SkXmClrExactAddr( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacSoftRst( + SK_AC *pAC, + SK_IOC IoC, + int Port); + +extern void SkMacHardRst( + SK_AC *pAC, + SK_IOC IoC, + int Port); + +extern void SkXmInitMac( + SK_AC *pAC, + SK_IOC IoC, + int Port); + +extern void SkGmInitMac( + SK_AC *pAC, + SK_IOC IoC, + int Port); + +extern void SkMacInitPhy( + SK_AC *pAC, + SK_IOC IoC, int Port, - int StartNum, - int StopNum); + SK_BOOL DoLoop); -extern void SkXmFlushTxFifo( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacIrqDisable( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern void SkXmFlushRxFifo( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacFlushTxFifo( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern void SkXmSoftRst( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacFlushRxFifo( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern void SkXmHardRst( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacIrq( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern void SkXmInitMac( - SK_AC *pAC, - SK_IOC IoC, +extern int SkMacAutoNegDone( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern void SkXmInitDupMd( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacAutoNegLipaPhy( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_U16 IStatus); + +extern void SkMacSetRxTxEn( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Para); + +extern int SkMacRxTxEnable( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern void SkXmInitPauseMd( - SK_AC *pAC, - SK_IOC IoC, +extern void SkMacPromiscMode( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); + +extern void SkMacHashing( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); + +extern void SkXmPhyRead( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 *pVal); + +extern void SkXmPhyWrite( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 Val); + +extern void SkGmPhyRead( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 *pVal); + +extern void SkGmPhyWrite( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 Val); + +extern void SkGePhyRead( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 *pVal); + +extern void SkGePhyWrite( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 Val); + +extern void SkXmClrExactAddr( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int StartNum, + int StopNum); + +extern void SkXmInitDupMd( + SK_AC *pAC, + SK_IOC IoC, int Port); -extern int SkXmAutoNegDone( - SK_AC *pAC, - SK_IOC IoC, +extern void SkXmInitPauseMd( + SK_AC *pAC, + SK_IOC IoC, int Port); extern void SkXmAutoNegLipaXmac( - SK_AC *pAC, - SK_IOC IoC, + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_U16 IStatus); + SK_U16 IStatus); -extern void SkXmAutoNegLipaBcom( - SK_AC *pAC, - SK_IOC IoC, +extern int SkXmUpdateStats( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port); + +extern int SkGmUpdateStats( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port); + +extern int SkXmMacStatistic( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port, + SK_U16 StatAddr, + SK_U32 *pVal); + +extern int SkGmMacStatistic( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port, + SK_U16 StatAddr, + SK_U32 *pVal); + +extern int SkXmResetCounter( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port); + +extern int SkGmResetCounter( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port); + +extern int SkXmOverflowStatus( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port, + SK_U16 IStatus, + SK_U64 *pStatus); + +extern int SkGmOverflowStatus( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port, + SK_U16 MacStatus, + SK_U64 *pStatus); + +extern int SkGmCableDiagStatus( + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_U16 IStatus); + SK_BOOL StartTest); -extern void SkXmAutoNegLipaLone( - SK_AC *pAC, - SK_IOC IoC, +#ifdef SK_DIAG +extern void SkMacSetRxCmd( + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_U16 IStatus); - -extern void SkXmIrq( - SK_AC *pAC, - SK_IOC IoC, + int Mode); +extern void SkMacCrcGener( + SK_AC *pAC, + SK_IOC IoC, int Port, - SK_U16 IStatus); + SK_BOOL Enable); +extern void SkMacTimeStamp( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); +extern void SkXmSendCont( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); +#endif /* SK_DIAG */ #else /* SK_KR_PROTO */ @@ -745,22 +1064,53 @@ extern int SkGeInitPort(); extern void SkGeXmitLED(); extern void SkGeInitRamIface(); +extern int SkGeInitAssignRamToQueues(); /* * public functions in skxmac2.c */ -extern void SkXmSetRxCmd(); -extern void SkXmClrExactAddr(); -extern void SkXmFlushTxFifo(); -extern void SkXmFlushRxFifo(); -extern void SkXmSoftRst(); -extern void SkXmHardRst(); +extern void SkMacRxTxDisable(); +extern void SkMacSoftRst(); +extern void SkMacHardRst(); +extern void SkMacInitPhy(); +extern int SkMacRxTxEnable(); +extern void SkMacPromiscMode(); +extern void SkMacHashing(); +extern void SkMacIrqDisable(); +extern void SkMacFlushTxFifo(); +extern void SkMacFlushRxFifo(); +extern void SkMacIrq(); +extern int SkMacAutoNegDone(); +extern void SkMacAutoNegLipaPhy(); +extern void SkMacSetRxTxEn(); +extern void SkGePhyRead(); +extern void SkGePhyWrite(); extern void SkXmInitMac(); +extern void SkXmPhyRead(); +extern void SkXmPhyWrite(); +extern void SkGmInitMac(); +extern void SkGmPhyRead(); +extern void SkGmPhyWrite(); +extern void SkXmClrExactAddr(); extern void SkXmInitDupMd(); extern void SkXmInitPauseMd(); -extern int SkXmAutoNegDone(); -extern void SkXmAutoNegLipa(); -extern void SkXmIrq(); +extern void SkXmAutoNegLipaXmac(); +extern int SkXmUpdateStats(); +extern int SkGmUpdateStats(); +extern int SkXmMacStatistic(); +extern int SkGmMacStatistic(); +extern int SkXmResetCounter(); +extern int SkGmResetCounter(); +extern int SkXmOverflowStatus(); +extern int SkGmOverflowStatus(); +extern int SkGmCableDiagStatus(); + +#ifdef SK_DIAG +extern void SkMacSetRxCmd(); +extern void SkMacCrcGener(); +extern void SkMacTimeStamp(); +extern void SkXmSendCont(); +#endif /* SK_DIAG */ #endif /* SK_KR_PROTO */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgepnm2.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgepnm2.h --- linux.21pre4/drivers/net/sk98lin/h/skgepnm2.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgepnm2.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skgepnm2.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.30 $ - * Date: $Date: 2001/02/06 10:03:41 $ + * Version: $Revision: 1.34 $ + * Date: $Date: 2002/12/16 09:05:18 $ * Purpose: Defines for Private Network Management Interface * ****************************************************************************/ @@ -26,6 +26,21 @@ * History: * * $Log: skgepnm2.h,v $ + * Revision 1.34 2002/12/16 09:05:18 tschilli + * Code for VCT handling added. + * + * Revision 1.33 2002/09/10 09:00:03 rwahl + * Adapted boolean definitions according sktypes. + * + * Revision 1.32 2002/08/09 09:47:01 rwahl + * Added write-only flag to oid access defines. + * Editorial changes. + * + * Revision 1.31 2002/07/17 19:23:18 rwahl + * - Replaced MAC counter definitions by enumeration. + * - Added definition SK_PNMI_MAC_TYPES. + * - Added chipset defnition for Yukon. + * * Revision 1.30 2001/02/06 10:03:41 mkunz * - Pnmi V4 dual net support added. Interface functions and macros extended * - Vpd bug fixed @@ -140,26 +155,19 @@ #ifndef _SKGEPNM2_H_ #define _SKGEPNM2_H_ -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE !(FALSE) -#endif - /* * General definitions */ -#define SK_PNMI_CHIPSET 1 /* XMAC11800FP */ +#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */ +#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */ #define SK_PNMI_BUS_PCI 1 /* PCI bus*/ /* * Actions */ -#define SK_PNMI_ACT_IDLE 1 -#define SK_PNMI_ACT_RESET 2 +#define SK_PNMI_ACT_IDLE 1 +#define SK_PNMI_ACT_RESET 2 #define SK_PNMI_ACT_SELFTEST 3 #define SK_PNMI_ACT_RESETCNT 4 @@ -170,13 +178,13 @@ #define SK_PNMI_VPD_RW 1 #define SK_PNMI_VPD_RO 2 -#define SK_PNMI_VPD_OK 0 +#define SK_PNMI_VPD_OK 0 #define SK_PNMI_VPD_NOTFOUND 1 -#define SK_PNMI_VPD_CUT 2 -#define SK_PNMI_VPD_TIMEOUT 3 -#define SK_PNMI_VPD_FULL 4 -#define SK_PNMI_VPD_NOWRITE 5 -#define SK_PNMI_VPD_FATAL 6 +#define SK_PNMI_VPD_CUT 2 +#define SK_PNMI_VPD_TIMEOUT 3 +#define SK_PNMI_VPD_FULL 4 +#define SK_PNMI_VPD_NOWRITE 5 +#define SK_PNMI_VPD_FATAL 6 #define SK_PNMI_VPD_IGNORE 0 #define SK_PNMI_VPD_CREATE 1 @@ -188,124 +196,137 @@ */ #define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */ + +/* + * VCT internal status values + */ +#define SK_PNMI_VCT_PENDING 32 +#define SK_PNMI_VCT_TEST_DONE 64 +#define SK_PNMI_VCT_LINK 128 + /* * Internal table definitions */ #define SK_PNMI_GET 0 -#define SK_PNMI_PRESET 1 +#define SK_PNMI_PRESET 1 #define SK_PNMI_SET 2 #define SK_PNMI_RO 0 #define SK_PNMI_RW 1 +#define SK_PNMI_WO 2 typedef struct s_OidTabEntry { - SK_U32 Id; - SK_U32 InstanceNo; + SK_U32 Id; + SK_U32 InstanceNo; unsigned int StructSize; unsigned int Offset; - int Access; - int (* Func)(SK_AC *pAc, SK_IOC pIo, int action, - SK_U32 Id, char* pBuf, unsigned int* pLen, - SK_U32 Instance, unsigned int TableIndex, - SK_U32 NetNumber); - SK_U16 Param; + int Access; + int (* Func)(SK_AC *pAc, SK_IOC pIo, int action, + SK_U32 Id, char* pBuf, unsigned int* pLen, + SK_U32 Instance, unsigned int TableIndex, + SK_U32 NetNumber); + SK_U16 Param; } SK_PNMI_TAB_ENTRY; /* * Trap lengths */ -#define SK_PNMI_TRAP_SIMPLE_LEN 17 +#define SK_PNMI_TRAP_SIMPLE_LEN 17 #define SK_PNMI_TRAP_SENSOR_LEN_BASE 46 #define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23 -#define SK_PNMI_TRAP_RLMT_PORT_LEN 23 - +#define SK_PNMI_TRAP_RLMT_PORT_LEN 23 /* - * MAC statistic data structures - * Only for the first 64 counters: the number relates to the bit in the - * XMAC overflow status register - */ -#define SK_PNMI_HTX 0 -#define SK_PNMI_HTX_OCTET 1 -#define SK_PNMI_HTX_OCTETHIGH 1 -#define SK_PNMI_HTX_OCTETLOW 2 -#define SK_PNMI_HTX_BROADCAST 3 -#define SK_PNMI_HTX_MULTICAST 4 -#define SK_PNMI_HTX_UNICAST 5 -#define SK_PNMI_HTX_LONGFRAMES 6 -#define SK_PNMI_HTX_BURST 7 -#define SK_PNMI_HTX_PMACC 8 -#define SK_PNMI_HTX_MACC 9 -#define SK_PNMI_HTX_SINGLE_COL 10 -#define SK_PNMI_HTX_MULTI_COL 11 -#define SK_PNMI_HTX_EXCESS_COL 12 -#define SK_PNMI_HTX_LATE_COL 13 -#define SK_PNMI_HTX_DEFFERAL 14 -#define SK_PNMI_HTX_EXCESS_DEF 15 -#define SK_PNMI_HTX_UNDERRUN 16 -#define SK_PNMI_HTX_CARRIER 17 -#define SK_PNMI_HTX_UTILUNDER 18 -#define SK_PNMI_HTX_UTILOVER 19 -#define SK_PNMI_HTX_64 20 -#define SK_PNMI_HTX_127 21 -#define SK_PNMI_HTX_255 22 -#define SK_PNMI_HTX_511 23 -#define SK_PNMI_HTX_1023 24 -#define SK_PNMI_HTX_MAX 25 -#define SK_PNMI_HTX_RESERVED26 26 -#define SK_PNMI_HTX_RESERVED27 27 -#define SK_PNMI_HTX_RESERVED28 28 -#define SK_PNMI_HTX_RESERVED29 29 -#define SK_PNMI_HTX_RESERVED30 30 -#define SK_PNMI_HTX_RESERVED31 31 -#define SK_PNMI_HRX (32 + 0) -#define SK_PNMI_HRX_OCTET (32 + 1) -#define SK_PNMI_HRX_OCTETHIGH (32 + 1) -#define SK_PNMI_HRX_OCTETLOW (32 + 2) -#define SK_PNMI_HRX_BROADCAST (32 + 3) -#define SK_PNMI_HRX_MULTICAST (32 + 4) -#define SK_PNMI_HRX_UNICAST (32 + 5) -#define SK_PNMI_HRX_PMACC (32 + 6) -#define SK_PNMI_HRX_MACC (32 + 7) -#define SK_PNMI_HRX_PMACC_ERR (32 + 8) -#define SK_PNMI_HRX_MACC_UNKWN (32 + 9) -#define SK_PNMI_HRX_BURST (32 + 10) -#define SK_PNMI_HRX_MISSED (32 + 11) -#define SK_PNMI_HRX_FRAMING (32 + 12) -#define SK_PNMI_HRX_OVERFLOW (32 + 13) -#define SK_PNMI_HRX_JABBER (32 + 14) -#define SK_PNMI_HRX_CARRIER (32 + 15) -#define SK_PNMI_HRX_IRLENGTH (32 + 16) -#define SK_PNMI_HRX_SYMBOL (32 + 17) -#define SK_PNMI_HRX_SHORTS (32 + 18) -#define SK_PNMI_HRX_RUNT (32 + 19) -#define SK_PNMI_HRX_TOO_LONG (32 + 20) -#define SK_PNMI_HRX_FCS (32 + 21) -#define SK_PNMI_HRX_RESERVED22 (32 + 22) -#define SK_PNMI_HRX_CEXT (32 + 23) -#define SK_PNMI_HRX_UTILUNDER (32 + 24) -#define SK_PNMI_HRX_UTILOVER (32 + 25) -#define SK_PNMI_HRX_64 (32 + 26) -#define SK_PNMI_HRX_127 (32 + 27) -#define SK_PNMI_HRX_255 (32 + 28) -#define SK_PNMI_HRX_511 (32 + 29) -#define SK_PNMI_HRX_1023 (32 + 30) -#define SK_PNMI_HRX_MAX (32 + 31) - -#define SK_PNMI_HTX_SYNC 64 -#define SK_PNMI_HTX_SYNC_OCTET 65 - -#define SK_PNMI_HRX_LONGFRAMES 66 + * Number of MAC types supported + */ +#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1) -#define SK_PNMI_MAX_IDX (SK_PNMI_CNT_NO) +/* + * MAC statistic data list (overall set for MAC types used) + */ +enum SK_MACSTATS { + SK_PNMI_HTX = 0, + SK_PNMI_HTX_OCTET, + SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET, + SK_PNMI_HTX_OCTETLOW, + SK_PNMI_HTX_BROADCAST, + SK_PNMI_HTX_MULTICAST, + SK_PNMI_HTX_UNICAST, + SK_PNMI_HTX_BURST, + SK_PNMI_HTX_PMACC, + SK_PNMI_HTX_MACC, + SK_PNMI_HTX_COL, + SK_PNMI_HTX_SINGLE_COL, + SK_PNMI_HTX_MULTI_COL, + SK_PNMI_HTX_EXCESS_COL, + SK_PNMI_HTX_LATE_COL, + SK_PNMI_HTX_DEFFERAL, + SK_PNMI_HTX_EXCESS_DEF, + SK_PNMI_HTX_UNDERRUN, + SK_PNMI_HTX_CARRIER, + SK_PNMI_HTX_UTILUNDER, + SK_PNMI_HTX_UTILOVER, + SK_PNMI_HTX_64, + SK_PNMI_HTX_127, + SK_PNMI_HTX_255, + SK_PNMI_HTX_511, + SK_PNMI_HTX_1023, + SK_PNMI_HTX_MAX, + SK_PNMI_HTX_LONGFRAMES, + SK_PNMI_HTX_SYNC, + SK_PNMI_HTX_SYNC_OCTET, + SK_PNMI_HTX_RESERVED, + + SK_PNMI_HRX, + SK_PNMI_HRX_OCTET, + SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET, + SK_PNMI_HRX_OCTETLOW, + SK_PNMI_HRX_BADOCTET, + SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET, + SK_PNMI_HRX_BADOCTETLOW, + SK_PNMI_HRX_BROADCAST, + SK_PNMI_HRX_MULTICAST, + SK_PNMI_HRX_UNICAST, + SK_PNMI_HRX_PMACC, + SK_PNMI_HRX_MACC, + SK_PNMI_HRX_PMACC_ERR, + SK_PNMI_HRX_MACC_UNKWN, + SK_PNMI_HRX_BURST, + SK_PNMI_HRX_MISSED, + SK_PNMI_HRX_FRAMING, + SK_PNMI_HRX_UNDERSIZE, + SK_PNMI_HRX_OVERFLOW, + SK_PNMI_HRX_JABBER, + SK_PNMI_HRX_CARRIER, + SK_PNMI_HRX_IRLENGTH, + SK_PNMI_HRX_SYMBOL, + SK_PNMI_HRX_SHORTS, + SK_PNMI_HRX_RUNT, + SK_PNMI_HRX_TOO_LONG, + SK_PNMI_HRX_FCS, + SK_PNMI_HRX_CEXT, + SK_PNMI_HRX_UTILUNDER, + SK_PNMI_HRX_UTILOVER, + SK_PNMI_HRX_64, + SK_PNMI_HRX_127, + SK_PNMI_HRX_255, + SK_PNMI_HRX_511, + SK_PNMI_HRX_1023, + SK_PNMI_HRX_MAX, + SK_PNMI_HRX_LONGFRAMES, + + SK_PNMI_HRX_RESERVED, + + SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */ +}; /* * MAC specific data */ typedef struct s_PnmiStatAddr { - SK_BOOL GetOffset; /* TRUE: Call GetStatVal function */ - SK_U16 Param; /* XMAC register containing value */ + SK_U16 Reg; /* MAC register containing the value */ + SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/ } SK_PNMI_STATADDR; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgepnmi.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgepnmi.h --- linux.21pre4/drivers/net/sk98lin/h/skgepnmi.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgepnmi.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skgepnmi.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.48 $ - * Date: $Date: 2001/02/23 14:34:24 $ + * Version: $Revision: 1.59 $ + * Date: $Date: 2002/12/16 14:03:50 $ * Purpose: Defines for Private Network Management Interface * ****************************************************************************/ @@ -26,6 +26,43 @@ * History: * * $Log: skgepnmi.h,v $ + * Revision 1.59 2002/12/16 14:03:50 tschilli + * New defines for VCT added. + * + * Revision 1.58 2002/12/16 09:04:59 tschilli + * Code for VCT handling added. + * + * Revision 1.57 2002/09/26 12:41:05 tschilli + * SK_PNMI_PORT BufPort entry in struct SK_PNMI added. + * + * Revision 1.56 2002/08/16 11:10:41 rwahl + * - Replaced c++ comment. + * + * Revision 1.55 2002/08/09 15:40:21 rwahl + * Editorial change (renamed ConfSpeedCap). + * + * Revision 1.54 2002/08/09 11:06:07 rwahl + * Added OID_SKGE_SPEED_CAP. + * + * Revision 1.53 2002/08/09 09:45:28 rwahl + * Added support for NDIS OID_PNP_xxx. + * Editorial changes. + * + * Revision 1.52 2002/08/06 17:54:07 rwahl + * - Added speed cap to PNMI config struct. + * + * Revision 1.51 2002/07/17 19:19:26 rwahl + * - Added OID_SKGE_SPEED_MODE and OID_SKGE_SPEED_STATUS. + * - Added SK_PNMI_CNT_RX_PMACC_ERR() & SK_PNMI_CNT_RX_LONGFRAMES(). + * - Added speed mode & status to PNMI config struct. + * - Editorial changes. + * + * Revision 1.50 2002/05/22 08:59:37 rwahl + * Added string definitions for error msgs. + * + * Revision 1.49 2001/11/20 09:23:50 rwahl + * - pnmi struct: reordered and aligned to 32bit. + * * Revision 1.48 2001/02/23 14:34:24 mkunz * Changed macro PHYS2INST. Added pAC to Interface * @@ -233,12 +270,14 @@ #define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */ #define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets 1 = single net; 2 = dual net */ +#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */ + /* * Return values */ -#define SK_PNMI_ERR_OK 0 -#define SK_PNMI_ERR_GENERAL 1 +#define SK_PNMI_ERR_OK 0 +#define SK_PNMI_ERR_GENERAL 1 #define SK_PNMI_ERR_TOO_SHORT 2 #define SK_PNMI_ERR_BAD_VALUE 3 #define SK_PNMI_ERR_READ_ONLY 4 @@ -290,11 +329,11 @@ */ #ifndef _NDIS_ /* Check, whether NDIS already included OIDs */ -#define OID_GEN_XMIT_OK 0x00020101 -#define OID_GEN_RCV_OK 0x00020102 -#define OID_GEN_XMIT_ERROR 0x00020103 -#define OID_GEN_RCV_ERROR 0x00020104 -#define OID_GEN_RCV_NO_BUFFER 0x00020105 +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 /* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */ #define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 @@ -303,211 +342,256 @@ /* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */ #define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 /* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */ -#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 /* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */ #define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A /* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */ #define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_RCV_CRC_ERROR 0x0002020D #define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -/* #define OID_802_3_MULTICAST_LIST 0x01010103 */ +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +/* #define OID_802_3_MULTICAST_LIST 0x01010103 */ /* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */ -/* #define OID_802_3_MAC_OPTIONS 0x01010105 */ +/* #define OID_802_3_MAC_OPTIONS 0x01010105 */ #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 #define OID_802_3_XMIT_ONE_COLLISION 0x01020102 #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_DEFERRED 0x01020201 #define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 #define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 #define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 +/* + * PnP and PM OIDs + */ +#ifdef SK_POWER_MGMT +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 +#endif /* SK_POWER_MGMT */ + #endif /* _NDIS_ */ -#define OID_SKGE_MDB_VERSION 0xFF010100 -#define OID_SKGE_SUPPORTED_LIST 0xFF010101 -#define OID_SKGE_VPD_FREE_BYTES 0xFF010102 -#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103 -#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104 -#define OID_SKGE_VPD_KEY 0xFF010105 -#define OID_SKGE_VPD_VALUE 0xFF010106 -#define OID_SKGE_VPD_ACCESS 0xFF010107 -#define OID_SKGE_VPD_ACTION 0xFF010108 +#define OID_SKGE_MDB_VERSION 0xFF010100 +#define OID_SKGE_SUPPORTED_LIST 0xFF010101 +#define OID_SKGE_VPD_FREE_BYTES 0xFF010102 +#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103 +#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104 +#define OID_SKGE_VPD_KEY 0xFF010105 +#define OID_SKGE_VPD_VALUE 0xFF010106 +#define OID_SKGE_VPD_ACCESS 0xFF010107 +#define OID_SKGE_VPD_ACTION 0xFF010108 -#define OID_SKGE_PORT_NUMBER 0xFF010110 -#define OID_SKGE_DEVICE_TYPE 0xFF010111 -#define OID_SKGE_DRIVER_DESCR 0xFF010112 -#define OID_SKGE_DRIVER_VERSION 0xFF010113 -#define OID_SKGE_HW_DESCR 0xFF010114 -#define OID_SKGE_HW_VERSION 0xFF010115 -#define OID_SKGE_CHIPSET 0xFF010116 -#define OID_SKGE_ACTION 0xFF010117 -#define OID_SKGE_RESULT 0xFF010118 -#define OID_SKGE_BUS_TYPE 0xFF010119 -#define OID_SKGE_BUS_SPEED 0xFF01011A -#define OID_SKGE_BUS_WIDTH 0xFF01011B - -/*#define OID_SKGE_MULTICAST_LIST 0xFF01011C*/ - -#define OID_SKGE_SENSOR_NUMBER 0xFF020100 -#define OID_SKGE_SENSOR_INDEX 0xFF020101 -#define OID_SKGE_SENSOR_DESCR 0xFF020102 -#define OID_SKGE_SENSOR_TYPE 0xFF020103 -#define OID_SKGE_SENSOR_VALUE 0xFF020104 +#define OID_SKGE_PORT_NUMBER 0xFF010110 +#define OID_SKGE_DEVICE_TYPE 0xFF010111 +#define OID_SKGE_DRIVER_DESCR 0xFF010112 +#define OID_SKGE_DRIVER_VERSION 0xFF010113 +#define OID_SKGE_HW_DESCR 0xFF010114 +#define OID_SKGE_HW_VERSION 0xFF010115 +#define OID_SKGE_CHIPSET 0xFF010116 +#define OID_SKGE_ACTION 0xFF010117 +#define OID_SKGE_RESULT 0xFF010118 +#define OID_SKGE_BUS_TYPE 0xFF010119 +#define OID_SKGE_BUS_SPEED 0xFF01011A +#define OID_SKGE_BUS_WIDTH 0xFF01011B +/* 0xFF01011C unused */ +#define OID_SKGE_DIAG_ACTION 0xFF01011D +#define OID_SKGE_DIAG_RESULT 0xFF01011E +#define OID_SKGE_MTU 0xFF01011F +#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120 +#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121 +#define OID_SKGE_PMD 0xFF010122 +#define OID_SKGE_CONNECTOR 0xFF010123 +#define OID_SKGE_LINK_CAP 0xFF010124 +#define OID_SKGE_LINK_MODE 0xFF010125 +#define OID_SKGE_LINK_MODE_STATUS 0xFF010126 +#define OID_SKGE_LINK_STATUS 0xFF010127 +#define OID_SKGE_FLOWCTRL_CAP 0xFF010128 +#define OID_SKGE_FLOWCTRL_MODE 0xFF010129 +#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A +#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B +#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C +#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D +#define OID_SKGE_MULTICAST_LIST 0xFF01012E +#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F + +#define OID_SKGE_TRAP 0xFF010130 +#define OID_SKGE_TRAP_NUMBER 0xFF010131 + +#define OID_SKGE_RLMT_MODE 0xFF010140 +#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141 +#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142 +#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143 +#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160 + +#define OID_SKGE_SPEED_CAP 0xFF010170 +#define OID_SKGE_SPEED_MODE 0xFF010171 +#define OID_SKGE_SPEED_STATUS 0xFF010172 + +#define OID_SKGE_SENSOR_NUMBER 0xFF020100 +#define OID_SKGE_SENSOR_INDEX 0xFF020101 +#define OID_SKGE_SENSOR_DESCR 0xFF020102 +#define OID_SKGE_SENSOR_TYPE 0xFF020103 +#define OID_SKGE_SENSOR_VALUE 0xFF020104 #define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105 #define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106 #define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107 #define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108 -#define OID_SKGE_SENSOR_STATUS 0xFF020109 -#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A -#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B -#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C -#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D +#define OID_SKGE_SENSOR_STATUS 0xFF020109 +#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A +#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B +#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C +#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D -#define OID_SKGE_CHKSM_NUMBER 0xFF020110 -#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111 +#define OID_SKGE_CHKSM_NUMBER 0xFF020110 +#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111 #define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112 -#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113 -#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114 +#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113 +#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114 #define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115 -#define OID_SKGE_STAT_TX 0xFF020120 -#define OID_SKGE_STAT_TX_OCTETS 0xFF020121 -#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122 -#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123 -#define OID_SKGE_STAT_TX_UNICAST 0xFF020124 -#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125 -#define OID_SKGE_STAT_TX_BURST 0xFF020126 -#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127 -#define OID_SKGE_STAT_TX_FLOWC 0xFF020128 -#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129 -#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A -#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B -#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C -#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D -#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E -#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F -#define OID_SKGE_STAT_TX_CARRIER 0xFF020130 +#define OID_SKGE_STAT_TX 0xFF020120 +#define OID_SKGE_STAT_TX_OCTETS 0xFF020121 +#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122 +#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123 +#define OID_SKGE_STAT_TX_UNICAST 0xFF020124 +#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125 +#define OID_SKGE_STAT_TX_BURST 0xFF020126 +#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127 +#define OID_SKGE_STAT_TX_FLOWC 0xFF020128 +#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129 +#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A +#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B +#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C +#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D +#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E +#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F +#define OID_SKGE_STAT_TX_CARRIER 0xFF020130 /* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */ -#define OID_SKGE_STAT_TX_64 0xFF020132 -#define OID_SKGE_STAT_TX_127 0xFF020133 -#define OID_SKGE_STAT_TX_255 0xFF020134 -#define OID_SKGE_STAT_TX_511 0xFF020135 -#define OID_SKGE_STAT_TX_1023 0xFF020136 -#define OID_SKGE_STAT_TX_MAX 0xFF020137 -#define OID_SKGE_STAT_TX_SYNC 0xFF020138 +#define OID_SKGE_STAT_TX_64 0xFF020132 +#define OID_SKGE_STAT_TX_127 0xFF020133 +#define OID_SKGE_STAT_TX_255 0xFF020134 +#define OID_SKGE_STAT_TX_511 0xFF020135 +#define OID_SKGE_STAT_TX_1023 0xFF020136 +#define OID_SKGE_STAT_TX_MAX 0xFF020137 +#define OID_SKGE_STAT_TX_SYNC 0xFF020138 #define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139 -#define OID_SKGE_STAT_RX 0xFF02013A -#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B -#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C -#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D -#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E -#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F -#define OID_SKGE_STAT_RX_FLOWC 0xFF020140 -#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141 +#define OID_SKGE_STAT_RX 0xFF02013A +#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B +#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C +#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D +#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E +#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F +#define OID_SKGE_STAT_RX_FLOWC 0xFF020140 +#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141 #define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142 -#define OID_SKGE_STAT_RX_BURST 0xFF020143 -#define OID_SKGE_STAT_RX_MISSED 0xFF020144 -#define OID_SKGE_STAT_RX_FRAMING 0xFF020145 -#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146 -#define OID_SKGE_STAT_RX_JABBER 0xFF020147 -#define OID_SKGE_STAT_RX_CARRIER 0xFF020148 -#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149 -#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A -#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B -#define OID_SKGE_STAT_RX_RUNT 0xFF02014C -#define OID_SKGE_STAT_RX_CEXT 0xFF02014D -#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E -#define OID_SKGE_STAT_RX_FCS 0xFF02014F +#define OID_SKGE_STAT_RX_BURST 0xFF020143 +#define OID_SKGE_STAT_RX_MISSED 0xFF020144 +#define OID_SKGE_STAT_RX_FRAMING 0xFF020145 +#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146 +#define OID_SKGE_STAT_RX_JABBER 0xFF020147 +#define OID_SKGE_STAT_RX_CARRIER 0xFF020148 +#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149 +#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A +#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B +#define OID_SKGE_STAT_RX_RUNT 0xFF02014C +#define OID_SKGE_STAT_RX_CEXT 0xFF02014D +#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E +#define OID_SKGE_STAT_RX_FCS 0xFF02014F /* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */ -#define OID_SKGE_STAT_RX_64 0xFF020151 -#define OID_SKGE_STAT_RX_127 0xFF020152 -#define OID_SKGE_STAT_RX_255 0xFF020153 -#define OID_SKGE_STAT_RX_511 0xFF020154 -#define OID_SKGE_STAT_RX_1023 0xFF020155 -#define OID_SKGE_STAT_RX_MAX 0xFF020156 -#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157 - -#define OID_SKGE_DIAG_ACTION 0xFF01011D -#define OID_SKGE_DIAG_RESULT 0xFF01011E -#define OID_SKGE_MTU 0xFF01011F -#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120 -#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121 -#define OID_SKGE_PMD 0xFF010122 -#define OID_SKGE_CONNECTOR 0xFF010123 -#define OID_SKGE_LINK_CAP 0xFF010124 -#define OID_SKGE_LINK_MODE 0xFF010125 -#define OID_SKGE_LINK_MODE_STATUS 0xFF010126 -#define OID_SKGE_LINK_STATUS 0xFF010127 -#define OID_SKGE_FLOWCTRL_CAP 0xFF010128 -#define OID_SKGE_FLOWCTRL_MODE 0xFF010129 -#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A -#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B -#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C -#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D -#define OID_SKGE_MULTICAST_LIST 0xFF01012E -#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F - -#define OID_SKGE_TRAP 0xFF010130 -#define OID_SKGE_TRAP_NUMBER 0xFF010131 - -#define OID_SKGE_RLMT_MODE 0xFF010140 -#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141 -#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142 -#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143 -#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160 -#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160 -#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161 -#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162 -#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163 - -#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164 -#define OID_SKGE_RLMT_STATUS 0xFF020165 -#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166 -#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167 -#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168 -#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169 +#define OID_SKGE_STAT_RX_64 0xFF020151 +#define OID_SKGE_STAT_RX_127 0xFF020152 +#define OID_SKGE_STAT_RX_255 0xFF020153 +#define OID_SKGE_STAT_RX_511 0xFF020154 +#define OID_SKGE_STAT_RX_1023 0xFF020155 +#define OID_SKGE_STAT_RX_MAX 0xFF020156 +#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157 + +#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160 +#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161 +#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162 +#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163 + +#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164 +#define OID_SKGE_RLMT_STATUS 0xFF020165 +#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166 +#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167 +#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168 +#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169 #define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150 -#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151 -#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152 -#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153 +#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151 +#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152 +#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153 #define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154 -#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155 +#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155 -#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170 -#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171 -#define OID_SKGE_TX_RETRY 0xFF020172 -#define OID_SKGE_RX_INTR_CTS 0xFF020173 -#define OID_SKGE_TX_INTR_CTS 0xFF020174 -#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175 -#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176 -#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177 -#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178 +#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170 +#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171 +#define OID_SKGE_TX_RETRY 0xFF020172 +#define OID_SKGE_RX_INTR_CTS 0xFF020173 +#define OID_SKGE_TX_INTR_CTS 0xFF020174 +#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175 +#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176 +#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177 +#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178 #define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179 -#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A -#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B -#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C -#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D -#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E -#define OID_SKGE_SYSUPTIME 0xFF02017F - -#define OID_SKGE_ALL_DATA 0xFF020190 - - -#define OID_SKGE_TRAP_SEN_WAR_LOW 500 -#define OID_SKGE_TRAP_SEN_WAR_UPP 501 -#define OID_SKGE_TRAP_SEN_ERR_LOW 502 -#define OID_SKGE_TRAP_SEN_ERR_UPP 503 +#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A +#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B +#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C +#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D +#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E +#define OID_SKGE_SYSUPTIME 0xFF02017F + +#define OID_SKGE_ALL_DATA 0xFF020190 + +/* Defines for VCT. */ +#define OID_SKGE_VCT_GET 0xFF020200 +#define OID_SKGE_VCT_SET 0xFF020201 +#define OID_SKGE_VCT_STATUS 0xFF020202 + + +/* VCT struct to store a backup copy of VCT data after a port reset. */ +typedef struct s_PnmiVct { + SK_U8 VctStatus; + SK_U8 PCableLen; + SK_U32 PMdiPairLen[4]; + SK_U8 PMdiPairSts[4]; +} SK_PNMI_VCT; + + +/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */ +#define SK_PNMI_VCT_NONE 0 +#define SK_PNMI_VCT_OLD_VCT_DATA 1 +#define SK_PNMI_VCT_NEW_VCT_DATA 2 +#define SK_PNMI_VCT_OLD_DSP_DATA 4 +#define SK_PNMI_VCT_NEW_DSP_DATA 8 +#define SK_PNMI_VCT_RUNNING 16 + + +/* VCT cable test status. */ +#define SK_PNMI_VCT_NORMAL_CABLE 0 +#define SK_PNMI_VCT_SHORT_CABLE 1 +#define SK_PNMI_VCT_OPEN_CABLE 2 +#define SK_PNMI_VCT_TEST_FAIL 3 +#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4 + +#define OID_SKGE_TRAP_SEN_WAR_LOW 500 +#define OID_SKGE_TRAP_SEN_WAR_UPP 501 +#define OID_SKGE_TRAP_SEN_ERR_LOW 502 +#define OID_SKGE_TRAP_SEN_ERR_UPP 503 #define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520 #define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521 #define OID_SKGE_TRAP_RLMT_PORT_DOWN 522 -#define OID_SKGE_TRAP_RLMT_PORT_UP 523 +#define OID_SKGE_TRAP_RLMT_PORT_UP 523 #define OID_SKGE_TRAP_RLMT_SEGMENTATION 524 @@ -539,7 +623,7 @@ #define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12) #define SK_PNMI_ERR012MSG "SensorStat: Unknown OID" #define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13) -#define SK_PNMI_ERR013MSG "SensorStat: Unknown OID should be errored before" +#define SK_PNMI_ERR013MSG "" #define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14) #define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys" #define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15) @@ -583,7 +667,7 @@ #define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35) #define SK_PNMI_ERR035MSG "Rlmt: Unknown OID" #define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36) -#define SK_PNMI_ERR036MSG "Rlmt: Unknown OID should be errored before" +#define SK_PNMI_ERR036MSG "" #define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37) #define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0" #define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38) @@ -591,17 +675,17 @@ #define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39) #define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID" #define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40) -#define SK_PNMI_ERR040MSG "RlmtStat: Unknown OID should be errored before" +#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID" #define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41) #define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID" #define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42) -#define SK_PNMI_ERR042MSG "MacPrivateConf: Unknown OID should be errored before" +#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0" #define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43) #define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0" #define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44) #define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0" #define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45) -#define SK_PNMI_ERR045MSG "MacPrivateConf: Unknown OID in set action" +#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0" #define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46) #define SK_PNMI_ERR046MSG "Monitor: Unknown OID" #define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47) @@ -609,13 +693,13 @@ #define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48) #define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0" #define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49) -#define SK_PNMI_ERR049MSG "" +#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!" #define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50) -#define SK_PNMI_ERR050MSG "MacUpdate: Cannot update statistic counter" +#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!" #define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51) #define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious" #define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52) -#define SK_PNMI_ERR052MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0" +#define SK_PNMI_ERR052MSG "" /* * Management counter macros called by the driver @@ -659,7 +743,21 @@ #define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \ { \ if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxLongFrameCts)++; \ + ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \ + } \ + } + +#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \ + { \ + if ((p) < SK_MAX_MACS) { \ + ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \ + } \ + } + +#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \ + { \ + if ((p) < SK_MAX_MACS) { \ + ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \ } \ } @@ -685,12 +783,12 @@ #define SK_PNMI_MULTICAST_LISTLEN 64 #define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS) #define SK_PNMI_CHECKSUM_ENTRIES 3 -#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1) +#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1) #define SK_PNMI_MONITOR_ENTRIES 20 #define SK_PNMI_TRAP_ENTRIES 10 -#define SK_PNMI_TRAPLEN 128 -#define SK_PNMI_STRINGLEN1 80 -#define SK_PNMI_STRINGLEN2 25 +#define SK_PNMI_TRAPLEN 128 +#define SK_PNMI_STRINGLEN1 80 +#define SK_PNMI_STRINGLEN2 25 #define SK_PNMI_TRAP_QUEUE_LEN 512 typedef struct s_PnmiVpd { @@ -798,6 +896,9 @@ SK_U8 ConfPhyOperationCapability; SK_U8 ConfPhyOperationMode; SK_U8 ConfPhyOperationStatus; + SK_U8 ConfSpeedCapability; + SK_U8 ConfSpeedMode; + SK_U8 ConfSpeedStatus; } SK_PNMI_CONF; typedef struct s_PnmiRlmt { @@ -843,11 +944,11 @@ SK_U8 BusSpeed; SK_U8 BusWidth; SK_U8 SensorNumber; - SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES]; + SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES]; SK_U8 ChecksumNumber; SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES]; - SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES]; - SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES]; + SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES]; + SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES]; SK_U8 RlmtMode; SK_U32 RlmtPortNumber; SK_U8 RlmtPortActive; @@ -856,7 +957,7 @@ SK_U64 RlmtChangeTime; SK_U64 RlmtChangeEstimate; SK_U64 RlmtChangeThreshold; - SK_PNMI_RLMT Rlmt[SK_MAX_MACS]; + SK_PNMI_RLMT Rlmt[SK_MAX_MACS]; SK_U32 RlmtMonitorNumber; SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES]; SK_U32 TrapNumber; @@ -882,25 +983,27 @@ #define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA)) #define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\ &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes)) - /* - * ReturnStatus field - * must be located - * before VpdFreeBytes - */ + /* + * ReturnStatus field + * must be located + * before VpdFreeBytes + */ /* * Various definitions */ #define SK_PNMI_MAX_PROTOS 3 -#define SK_PNMI_SCNT_NOT 64 -#define SK_PNMI_CNT_NO 67 +#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum + * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK + * for check while init phase 1 + */ /* * Estimate data structure */ typedef struct s_PnmiEstimate { - unsigned int EstValueIndex; + unsigned int EstValueIndex; SK_U64 EstValue[7]; SK_U64 Estimate; SK_TIMER EstTimer; @@ -908,15 +1011,22 @@ /* - * PNMI specific adatper context structure + * VCT timer data structure + */ +typedef struct s_VctTimer { + SK_TIMER VctTimer; +} SK_PNMI_VCT_TIMER; + + +/* + * PNMI specific adapter context structure */ typedef struct s_PnmiPort { - SK_U32 CounterHigh[SK_PNMI_SCNT_NOT]; - SK_U64 CounterOffset[SK_PNMI_CNT_NO]; SK_U64 StatSyncCts; SK_U64 StatSyncOctetsCts; SK_U64 StatRxLongFrameCts; - SK_BOOL ActiveFlag; + SK_U64 StatRxFrameTooLongCts; + SK_U64 StatRxPMaccErr; SK_U64 TxSwQueueLen; SK_U64 TxSwQueueMax; SK_U64 TxRetryCts; @@ -932,41 +1042,53 @@ SK_U64 InErrorsCts; SK_U64 OutErrorsCts; SK_U64 ErrRecoveryCts; + SK_U64 RxShortZeroMark; + SK_U64 CounterOffset[SK_PNMI_CNT_NO]; + SK_U32 CounterHigh[SK_PNMI_CNT_NO]; + SK_BOOL ActiveFlag; + SK_U8 Align[3]; } SK_PNMI_PORT; typedef struct s_PnmiData { - SK_PNMI_PORT Port[SK_MAX_MACS]; + SK_PNMI_PORT Port [SK_MAX_MACS]; + SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */ SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO]; SK_U32 TestResult; char HwVersion[10]; + SK_U16 Align01; char *pDriverDescription; char *pDriverVersion; - char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN]; - unsigned int TrapBufFree; - unsigned int TrapQueueBeg; - unsigned int TrapQueueEnd; - unsigned int TrapBufPad; - unsigned int TrapUnique; - - int MacUpdatedFlag; - int RlmtUpdatedFlag; - int SirqUpdatedFlag; + int MacUpdatedFlag; + int RlmtUpdatedFlag; + int SirqUpdatedFlag; SK_U64 RlmtChangeCts; SK_U64 RlmtChangeTime; SK_PNMI_ESTIMATE RlmtChangeEstimate; SK_U64 RlmtChangeThreshold; + SK_U64 StartUpTime; SK_U32 DeviceType; char PciBusSpeed; char PciBusWidth; + char Chipset; char PMD; char Connector; - SK_U64 StartUpTime; SK_BOOL DualNetActiveFlag; + SK_U16 Align02; + + char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN]; + unsigned int TrapBufFree; + unsigned int TrapQueueBeg; + unsigned int TrapQueueEnd; + unsigned int TrapBufPad; + unsigned int TrapUnique; + SK_U8 VctStatus[SK_MAX_MACS]; + SK_PNMI_VCT VctBackup[SK_MAX_MACS]; + SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS]; } SK_PNMI; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skgesirq.h linux.21pre4-ac6/drivers/net/sk98lin/h/skgesirq.h --- linux.21pre4/drivers/net/sk98lin/h/skgesirq.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skgesirq.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skgesirq.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.22 $ - * Date: $Date: 2000/11/09 11:30:10 $ + * Version: $Revision: 1.26 $ + * Date: $Date: 2002/10/14 09:52:36 $ * Purpose: SK specific Gigabit Ethernet special IRQ functions * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2000 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -25,6 +25,21 @@ * * History: * $Log: skgesirq.h,v $ + * Revision 1.26 2002/10/14 09:52:36 rschmidt + * Added SKERR_SIRQ_E023 and SKERR_SIRQ_E023 for GPHY (Yukon) + * Editorial changes + * + * Revision 1.25 2002/07/15 18:15:52 rwahl + * Editorial changes. + * + * Revision 1.24 2002/07/15 15:39:21 rschmidt + * Corrected define for SKERR_SIRQ_E022 + * Editorial changes + * + * Revision 1.23 2002/04/25 11:09:45 rschmidt + * Removed declarations for SkXmInitPhy(), SkXmRxTxEnable() + * Editorial changes + * * Revision 1.22 2000/11/09 11:30:10 rassmann * WA: Waiting after releasing reset until BCom chip is accessible. * @@ -66,7 +81,7 @@ * defined in skgeinit.h now. * * Revision 1.9 1998/10/14 14:00:39 gklug - * add: eroor logs for init phys + * add: error logs for init phys * * Revision 1.8 1998/10/14 05:44:05 gklug * add: E020 @@ -103,73 +118,76 @@ /* * Define the Event the special IRQ/INI module can handle */ -#define SK_HWEV_WATIM 1 /* Timeout for WA errata #2 XMAC */ -#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */ -#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */ -#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */ -#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */ -#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */ +#define SK_HWEV_WATIM 1 /* Timeout for WA errata #2 XMAC */ +#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */ +#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */ +#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */ +#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */ +#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */ #define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */ -#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */ -#define SK_HWEV_HALFDUP_CHK 9 /* Set Master/Slave (Role) by PNMI */ +#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */ +#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */ +#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */ -#define SK_WA_ACT_TIME (5000000L) /* 5 sec */ -#define SK_WA_INA_TIME (100000L) /* 100 msec */ +#define SK_WA_ACT_TIME (5000000L) /* 5 sec */ +#define SK_WA_INA_TIME (100000L) /* 100 msec */ -#define SK_HALFDUP_CHK_TIME (10000L) /* 10 msec */ +#define SK_HALFDUP_CHK_TIME (10000L) /* 10 msec */ /* * Define the error numbers and messages */ -#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0) -#define SKERR_SIRQ_E001MSG "Unknown event" -#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1) -#define SKERR_SIRQ_E002MSG "Packet timeout RX1" -#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1) -#define SKERR_SIRQ_E003MSG "Packet timeout RX2" -#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1) -#define SKERR_SIRQ_E004MSG "XMAC 1 not correctly initialized" -#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1) -#define SKERR_SIRQ_E005MSG "XMAC 2 not correctly initialized" -#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1) -#define SKERR_SIRQ_E006MSG "CHECK failure R1" -#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1) -#define SKERR_SIRQ_E007MSG "CHECK failure R2" -#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1) -#define SKERR_SIRQ_E008MSG "CHECK failure XS1" -#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1) -#define SKERR_SIRQ_E009MSG "CHECK failure XA1" -#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1) -#define SKERR_SIRQ_E010MSG "CHECK failure XS2" -#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1) -#define SKERR_SIRQ_E011MSG "CHECK failure XA2" -#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1) -#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error" -#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1) -#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error" -#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1) -#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)" -#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1) -#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)" -#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1) -#define SKERR_SIRQ_E016MSG "Parity error MAC 1" -#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1) -#define SKERR_SIRQ_E017MSG "Parity error MAC 2" -#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1) -#define SKERR_SIRQ_E018MSG "Parity error RX 1" -#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1) -#define SKERR_SIRQ_E019MSG "Parity error RX 2" -#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1) -#define SKERR_SIRQ_E020MSG "XMAC transmit FIFO underrun" -#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1) -#define SKERR_SIRQ_E021MSG "Spurious I2C interrupt" -#define SKERR_SIRQ_E022 (SKERR_SIRQ_E020+1) -#define SKERR_SIRQ_E022MSG "Cable pair swap error" +#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0) +#define SKERR_SIRQ_E001MSG "Unknown event" +#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1) +#define SKERR_SIRQ_E002MSG "Packet timeout RX1" +#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1) +#define SKERR_SIRQ_E003MSG "Packet timeout RX2" +#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1) +#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized" +#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1) +#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized" +#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1) +#define SKERR_SIRQ_E006MSG "CHECK failure R1" +#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1) +#define SKERR_SIRQ_E007MSG "CHECK failure R2" +#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1) +#define SKERR_SIRQ_E008MSG "CHECK failure XS1" +#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1) +#define SKERR_SIRQ_E009MSG "CHECK failure XA1" +#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1) +#define SKERR_SIRQ_E010MSG "CHECK failure XS2" +#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1) +#define SKERR_SIRQ_E011MSG "CHECK failure XA2" +#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1) +#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error" +#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1) +#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error" +#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1) +#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)" +#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1) +#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)" +#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1) +#define SKERR_SIRQ_E016MSG "Parity error MAC 1" +#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1) +#define SKERR_SIRQ_E017MSG "Parity error MAC 2" +#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1) +#define SKERR_SIRQ_E018MSG "Parity error RX 1" +#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1) +#define SKERR_SIRQ_E019MSG "Parity error RX 2" +#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1) +#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun" +#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1) +#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt" +#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1) +#define SKERR_SIRQ_E022MSG "Cable pair swap error" +#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1) +#define SKERR_SIRQ_E023MSG "Auto-negotiation error" +#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1) +#define SKERR_SIRQ_E024MSG "FIFO overflow error" extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern void SkXmInitPhy( SK_AC *pAC, SK_IOC IoC, int Port, SK_BOOL DoLoop); -extern int SkXmRxTxEnable(SK_AC *pAC, SK_IOC IoC, int Port); extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port); extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/ski2c.h linux.21pre4-ac6/drivers/net/sk98lin/h/ski2c.h --- linux.21pre4/drivers/net/sk98lin/h/ski2c.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/ski2c.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: ski2c.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.30 $ - * Date: $Date: 2001/04/05 11:38:09 $ + * Version: $Revision: 1.33 $ + * Date: $Date: 2002/10/14 16:40:50 $ * Purpose: Defines to access Voltage and Temperature Sensor * (taken from Monalisa (taken from Concentrator)) * @@ -28,6 +28,15 @@ * History: * * $Log: ski2c.h,v $ + * Revision 1.33 2002/10/14 16:40:50 rschmidt + * Editorial changes (TWSI) + * + * Revision 1.32 2002/08/13 08:55:07 rschmidt + * Editorial changes + * + * Revision 1.31 2002/08/06 09:44:22 jschmalz + * Extensions and changes for Yukon + * * Revision 1.30 2001/04/05 11:38:09 rassmann * Set SenState to idle in SkI2cWaitIrq(). * Changed error message in SkI2cWaitIrq(). @@ -142,127 +151,131 @@ #include "h/skgei2c.h" /* - * Define the I2c events. + * Define the I2C events. */ #define SK_I2CEV_IRQ 1 /* IRQ happened Event */ #define SK_I2CEV_TIM 2 /* Timeout event */ -#define SK_I2CEV_CLEAR 3 /* Clear Mib Values */ +#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */ /* * Define READ and WRITE Constants. */ -#define I2C_READ 0 -#define I2C_WRITE 1 +#define I2C_READ 0 +#define I2C_WRITE 1 #define I2C_BURST 1 #define I2C_SIGLE 0 -#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0) -#define SKERR_I2C_E001MSG "Sensor index unknown" -#define SKERR_I2C_E002 (SKERR_I2C_E001+1) -#define SKERR_I2C_E002MSG "I2C: transfer does not complete.\n" -#define SKERR_I2C_E003 (SKERR_I2C_E002+1) -#define SKERR_I2C_E003MSG "lm80: NAK on device send.\n" -#define SKERR_I2C_E004 (SKERR_I2C_E003+1) -#define SKERR_I2C_E004MSG "lm80: NAK on register send.\n" -#define SKERR_I2C_E005 (SKERR_I2C_E004+1) -#define SKERR_I2C_E005MSG "lm80: NAK on device (2) send.\n" -#define SKERR_I2C_E006 (SKERR_I2C_E005+1) -#define SKERR_I2C_E006MSG "Unknown event" -#define SKERR_I2C_E007 (SKERR_I2C_E006+1) -#define SKERR_I2C_E007MSG "LM80 read out of state" -#define SKERR_I2C_E008 (SKERR_I2C_E007+1) -#define SKERR_I2C_E008MSG "unexpected sensor read completed" -#define SKERR_I2C_E009 (SKERR_I2C_E008+1) -#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range" -#define SKERR_I2C_E010 (SKERR_I2C_E009+1) -#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range" -#define SKERR_I2C_E011 (SKERR_I2C_E010+1) -#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range" -#define SKERR_I2C_E012 (SKERR_I2C_E011+1) -#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range" -#define SKERR_I2C_E013 (SKERR_I2C_E012+1) -#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor" -#define SKERR_I2C_E014 (SKERR_I2C_E013+1) -#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range" -#define SKERR_I2C_E015 (SKERR_I2C_E014+1) -#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range" -#define SKERR_I2C_E016 (SKERR_I2C_E015+1) -#define SKERR_I2C_E016MSG "I2C: active transfer does not complete.\n" +#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0) +#define SKERR_I2C_E001MSG "Sensor index unknown" +#define SKERR_I2C_E002 (SKERR_I2C_E001+1) +#define SKERR_I2C_E002MSG "TWSI: transfer does not complete" +#define SKERR_I2C_E003 (SKERR_I2C_E002+1) +#define SKERR_I2C_E003MSG "LM80: NAK on device send" +#define SKERR_I2C_E004 (SKERR_I2C_E003+1) +#define SKERR_I2C_E004MSG "LM80: NAK on register send" +#define SKERR_I2C_E005 (SKERR_I2C_E004+1) +#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send" +#define SKERR_I2C_E006 (SKERR_I2C_E005+1) +#define SKERR_I2C_E006MSG "Unknown event" +#define SKERR_I2C_E007 (SKERR_I2C_E006+1) +#define SKERR_I2C_E007MSG "LM80 read out of state" +#define SKERR_I2C_E008 (SKERR_I2C_E007+1) +#define SKERR_I2C_E008MSG "Unexpected sensor read completed" +#define SKERR_I2C_E009 (SKERR_I2C_E008+1) +#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range" +#define SKERR_I2C_E010 (SKERR_I2C_E009+1) +#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range" +#define SKERR_I2C_E011 (SKERR_I2C_E010+1) +#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range" +#define SKERR_I2C_E012 (SKERR_I2C_E011+1) +#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range" +#define SKERR_I2C_E013 (SKERR_I2C_E012+1) +#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor" +#define SKERR_I2C_E014 (SKERR_I2C_E013+1) +#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range" +#define SKERR_I2C_E015 (SKERR_I2C_E014+1) +#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range" +#define SKERR_I2C_E016 (SKERR_I2C_E015+1) +#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete" /* * Define Timeout values */ -#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */ -#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */ +#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */ +#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */ +#define SK_I2C_TIM_WATCH 1000000L /* 1 second */ /* * Define trap and error log hold times */ #ifndef SK_SEN_ERR_TR_HOLD -#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC) +#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC) #endif #ifndef SK_SEN_ERR_LOG_HOLD -#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC) +#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC) #endif #ifndef SK_SEN_WARN_TR_HOLD -#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC) +#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC) #endif #ifndef SK_SEN_WARN_LOG_HOLD -#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC) +#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC) #endif /* * Defines for SenType */ -#define SK_SEN_TEMP 1 -#define SK_SEN_VOLT 2 -#define SK_SEN_FAN 3 +#define SK_SEN_UNKNOWN 0 +#define SK_SEN_TEMP 1 +#define SK_SEN_VOLT 2 +#define SK_SEN_FAN 3 /* - * Define for the ErrorFlag + * Define for the SenErrorFlag */ -#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */ -#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */ -#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */ +#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */ +#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */ +#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */ +#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */ +#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */ /* * Define the Sensor struct */ struct s_Sensor { - char *SenDesc; /* Description */ - int SenType; /* Voltage or Temperature */ - SK_I32 SenValue; /* Current value of the sensor */ - SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */ - SK_I32 SenThreWarnHigh;/* High warning Threshhold of this sensor */ - SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */ - SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ - int SenErrFlag; /* Sensor indicated an error */ - SK_BOOL SenInit; /* Is sensor initialized? */ - SK_U64 SenErrCts; /* Error trap counter */ - SK_U64 SenWarnCts; /* Warning trap counter */ - SK_U64 SenBegErrTS; /* Begin error timestamp */ - SK_U64 SenBegWarnTS; /* Begin warning timestamp */ + char *SenDesc; /* Description */ + int SenType; /* Voltage or Temperature */ + SK_I32 SenValue; /* Current value of the sensor */ + SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */ + SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */ + SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */ + SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ + int SenErrFlag; /* Sensor indicated an error */ + SK_BOOL SenInit; /* Is sensor initialized ? */ + SK_U64 SenErrCts; /* Error trap counter */ + SK_U64 SenWarnCts; /* Warning trap counter */ + SK_U64 SenBegErrTS; /* Begin error timestamp */ + SK_U64 SenBegWarnTS; /* Begin warning timestamp */ SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */ SK_U64 SenLastErrLogTS; /* Last error log timestamp */ SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */ SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */ - int SenState; /* Sensor State (see HW specific include) */ - int (*SenRead)(SK_AC *pAC, SK_IOC IoC,struct s_Sensor *pSen) ; - /* Sensors read function */ - SK_U16 SenReg; /* Register Address for this sensor */ - SK_U8 SenDev; /* DeviceSelection for this sensor */ -} ; - + int SenState; /* Sensor State (see HW specific include) */ + int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen); + /* Sensors read function */ + SK_U16 SenReg; /* Register Address for this sensor */ + SK_U8 SenDev; /* Device Selection for this sensor */ +}; typedef struct s_I2c { SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */ - int CurrSens; /* Which sensor is currently queried */ - int MaxSens; /* Max. number of sensors */ - int InitLevel; /* Initialized Level */ + int CurrSens; /* Which sensor is currently queried */ + int MaxSens; /* Max. number of sensors */ + int TimerMode; /* Use the timer also to watch the state machine */ + int InitLevel; /* Initialized Level */ #ifndef SK_DIAG - int DummyReads; /* Number of non-checked dummy reads */ + int DummyReads; /* Number of non-checked dummy reads */ SK_TIMER SenTimer; /* Sensors timer */ -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ } SK_I2C; extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); @@ -273,5 +286,5 @@ extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); #endif -#endif /* n_SKI2C_H */ +#endif /* n_SKI2C_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skqueue.h linux.21pre4-ac6/drivers/net/sk98lin/h/skqueue.h --- linux.21pre4/drivers/net/sk98lin/h/skqueue.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skqueue.h 2003-01-06 15:38:18.000000000 +0000 @@ -1,32 +1,23 @@ /****************************************************************************** * * Name: skqueue.h - * Project: Genesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.12 $ - * Date: $Date: 1998/09/08 08:48:01 $ + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.14 $ + * Date: $Date: 2002/03/15 10:52:13 $ * Purpose: Defines for the Event queue * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1989-1998 SysKonnect, + * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. - * All Rights Reserved * - * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT - * The copyright notice above does not evidence any - * actual or intended publication of such source code. - * - * This Module contains Proprietary Information of SysKonnect - * and should be treated as Confidential. - * - * The information in this file is provided for the exclusive use of - * the licensees of SysKonnect. - * Such users have the right to use, modify, and incorporate this code - * into products for purposes authorized by the license agreement - * provided they include this notice and the associated copyright notice - * with any such product. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -36,6 +27,12 @@ * History: * * $Log: skqueue.h,v $ + * Revision 1.14 2002/03/15 10:52:13 mkunz + * Added event classes for link aggregation + * + * Revision 1.13 1999/11/22 13:59:05 cgoos + * Changed license header to GPL. + * * Revision 1.12 1998/09/08 08:48:01 gklug * add: init level handling * @@ -97,6 +94,12 @@ #define SKGE_CSUM 5 /* Checksum Event Class */ #define SKGE_HWAC 6 /* Hardware Access Event Class */ +#define SKGE_SWT 9 /* Software Timer Event Class */ +#define SKGE_LACP 10 /* LACP Aggregation Event Class */ +#define SKGE_RSF 11 /* RSF Aggregation Event Class */ +#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */ +#define SKGE_FD 13 /* FD Distributor Event Class */ + /* * define event queue as circular buffer */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skrlmt.h linux.21pre4-ac6/drivers/net/sk98lin/h/skrlmt.h --- linux.21pre4/drivers/net/sk98lin/h/skrlmt.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skrlmt.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skrlmt.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.32 $ - * Date: $Date: 2001/02/14 14:06:31 $ + * Version: $Revision: 1.33 $ + * Date: $Date: 2001/07/03 12:16:48 $ * Purpose: Header file for Redundant Link ManagemenT. * ******************************************************************************/ @@ -26,6 +26,9 @@ * History: * * $Log: skrlmt.h,v $ + * Revision 1.33 2001/07/03 12:16:48 mkunz + * New Flag ChgBcPrio (Change priority of last broadcast received) + * * Revision 1.32 2001/02/14 14:06:31 rassmann * Editorial changes. * @@ -468,6 +471,7 @@ /* For PNMI */ + SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */ SK_U32 RlmtMode; /* Check ... */ SK_U32 ActivePort; /* Active port. */ SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/sktimer.h linux.21pre4-ac6/drivers/net/sk98lin/h/sktimer.h --- linux.21pre4/drivers/net/sk98lin/h/sktimer.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/sktimer.h 2003-01-06 15:38:18.000000000 +0000 @@ -1,32 +1,23 @@ /****************************************************************************** * * Name: sktimer.h - * Project: Genesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.8 $ - * Date: $Date: 1998/09/08 08:48:02 $ + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.9 $ + * Date: $Date: 1999/11/22 14:00:29 $ * Purpose: Defines for the timer functions * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1989-1998 SysKonnect, + * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. - * All Rights Reserved * - * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT - * The copyright notice above does not evidence any - * actual or intended publication of such source code. - * - * This Module contains Proprietary Information of SysKonnect - * and should be treated as Confidential. - * - * The information in this file is provided for the exclusive use of - * the licensees of SysKonnect. - * Such users have the right to use, modify, and incorporate this code - * into products for purposes authorized by the license agreement - * provided they include this notice and the associated copyright notice - * with any such product. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -36,6 +27,9 @@ * History: * * $Log: sktimer.h,v $ + * Revision 1.9 1999/11/22 14:00:29 cgoos + * Changed license header to GPL. + * * Revision 1.8 1998/09/08 08:48:02 gklug * add: init level handling * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skversion.h linux.21pre4-ac6/drivers/net/sk98lin/h/skversion.h --- linux.21pre4/drivers/net/sk98lin/h/skversion.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skversion.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: version.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2001/03/06 09:25:00 $ + * Version: $Revision: 1.1.2.1 $ + * Date: $Date: 2001/09/05 13:38:30 $ * Purpose: SK specific Error log support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, + * (C)Copyright 1998-2002 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. * * This program is free software; you can redistribute it and/or modify @@ -26,6 +26,9 @@ * * History: * $Log: skversion.h,v $ + * Revision 1.1.2.1 2001/09/05 13:38:30 mlindner + * Removed FILE description + * * Revision 1.1 2001/03/06 09:25:00 mlindner * first version * @@ -34,13 +37,13 @@ ******************************************************************************/ -static const char SysKonnectFileId[] = "@(#)" __FILE__ " (C) SysKonnect GmbH."; +static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 4.06 PL: 01"; + "@(#)SK-BUILD: 6.02 PL: 01"; -#define BOOT_STRING "sk98lin: Network Device Driver v4.06\n" \ - "Copyright (C) 2000-2001 SysKonnect GmbH." +#define BOOT_STRING "sk98lin: Network Device Driver v6.02\n" \ + "Copyright (C) 2000-2002 SysKonnect GmbH." -#define VER_STRING "4.06" +#define VER_STRING "6.02" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/skvpd.h linux.21pre4-ac6/drivers/net/sk98lin/h/skvpd.h --- linux.21pre4/drivers/net/sk98lin/h/skvpd.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/skvpd.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: skvpd.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.9 $ - * Date: $Date: 1999/11/22 14:02:27 $ + * Version: $Revision: 1.13 $ + * Date: $Date: 2002/10/14 15:58:18 $ * Purpose: Defines and Macros for VPD handling * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -27,6 +26,25 @@ * History: * * $Log: skvpd.h,v $ + * Revision 1.13 2002/10/14 15:58:18 rschmidt + * Added entry in rom_size struct s_vpd + * Editorial changes + * + * Revision 1.12 2002/09/09 14:43:51 mkarl + * added PCI Id of Yukon for reading VPD in diag before the adapter has + * been initialized + * editorial changes + * + * Revision 1.11 2002/07/26 13:19:16 mkarl + * added support for Yukon + * added vpd_size to VPD struct + * + * Revision 1.10 2000/08/10 11:29:07 rassmann + * Editorial changes. + * Preserving 32-bit alignment in structs for the adapter context. + * Removed unused function VpdWriteDword() (#if 0). + * Made VpdReadKeyword() available for SKDIAG only. + * * Revision 1.9 1999/11/22 14:02:27 cgoos * Changed license header to GPL. * @@ -99,7 +117,12 @@ /* * Define READ and WRITE Constants. */ -#define VPD_SIZE 512 + +#define VPD_PCI_ID_YUKON 0x4320 + +#define VPD_SIZE_YUKON 256 +#define VPD_SIZE_GENESIS 512 +#define VPD_SIZE 512 #define VPD_READ 0x0000 #define VPD_WRITE 0x8000 @@ -115,40 +138,44 @@ /* VPD status */ /* bit 7..1 reserved */ -#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */ - /* and vpd_free_rw valid */ +#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */ + /* and vpd_free_rw valid */ /* * VPD structs */ typedef struct s_vpd_status { - unsigned short vpd_status ; /* VPD status, description see above */ - int vpd_free_ro ; /* unused bytes in read only area */ - int vpd_free_rw ; /* bytes available in read/write area */ + unsigned short Align01; /* Alignment */ + unsigned short vpd_status; /* VPD status, description see above */ + int vpd_free_ro; /* unused bytes in read only area */ + int vpd_free_rw; /* bytes available in read/write area */ } SK_VPD_STATUS; typedef struct s_vpd { - SK_VPD_STATUS v ; /* VPD status structure */ - char vpd_buf[VPD_SIZE] ; /* VPD buffer */ + SK_VPD_STATUS v; /* VPD status structure */ + char vpd_buf[VPD_SIZE]; /* VPD buffer */ + int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */ + int vpd_size; /* saved VPD-size */ } SK_VPD; typedef struct s_vpd_para { - unsigned int p_len ; /* parameter length */ - char *p_val ; /* points to the value */ + unsigned int p_len; /* parameter length */ + char *p_val; /* points to the value */ } SK_VPD_PARA; /* * structure of Large Resource Type Identifiers */ -/* was removed, because of alignment problems */ + +/* was removed because of alignment problems */ /* - * sturcture of VPD keywords + * structure of VPD keywords */ typedef struct s_vpd_key { - char p_key[2] ; /* 2 bytes ID string */ - unsigned char p_len ; /* 1 byte length */ - char p_val ; /* start of the value string */ + char p_key[2]; /* 2 bytes ID string */ + unsigned char p_len; /* 1 byte length */ + char p_val; /* start of the value string */ } SK_VPD_KEY; @@ -172,39 +199,39 @@ #define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal) #endif /* VPD_DO_IO */ #else /* SKDIAG */ -#define VPD_OUT8(pAC,Ioc,Addr,Val) { \ +#define VPD_OUT8(pAC,Ioc,Addr,Val) { \ if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciWriteCfgByte(pAC,Addr,Val) ; \ - else \ + SkPciWriteCfgByte(pAC,Addr,Val); \ + else \ SK_OUT8(pAC,PCI_C(Addr),Val); \ } -#define VPD_OUT16(pAC,Ioc,Addr,Val) { \ +#define VPD_OUT16(pAC,Ioc,Addr,Val) { \ if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciWriteCfgWord(pAC,Addr,Val) ; \ + SkPciWriteCfgWord(pAC,Addr,Val); \ else \ SK_OUT16(pAC,PCI_C(Addr),Val); \ } -#define VPD_OUT32(pAC,Ioc,Addr,Val) { \ +#define VPD_OUT32(pAC,Ioc,Addr,Val) { \ if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciWriteCfgDWord(pAC,Addr,Val) ; \ + SkPciWriteCfgDWord(pAC,Addr,Val); \ else \ SK_OUT32(pAC,PCI_C(Addr),Val); \ } -#define VPD_IN8(pAC,Ioc,Addr,pVal) { \ +#define VPD_IN8(pAC,Ioc,Addr,pVal) { \ if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciReadCfgByte(pAC,Addr,pVal) ; \ + SkPciReadCfgByte(pAC,Addr,pVal); \ else \ SK_IN8(pAC,PCI_C(Addr),pVal); \ } -#define VPD_IN16(pAC,Ioc,Addr,pVal) { \ +#define VPD_IN16(pAC,Ioc,Addr,pVal) { \ if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciReadCfgWord(pAC,Addr,pVal) ; \ + SkPciReadCfgWord(pAC,Addr,pVal); \ else \ SK_IN16(pAC,PCI_C(Addr),pVal); \ } -#define VPD_IN32(pAC,Ioc,Addr,pVal) { \ +#define VPD_IN32(pAC,Ioc,Addr,pVal) { \ if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciReadCfgDWord(pAC,Addr,pVal) ; \ + SkPciReadCfgDWord(pAC,Addr,pVal); \ else \ SK_IN32(pAC,PCI_C(Addr),pVal); \ } @@ -213,50 +240,52 @@ /* function prototypes ********************************************************/ #ifndef SK_KR_PROTO +#ifdef SKDIAG extern SK_U32 VpdReadDWord( SK_AC *pAC, SK_IOC IoC, - int addr) ; + int addr); +#endif /* SKDIAG */ extern int VpdSetupPara( SK_AC *pAC, char *key, char *buf, - int len, - int type, - int op) ; + int len, + int type, + int op); extern SK_VPD_STATUS *VpdStat( SK_AC *pAC, - SK_IOC IoC) ; + SK_IOC IoC); extern int VpdKeys( SK_AC *pAC, SK_IOC IoC, char *buf, - int *len, - int *elements) ; + int *len, + int *elements); extern int VpdRead( SK_AC *pAC, SK_IOC IoC, char *key, char *buf, - int *len) ; + int *len); -extern SK_BOOL VpdMayWrite( - char *key) ; +extern SK_BOOL VpdMayWrite( + char *key); extern int VpdWrite( SK_AC *pAC, SK_IOC IoC, char *key, - char *buf) ; + char *buf); extern int VpdDelete( SK_AC *pAC, SK_IOC IoC, - char *key) ; + char *key); extern int VpdUpdate( SK_AC *pAC, @@ -265,34 +294,34 @@ extern void VpdErrLog( SK_AC *pAC, SK_IOC IoC, - char *msg) ; + char *msg); #ifdef SKDIAG extern int VpdReadBlock( SK_AC *pAC, SK_IOC IoC, char *buf, - int addr, - int len) ; + int addr, + int len); extern int VpdWriteBlock( SK_AC *pAC, SK_IOC IoC, char *buf, - int addr, - int len) ; + int addr, + int len); #endif /* SKDIAG */ #else /* SK_KR_PROTO */ -extern SK_U32 VpdReadDWord() ; -extern int VpdSetupPara() ; -extern SK_VPD_STATUS *VpdStat() ; -extern int VpdKeys() ; -extern int VpdRead() ; -extern SK_BOOL VpdMayWrite() ; -extern int VpdWrite() ; -extern int VpdDelete() ; -extern int VpdUpdate() ; -extern void VpdErrLog() ; +extern SK_U32 VpdReadDWord(); +extern int VpdSetupPara(); +extern SK_VPD_STATUS *VpdStat(); +extern int VpdKeys(); +extern int VpdRead(); +extern SK_BOOL VpdMayWrite(); +extern int VpdWrite(); +extern int VpdDelete(); +extern int VpdUpdate(); +extern void VpdErrLog(); #endif /* SK_KR_PROTO */ #endif /* __INC_SKVPD_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/h/xmac_ii.h linux.21pre4-ac6/drivers/net/sk98lin/h/xmac_ii.h --- linux.21pre4/drivers/net/sk98lin/h/xmac_ii.h 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/h/xmac_ii.h 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: xmac_ii.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.28 $ - * Date: $Date: 2000/11/09 12:32:49 $ - * Purpose: Defines and Macros for XaQti's Gigabit Ethernet Controller + * Version: $Revision: 1.45 $ + * Date: $Date: 2002/12/10 14:35:13 $ + * Purpose: Defines and Macros for Gigabit Ethernet Controller * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2000 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,77 @@ * History: * * $Log: xmac_ii.h,v $ + * Revision 1.45 2002/12/10 14:35:13 rschmidt + * Corrected defines for Extended PHY Specific Control + * Added defines for Ext. PHY Specific Ctrl 2 Reg. (Fiber specific) + * + * Revision 1.44 2002/12/09 14:58:41 rschmidt + * Added defines for Ext. PHY Specific Ctrl Reg. (downshift feature) + * Added 'GMR_FS_UN_SIZE'-Bit to Rx GMAC FIFO Flush Mask + * + * Revision 1.43 2002/12/05 10:14:45 rschmidt + * Added define for GMAC's Half Duplex Burst Mode + * Added define for Rx GMAC FIFO Flush Mask (default) + * + * Revision 1.42 2002/11/12 16:48:19 rschmidt + * Added defines for Cable Diagnostic Register (GPHY) + * Editorial changes + * + * Revision 1.41 2002/10/21 11:20:22 rschmidt + * Added bit GMR_FS_GOOD_FC to GMR_FS_ANY_ERR + * Editorial changes + * + * Revision 1.40 2002/10/14 14:54:14 rschmidt + * Added defines for GPHY Specific Status and GPHY Interrupt Status + * Added bits PHY_M_IS_AN_ERROR and PHY_M_IS_FIFO_ERROR to PHY_M_DEF_MSK + * Editorial changes + * + * Revision 1.39 2002/10/10 15:53:44 mkarl + * added some bit definitions for link speed status and LED's + * + * Revision 1.38 2002/08/21 16:23:46 rschmidt + * Added defines for PHY Specific Ctrl Reg + * Editorial changes + * + * Revision 1.37 2002/08/16 14:50:33 rschmidt + * Added defines for Auto-Neg. Advertisement YUKON Fiber (88E1011S only) + * Changed define PHY_M_DEF_MSK for GPHY IRQ Mask + * Editorial changes + * + * Revision 1.36 2002/08/12 13:21:10 rschmidt + * Added defines for different Broadcom PHY Ids + * + * Revision 1.35 2002/08/08 15:58:01 rschmidt + * Added defines for Manual LED Override register (YUKON) + * Editorial changes + * + * Revision 1.34 2002/07/31 17:23:36 rwahl + * Added define GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR). + * + * Revision 1.33 2002/07/23 16:03:37 rschmidt + * Added defines for GPHY registers + * Editorial changes + * + * Revision 1.32 2002/07/15 18:14:37 rwahl + * Added GMAC MIB counters definitions. + * Editorial changes. + * + * Revision 1.31 2002/07/15 15:42:50 rschmidt + * Removed defines from PHY specific reg. which are + * common to all PHYs + * Added defines for GMAC MIB Counters + * Editorial changes + * + * Revision 1.30 2002/06/05 08:22:12 rschmidt + * Changed defines for GMAC Rx Control Register and Rx Status + * Editorial changes + * + * Revision 1.29 2002/04/25 11:43:56 rschmidt + * Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res. + * Added new registers and defines for YUKON (GMAC, GPHY) + * Added Receive Frame Status Encoding for YUKON + * Editorial changes + * * Revision 1.28 2000/11/09 12:32:49 rassmann * Renamed variables. * @@ -82,7 +153,7 @@ * Changed shifted constant to ULONG. * * Revision 1.11 1998/10/14 05:43:26 gklug - * add: shift pause codeing + * add: shift pause coding * fix: PAUSE bits definition * * Revision 1.10 1998/10/13 09:19:21 malthoff @@ -135,61 +206,61 @@ /* * XMAC II registers * - * The XMAC registers are 16 or 32 bits wide. The XMACs host processor - * interface is set to 16 bit mode, therefore ALL registers will be - * addressed with 16 bit accesses. + * The XMAC registers are 16 or 32 bits wide. + * The XMACs host processor interface is set to 16 bit mode, + * therefore ALL registers will be addressed with 16 bit accesses. * * The following macros are provided to access the XMAC registers - * XM_IN16(), XM_OUT16, XM_IN32(), MX_OUT32(), XM_INADR(), XM_OUTADR(), + * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(), * XM_INHASH(), and XM_OUTHASH(). * The macros are defined in SkGeHw.h. * * Note: NA reg = Network Address e.g DA, SA etc. * */ -#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */ +#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */ /* 0x0004: reserved */ -#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */ -#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/ +#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */ +#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/ #define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */ #define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */ /* 0x0018 - 0x001e: reserved */ -#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */ -#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */ -#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */ -#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */ -#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */ -#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */ -#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */ +#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */ +#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */ +#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */ +#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */ +#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */ +#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */ +#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */ /* 0x003c: reserved */ -#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */ -#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */ -#define XM_ISRC 0x0048 /* 16 bit ro Interrupt Status Register */ -#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */ +#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */ +#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */ +#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */ +#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */ /* 0x0050 - 0x005e: reserved */ -#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */ -#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */ -#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */ -#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */ -#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */ +#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */ +#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */ +#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */ +#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */ +#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */ /* 0x006e: reserved */ -#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */ +#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */ #define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */ #define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/ -#define XM_TX_STAT 0x0078 /* 32 bit ro Tx Status LIFO Register */ +#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */ - /* 0x0080 - 0x00fc: 16 NA reg r/w Exakt Match Address Registers */ - /* use the XM_EMX() macro to address */ + /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */ + /* use the XM_EXM() macro to address */ #define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */ /* * XM_EXM(Reg) * - * returns the XMAC address offset off specified Exakt Match Addr Reg + * returns the XMAC address offset of specified Exact Match Addr Reg * * para: Reg EXM register to addr (0 .. 15) * - * usage: XM_INADDR(XMAC_1,pAC,XM_EXM(i),&val[i]) ; + * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]); */ #define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3)) @@ -199,78 +270,78 @@ #define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */ #define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */ #define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */ -#define XM_DEV_ID 0x0120 /* 32 bit ro Device ID Register */ +#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */ #define XM_MODE 0x0124 /* 32 bit r/w Mode Register */ -#define XM_LSA 0x0128 /* NA reg ro Last Source Register */ +#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */ /* 0x012e: reserved */ -#define XM_TS_READ 0x0130 /* 32 bit ro TimeStamp Read Regeister */ -#define XM_TS_LOAD 0x0134 /* 32 bit ro TimeStamp Load Value */ +#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */ +#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */ /* 0x0138 - 0x01fe: reserved */ #define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */ -#define XM_RX_CNT_EV 0x0204 /* 32 bit ro Rx Counter Event Register */ -#define XM_TX_CNT_EV 0x0208 /* 32 bit ro Tx Counter Event Register */ +#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */ +#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */ #define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */ #define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */ /* 0x0204 - 0x027e: reserved */ -#define XM_TXF_OK 0x0280 /* 32 bit ro Frames Transmitted OK Conuter */ -#define XM_TXO_OK_HI 0x0284 /* 32 bit ro Octets Transmitted OK High Cnt*/ -#define XM_TXO_OK_LO 0x0288 /* 32 bit ro Octets Transmitted OK Low Cnt */ -#define XM_TXF_BC_OK 0x028c /* 32 bit ro Broadcast Frames Xmitted OK */ -#define XM_TXF_MC_OK 0x0290 /* 32 bit ro Multicast Frames Xmitted OK */ -#define XM_TXF_UC_OK 0x0294 /* 32 bit ro Unicast Frames Xmitted OK */ -#define XM_TXF_LONG 0x0298 /* 32 bit ro Tx Long Frame Counter */ -#define XM_TXE_BURST 0x029c /* 32 bit ro Tx Burst Event Counter */ -#define XM_TXF_MPAUSE 0x02a0 /* 32 bit ro Tx Pause MAC Ctrl Frame Cnt */ -#define XM_TXF_MCTRL 0x02a4 /* 32 bit ro Tx MAC Ctrl Frame Counter */ -#define XM_TXF_SNG_COL 0x02a8 /* 32 bit ro Tx Single Colliosion Counter */ -#define XM_TXF_MUL_COL 0x02ac /* 32 bit ro Tx Multiple Collision Counter */ -#define XM_TXF_ABO_COL 0x02b0 /* 32 bit ro Tx aborted due to Exessive Col*/ -#define XM_TXF_LAT_COL 0x02b4 /* 32 bit ro Tx Late Collision Counter */ -#define XM_TXF_DEF 0x02b8 /* 32 bit ro Tx Deferred Frame Counter */ -#define XM_TXF_EX_DEF 0x02bc /* 32 bit ro Tx Excessive Deferall Counter */ -#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit ro Tx FIFO Underrun Event Cnt */ -#define XM_TXE_CS_ERR 0x02c4 /* 32 bit ro Tx Carrier Sence Error Cnt */ -#define XM_TXP_UTIL 0x02c8 /* 32 bit ro Tx Utilization in % */ +#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */ +#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/ +#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */ +#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */ +#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */ +#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */ +#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */ +#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */ +#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */ +#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */ +#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */ +#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */ +#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */ +#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */ +#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */ +#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */ +#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */ +#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */ +#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */ /* 0x02cc - 0x02ce: reserved */ -#define XM_TXF_64B 0x02d0 /* 32 bit ro 64 Byte Tx Frame Counter */ -#define XM_TXF_127B 0x02d4 /* 32 bit ro 65-127 Byte Tx Frame Counter */ -#define XM_TXF_255B 0x02d8 /* 32 bit ro 128-255 Byte Tx Frame Counter */ -#define XM_TXF_511B 0x02dc /* 32 bit ro 256-511 Byte Tx Frame Counter */ -#define XM_TXF_1023B 0x02e0 /* 32 bit ro 512-1023 Byte Tx Frame Counter*/ -#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit ro 1024-MaxSize Byte Tx Frame Cnt*/ +#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */ +#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */ +#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */ +#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */ +#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/ +#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/ /* 0x02e8 - 0x02fe: reserved */ -#define XM_RXF_OK 0x0300 /* 32 bit ro Frames Received OK */ -#define XM_RXO_OK_HI 0x0304 /* 32 bit ro Octets Received OK High Cnt */ -#define XM_RXO_OK_LO 0x0308 /* 32 bit ro Octets Received OK Low Counter*/ -#define XM_RXF_BC_OK 0x030c /* 32 bit ro Broadcast Frames Received OK */ -#define XM_RXF_MC_OK 0x0310 /* 32 bit ro Multicast Frames Received OK */ -#define XM_RXF_UC_OK 0x0314 /* 32 bit ro Unicast Frames Received OK */ -#define XM_RXF_MPAUSE 0x0318 /* 32 bit ro Rx Pause MAC Ctrl Frame Cnt */ -#define XM_RXF_MCTRL 0x031c /* 32 bit ro Rx MAC Ctrl Frame Counter */ -#define XM_RXF_INV_MP 0x0320 /* 32 bit ro Rx invalid Pause Frame Cnt */ -#define XM_RXF_INV_MOC 0x0324 /* 32 bit ro Rx Frames with inv. MAC Opcode*/ -#define XM_RXE_BURST 0x0328 /* 32 bit ro Rx Burst Event Counter */ -#define XM_RXE_FMISS 0x032c /* 32 bit ro Rx Missed Frames Event Cnt */ -#define XM_RXF_FRA_ERR 0x0330 /* 32 bit ro Rx Framing Error Counter */ -#define XM_RXE_FIFO_OV 0x0334 /* 32 bit ro Rx FIFO overflow Event Cnt */ -#define XM_RXF_JAB_PKT 0x0338 /* 32 bit ro Rx Jabber Packet Frame Cnt */ -#define XM_RXE_CAR_ERR 0x033c /* 32 bit ro Rx Carrier Event Error Cnt */ -#define XM_RXF_LEN_ERR 0x0340 /* 32 bit ro Rx in Range Length Error */ -#define XM_RXE_SYM_ERR 0x0344 /* 32 bit ro Rx Symbol Error Counter */ -#define XM_RXE_SHT_ERR 0x0348 /* 32 bit ro Rx Short Event Error Cnt */ -#define XM_RXE_RUNT 0x034c /* 32 bit ro Rx Runt Event Counter */ -#define XM_RXF_LNG_ERR 0x0350 /* 32 bit ro Rx Frame too Long Error Cnt */ -#define XM_RXF_FCS_ERR 0x0354 /* 32 bit ro Rx Frame Check Seq. Error Cnt */ +#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */ +#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */ +#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/ +#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */ +#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */ +#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */ +#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */ +#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */ +#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */ +#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/ +#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */ +#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */ +#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */ +#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */ +#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */ +#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */ +#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */ +#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */ +#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */ +#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */ +#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */ +#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */ /* 0x0358 - 0x035a: reserved */ -#define XM_RXF_CEX_ERR 0x035c /* 32 bit ro Rx Carrier Ext Error Frame Cnt*/ -#define XM_RXP_UTIL 0x0360 /* 32 bit ro Rx Utilization in % */ +#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/ +#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */ /* 0x0364 - 0x0366: reserved */ -#define XM_RXF_64B 0x0368 /* 32 bit ro 64 Byte Rx Frame Counter */ -#define XM_RXF_127B 0x036c /* 32 bit ro 65-127 Byte Rx Frame Counter */ -#define XM_RXF_255B 0x0370 /* 32 bit ro 128-255 Byte Rx Frame Counter */ -#define XM_RXF_511B 0x0374 /* 32 bit ro 256-511 Byte Rx Frame Counter */ -#define XM_RXF_1023B 0x0378 /* 32 bit ro 512-1023 Byte Rx Frame Counter*/ -#define XM_RXF_MAX_SZ 0x037c /* 32 bit ro 1024-MaxSize Byte Rx Frame Cnt*/ +#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */ +#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */ +#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */ +#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */ +#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/ +#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/ /* 0x02e8 - 0x02fe: reserved */ @@ -279,104 +350,104 @@ * XMAC Bit Definitions * * If the bit access behaviour differs from the register access behaviour - * (r/w, ro) this is docomented after the bit number. The following bit - * access behaviours are used: + * (r/w, r/o) this is documented after the bit number. + * The following bit access behaviours are used: * (sc) self clearing * (ro) read only */ -/* XM_MMU_CMD 16 bit r/w MMU Comamnd Register */ +/* XM_MMU_CMD 16 bit r/w MMU Command Register */ /* Bit 15..13: reserved */ #define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */ #define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */ #define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */ -#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */ - /* Bit 8: reserved */ -#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */ -#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */ -#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */ -#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */ -#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */ -#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Lookback Mode */ -#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */ -#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */ +#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */ + /* Bit 8: reserved */ +#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */ +#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */ +#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */ +#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */ +#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */ +#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */ +#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */ +#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */ /* XM_TX_CMD 16 bit r/w Transmit Command Register */ /* Bit 15..7: reserved */ -#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (tx Bk2Bk)*/ -#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */ -#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */ -#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */ -#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */ -#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */ -#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */ +#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/ +#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */ +#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */ +#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */ +#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */ +#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */ +#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */ /* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */ /* Bit 15..5: reserved */ -#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */ +#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */ /* XM_TX_STIME 16 bit r/w Transmit Slottime Register */ /* Bit 15..7: reserved */ -#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */ +#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */ /* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */ /* Bit 15..8: reserved */ -#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */ +#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */ /* XM_RX_CMD 16 bit r/w Receive Command Register */ /* Bit 15..9: reserved */ -#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */ +#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */ /* inrange error packets */ -#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */ +#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */ /* jumbo packets */ -#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */ -#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */ -#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */ -#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */ -#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */ -#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of rx frames */ -#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */ +#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */ +#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */ +#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */ +#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */ +#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */ +#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */ +#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */ /* XM_PHY_ADDR 16 bit r/w PHY Address Register */ /* Bit 15..5: reserved */ -#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */ +#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */ /* XM_GP_PORT 32 bit r/w General Purpose Port Register */ /* Bit 31..7: reserved */ -#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto Negotiation in Progress */ -#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */ - /* Bit 4: reserved */ -#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */ -#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */ - /* Bit 1: reserved */ -#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */ +#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */ +#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */ + /* Bit 4: reserved */ +#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */ +#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */ + /* Bit 1: reserved */ +#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */ /* XM_IMSK 16 bit r/w Interrupt Mask Register */ -/* XM_ISRC 16 bit ro Interrupt Status Register */ +/* XM_ISRC 16 bit r/o Interrupt Status Register */ /* Bit 15: reserved */ #define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */ #define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */ #define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */ #define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */ #define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */ -#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */ -#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */ -#define XM_IS_AND (1<<7) /* Bit 7: Auto Negotiation Done */ -#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */ -#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */ -#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */ -#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */ -#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */ -#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */ -#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */ +#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */ +#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */ +#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */ +#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */ +#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */ +#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */ +#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */ +#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */ +#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */ +#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */ #define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\ XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR)) @@ -384,50 +455,50 @@ /* XM_HW_CFG 16 bit r/w Hardware Config Register */ /* Bit 15.. 4: reserved */ -#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */ -#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/ - /* Bit 1: reserved */ -#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */ +#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */ +#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/ + /* Bit 1: reserved */ +#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */ /* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */ /* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */ /* Bit 15..10 reserved */ -#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */ +#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */ /* XM_TX_THR 16 bit r/w Tx Request Threshold */ /* XM_HT_THR 16 bit r/w Host Request Threshold */ -/* XM_RX_THR 16 bit r/w Receive Request Threshold */ +/* XM_RX_THR 16 bit r/w Rx Request Threshold */ /* Bit 15..11 reserved */ -#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Tx FIFO Watermark bits */ +#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */ -/* XM_TX_STAT 32 bit ro Tx Status LIFO Register */ +/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */ #define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */ #define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */ #define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */ #define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */ #define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */ -#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/ -#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */ -#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */ -#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */ -#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */ -#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */ -#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */ -#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */ -#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */ -#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */ +#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/ +#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */ +#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */ +#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */ +#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */ +#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */ +#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */ +#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */ +#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */ +#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */ /* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */ /* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */ /* Bit 15..11: reserved */ -#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */ +#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */ -/* XM_DEV_ID 32 bit ro Device ID Register */ -#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */ -#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */ +/* XM_DEV_ID 32 bit r/o Device ID Register */ +#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */ +#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */ /* XM_MODE 32 bit r/w Mode Register */ @@ -435,10 +506,10 @@ #define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */ #define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */ /* extern generated */ -#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode*/ -#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFOfull*/ +#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */ +#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */ /* intern generated */ -#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Lit En*/ +#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */ #define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */ #define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */ #define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */ @@ -447,40 +518,40 @@ #define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */ /* intern generated */ #define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */ -#define XM_MD_ENA_HSH (1L<<15) /* Bit 15: Enable Hashing */ +#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */ #define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */ #define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */ -#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frames */ +#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */ #define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */ -#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err F */ -#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frames */ -#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frames */ -#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frames */ -#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */ -#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */ -#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Boradcast */ -#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */ -#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */ -#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */ -#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */ - -#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) -#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ - XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) +#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */ +#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */ +#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */ +#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */ +#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */ +#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */ +#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */ +#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */ +#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */ +#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */ +#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */ + +#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) +#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ + XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ /* Bit 16..6: reserved */ -#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */ -#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */ -#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */ -#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */ -#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */ -#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */ +#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */ +#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */ +#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */ +#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */ +#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */ +#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */ -/* XM_RX_CNT_EV 32 bit ro Rx Counter Event Register */ +/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */ /* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */ -#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/ +#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/ #define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/ #define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/ #define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/ @@ -502,20 +573,20 @@ #define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */ #define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */ #define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */ -#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/ -#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */ -#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */ -#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/ -#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/ -#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */ -#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */ -#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/ -#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/ -#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */ +#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/ +#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */ +#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */ +#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/ +#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/ +#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */ +#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */ +#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/ +#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/ +#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */ -#define XMR_DEF_MSK 0x00000006L /* all bits excepting 1 and 2 */ +#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV) -/* XM_TX_CNT_EV 32 bit ro Tx Counter Event Register */ +/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */ /* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */ /* Bit 31..26: reserved */ #define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/ @@ -534,18 +605,18 @@ #define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/ #define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */ #define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */ -#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/ -#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/ -#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */ -#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */ -#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */ -#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */ -#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */ -#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/ -#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/ -#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */ +#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/ +#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/ +#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */ +#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */ +#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */ +#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */ +#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */ +#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/ +#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/ +#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */ -#define XMT_DEF_MSK 0x00000006L /* all bits excepting 1 and 2 */ +#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV) /* * Receive Frame Status Encoding @@ -559,16 +630,16 @@ /* Bit 12: reserved */ #define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */ #define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */ -#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */ -#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */ -#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */ -#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */ -#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */ -#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Error */ -#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Gaint Error */ -#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */ -#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */ -#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */ +#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */ +#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */ +#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */ +#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */ +#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */ +#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */ +#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */ +#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */ +#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */ +#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */ /* * XMR_FS_ERR will be set if @@ -584,102 +655,135 @@ /* * XMAC-PHY Registers, indirect addressed over the XMAC */ -#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */ -#define PHY_XMAC_ID0 0x02 /* 16 bit ro PHY ID0 Register */ -#define PHY_XMAC_ID1 0x03 /* 16 bit ro PHY ID1 Register */ -#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Autoneg Advertisement */ -#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit ro Link Partner Abi Reg */ -#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit ro Autoneg Expansion Reg */ -#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit ro Next Page Link P Reg */ +#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */ +#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */ +#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ +#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ +#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ +#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */ +#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ +#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */ +#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ /* 0x09 - 0x0e: reserved */ -#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit ro Ext Status Register */ -#define PHY_XMAC_RES_ABI 0x10 /* 16 bit ro PHY Resolved Ability */ +#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */ +#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */ /*----------------------------------------------------------------------------*/ /* * Broadcom-PHY Registers, indirect addressed over XMAC */ -#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_BCOM_STAT 0x01 /* 16 bit ro PHY Status Register */ -#define PHY_BCOM_ID0 0x02 /* 16 bit ro PHY ID0 Register */ -#define PHY_BCOM_ID1 0x03 /* 16 bit ro PHY ID1 Register */ -#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Autoneg Advertisement */ -#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit ro Link Part Ability Reg */ -#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit ro Autoneg Expansion Reg */ -#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit ro Next Page Link P Reg */ +#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */ +#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */ +#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ +#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ +#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ +#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ +#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ +#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */ +#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ /* Broadcom-specific registers */ -#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ -#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit ro 1000Base-T Status Reg */ +#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ +#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ /* 0x0b - 0x0e: reserved */ -#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit ro Extended Status Reg */ -#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */ -#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit ro PHY Extended Stat Reg */ -#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */ -#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carr Sense Cnt */ -#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */ +#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ +#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */ +#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */ +#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */ +#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carr Sense Cnt */ +#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */ /* 0x15 - 0x17: reserved */ -#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */ -#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit ro Auxiliary Stat Summary*/ -#define PHY_BCOM_INT_STAT 0x1a /* 16 bit ro Interrupt Status Reg */ -#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */ +#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */ +#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */ +#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */ +#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */ /* 0x1c: reserved */ /* 0x1d - 0x1f: test registers */ /*----------------------------------------------------------------------------*/ /* + * Marvel-PHY Registers, indirect addressed over GMAC + */ +#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */ +#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */ +#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ +#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ +#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ +#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ +#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ +#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */ +#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ + /* Marvel-specific registers */ +#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ +#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ + /* 0x0b - 0x0e: reserved */ +#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ +#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */ +#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */ +#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */ +#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */ +#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */ +#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */ +#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */ + /* 0x17: reserved */ +#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */ +#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */ +#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */ +#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */ +#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */ + /* 0x1d - 0x1f: reserved */ + +/*----------------------------------------------------------------------------*/ +/* * Level One-PHY Registers, indirect addressed over XMAC */ -#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_LONE_STAT 0x01 /* 16 bit ro PHY Status Register */ -#define PHY_LONE_ID0 0x02 /* 16 bit ro PHY ID0 Register */ -#define PHY_LONE_ID1 0x03 /* 16 bit ro PHY ID1 Register */ -#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Autoneg Advertisement */ -#define PHY_LONE_AUNE_LP 0x05 /* 16 bit ro Link Part Ability Reg */ -#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit ro Autoneg Expansion Reg */ -#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_LONE_NEPG_LP 0x08 /* 16 bit ro Next Page Link Partner*/ +#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */ +#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */ +#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ +#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ +#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ +#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ +#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ +#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */ +#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner*/ /* Level One-specific registers */ -#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/ -#define PHY_LONE_1000T_STAT 0x0a /* 16 bit ro 1000Base-T Status Reg */ +#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/ +#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ /* 0x0b -0x0e: reserved */ -#define PHY_LONE_EXT_STAT 0x0f /* 16 bit ro Extended Status Reg */ -#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/ -#define PHY_LONE_Q_STAT 0x11 /* 16 bit ro Quick Status Reg */ -#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */ -#define PHY_LONE_INT_STAT 0x13 /* 16 bit ro Interrupt Status Reg */ -#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */ -#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */ -#define PHY_LONE_CIM 0x16 /* 16 bit ro CIM Reg */ +#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ +#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/ +#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */ +#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */ +#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */ +#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */ +#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */ +#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */ /* 0x17 -0x1c: reserved */ /*----------------------------------------------------------------------------*/ /* * National-PHY Registers, indirect addressed over XMAC */ -#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */ -#define PHY_NAT_ID0 0x02 /* 16 bit ro PHY ID0 Register */ -#define PHY_NAT_ID1 0x03 /* 16 bit ro PHY ID1 Register */ -#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Autonegotiation Advertisement */ -#define PHY_NAT_AUNE_LP 0x05 /* 16 bit ro Link Partner Ability Reg */ -#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit ro Autonegotiation Expansion Reg */ -#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_NAT_NEPG_LP 0x08 /* 16 bit ro Next Page Link Partner Reg */ +#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */ +#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */ +#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ +#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ +#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ +#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */ +#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ +#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */ +#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */ /* National-specific registers */ -#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ -#define PHY_NAT_1000T_STAT 0x0a /* 16 bit ro 1000Base-T Status Reg */ +#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ +#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ /* 0x0b -0x0e: reserved */ -#define PHY_NAT_EXT_STAT 0x0f /* 16 bit ro Extended Status Register */ -#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit ro Extended Control Reg1 */ -#define PHY_NAT_Q_STAT1 0x11 /* 16 bit ro Quick Status Reg1 */ -#define PHY_NAT_10B_OP 0x12 /* 16 bit ro 10Base-T Operations Reg */ -#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit ro Extended Control Reg1 */ -#define PHY_NAT_Q_STAT2 0x14 /* 16 bit ro Quick Status Reg2 */ +#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */ +#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */ +#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */ +#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */ +#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */ +#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */ /* 0x15 -0x18: reserved */ -#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit ro PHY Address Register */ +#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */ /*----------------------------------------------------------------------------*/ @@ -691,131 +795,135 @@ * All other are general. */ -/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/ -/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/ -/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/ -#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY releated regs */ +/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/ +/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/ +/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/ +#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */ #define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */ #define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */ -#define PHY_CT_ANE (1<<12) /* Bit 12: Autonegotiation Enabled */ +#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */ #define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */ #define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */ -#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Autonegotiation */ -#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */ -#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collsion Test enabled */ -#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */ - /* Bit 5..0: reserved */ - -#define PHY_B_CT_SP1000 (1<<6) /* Bit 6: enable speed of 1000 MBit/s */ -#define PHY_B_CT_SP100 (1<<13) /* Bit 13: enable speed of 100 MBit/s */ -#define PHY_B_CT_SP10 (0) /* Bit 6/13 not set, speed of 10 MBit/s */ - -#define PHY_L_CT_SP1000 (1<<6) /* Bit 6: enable speed of 1000 MBit/s */ -#define PHY_L_CT_SP100 (1<<13) /* Bit 13: enable speed of 100 MBit/s */ -#define PHY_L_CT_SP10 (0) /* Bit 6/13 not set, speed of 10 MBit/s */ - - -/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/ -/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/ -/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/ +#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */ +#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */ +#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */ +#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */ + /* Bit 5..0: reserved */ + +#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */ +#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */ +#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */ + + +/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/ +/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/ +/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/ +/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/ /* Bit 15..9: reserved */ - /* (BC/L1) 100/10 MBit/s cap bits ignored*/ -#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */ - /* Bit 7: reserved */ -#define PHY_ST_PRE_SUB (1<<6) /* Bit 6: (BC/L1) preamble suppression */ -#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Autonegotiation Over */ -#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remode Fault Condition Occured*/ -#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Autonegotiation Capability */ -#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */ -#define PHY_ST_JAP_DET (1<<1) /* Bit 1: (BC/L1) Japper Detected */ -#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */ - - -/* PHY_XMAC_ID1 16 bit ro PHY ID1 Register */ -/* PHY_BCOM_ID1 16 bit ro PHY ID1 Register */ -/* PHY_LONE_ID1 16 bit ro PHY ID1 Register */ -#define PHY_I1_OUI (0x3f<<10) /* Bit 15..10: Organiz. Unique ID */ -#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */ -#define PHY_I1_REV (0x0f<<0) /* Bit 3.. 0: Revision Number */ + /* (BC/L1) 100/10 Mbps cap bits ignored*/ +#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */ + /* Bit 7: reserved */ +#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */ +#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */ +#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */ +#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */ +#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */ +#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */ +#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */ + + +/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */ +#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */ +#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */ +#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */ + +/* different Broadcom PHY Ids */ +#define PHY_BCOM_ID1_A1 0x6041 +#define PHY_BCOM_ID1_B2 0x6043 +#define PHY_BCOM_ID1_C0 0x6044 +#define PHY_BCOM_ID1_C5 0x6047 -/***** PHY_XMAC_AUNE_ADV 16 bit r/w Autoneg Advertisement *****/ -/***** PHY_XMAC_AUNE_LP 16 bit ro Link Partner Ability Reg *****/ +/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ #define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */ #define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */ -#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remode Fault Bits */ +#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */ /* Bit 11.. 9: reserved */ -#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */ -#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */ -#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */ - /* Bit 4.. 0: reserved */ +#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */ +#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */ +#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */ + /* Bit 4.. 0: reserved */ -/***** PHY_BCOM_AUNE_ADV 16 bit r/w Autoneg Advertisement *****/ -/***** PHY_BCOM_AUNE_LP 16 bit ro Link Partner Ability Reg *****/ +/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ /* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ /* Bit 14: reserved */ #define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */ /* Bit 12: reserved */ -#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymetric Pause */ +#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */ #define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */ - /* Bit 9..5: 100/10 BT cap bits ingnored */ -#define PHY_B_AN_SEL (0x1f<<0)/* Bit 4..0: Selector Field, 00001=Ethernet*/ + /* Bit 9..5: 100/10 BT cap bits ingnored */ +#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/ -/***** PHY_LONE_AUNE_ADV 16 bit r/w Autoneg Advertisement *****/ -/***** PHY_LONE_AUNE_LP 16 bit ro Link Partner Ability Reg *****/ +/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ /* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ /* Bit 14: reserved */ #define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */ /* Bit 12: reserved */ -#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymetric Pause */ +#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */ #define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */ - /* Bit 9..5: 100/10 BT cap bits ingnored */ -#define PHY_L_AN_SEL (0x1f<<0)/* Bit 4..0: Selector Field, 00001=Ethernet*/ + /* Bit 9..5: 100/10 BT cap bits ingnored */ +#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/ -/***** PHY_NAT_AUNE_ADV 16 bit r/w Autoneg Advertisement *****/ -/***** PHY_NAT_AUNE_LP 16 bit ro Link Partner Ability Reg *****/ +/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ /* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ /* Bit 14: reserved */ #define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */ /* Bit 12: reserved */ #define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */ #define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */ - /* Bit 9..5: 100/10 BT cap bits ingnored */ -#define PHY_N_AN_SEL (0x1f<<0)/* Bit 4..0: Selector Field, 00001=Ethernet*/ + /* Bit 9..5: 100/10 BT cap bits ingnored */ +#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/ /* field type definition for PHY_x_AN_SEL */ #define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */ -/***** PHY_XMAC_AUNE_EXP 16 bit ro Autoneg Expansion Reg *****/ - /* Bit 15..4: reserved */ -#define PHY_AN_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ -#define PHY_AN_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ -#define PHY_AN_RX_PG (1<<1) /* Bit 1: Page Received */ - /* Bit 0: reserved */ +/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ + /* Bit 15..4: reserved */ +#define PHY_AN_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ +#define PHY_AN_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ +#define PHY_AN_RX_PG (1<<1) /* Bit 1: Page Received */ + /* Bit 0: reserved */ -/***** PHY_BCOM_AUNE_EXP 16 bit ro Autoneg Expansion Reg *****/ +/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ /* Bit 15..5: reserved */ -#define PHY_B_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Autoneg Cap. */ - -/***** PHY_LONE_AUNE_EXP 16 bit ro Autoneg Expansion Reg *****/ -#define PHY_L_AN_BP (1<<5) /* Bit 5: Base Page Indication */ -#define PHY_L_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Autoneg Cap. */ - - -/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/ -/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/ -/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/ -/***** PHY_XMAC_NEPG_LP 16 bit ro Next Page Link Partner *****/ -/***** PHY_BCOM_NEPG_LP 16 bit ro Next Page Link Partner *****/ -/***** PHY_LONE_NEPG_LP 16 bit ro Next Page Link Partner *****/ +#define PHY_B_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ +/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ +/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ +/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ +#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ + +/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ +#define PHY_L_AN_BP (1<<5) /* Bit 5: Base Page Indication */ +#define PHY_L_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ +/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ +/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ +/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ +#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ + + +/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/ +/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/ +/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/ +/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/ +/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/ +/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/ #define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */ #define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack 1, for receiving a message*/ #define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */ @@ -826,66 +934,66 @@ /* * XMAC-Specific */ -/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/ +/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/ #define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */ #define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */ /* Bit 13..0: reserved */ -/***** PHY_XMAC_RES_ABI 16 bit ro PHY Resolved Ability *****/ +/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/ /* Bit 15..9: reserved */ -#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */ -#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */ -#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */ -#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */ -#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability missmatch */ - /* Bit 2..0: reserved */ +#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */ +#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */ +#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */ +#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */ +#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability missmatch */ + /* Bit 2..0: reserved */ /* * Remote Fault Bits (PHY_X_AN_RFB) encoding */ -#define X_RFB_OK (0<<12) /* Bit 12..13 No errors, Link OK */ -#define X_RFB_LF (1<<12) /* Bit 12..13 Link Failure */ -#define X_RFB_OFF (2<<12) /* Bit 12..13 Offline */ -#define X_RFB_AN_ERR (3<<12) /* Bit 12..13 Autonegotiation Error */ +#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */ +#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */ +#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */ +#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */ /* * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ -#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */ -#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */ -#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */ -#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */ +#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */ +#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */ +#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */ +#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */ /* * Broadcom-Specific */ -/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ -#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ -#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ -#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ - /* Bit 7..0: reserved */ - -/***** PHY_BCOM_1000T_STAT 16 bit ro 1000Base-T Status Reg *****/ -#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ -#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ -#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */ -#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ -#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ - /* Bit 9..8: reserved */ -#define PHY_B_1000S_IEC (255<<0)/* Bit 7..0: Idle Error Count */ +/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ +#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ +#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ +#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ +#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ +#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ +#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ + /* Bit 7..0: reserved */ + +/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ +#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ +#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ +#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ +#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */ +#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ +#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ + /* Bit 9..8: reserved */ +#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */ -/***** PHY_BCOM_EXT_STAT 16 bit ro Extended Status Register *****/ +/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/ #define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */ #define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */ #define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */ #define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */ /* Bit 11..0: reserved */ -/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/ +/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/ #define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */ #define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */ #define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */ @@ -901,9 +1009,9 @@ #define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */ #define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */ #define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */ -#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII Fifo Elasticy */ +#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */ -/***** PHY_BCOM_P_EXT_STAT 16 bit ro PHY Extended Status Reg *****/ +/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/ /* Bit 15..14: reserved */ #define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */ #define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */ @@ -920,20 +1028,20 @@ #define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */ #define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */ -/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ +/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ /* Bit 15..8: reserved */ -#define PHY_B_FC_CTR (255<<0)/* Bit 7..0: False Carrier Counter */ +#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */ -/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/ -#define PHY_B_RC_LOC (255<<8)/* Bit 15..8: Local Rx NOT_OK cnt */ -#define PHY_B_RC_REM (255<<0)/* Bit 7..0: Remote Rx NOT_OK cnt */ +/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/ +#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */ +#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */ -/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/ +/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/ #define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */ #define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */ #define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */ /* Bit 11: reserved */ -#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: tx test bit, always 1 */ +#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */ /* Bit 9.. 8: reserved */ #define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */ /* Bit 6: reserved */ @@ -942,14 +1050,14 @@ #define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */ /* Bit 2.. 0: reserved */ -/***** PHY_BCOM_AUX_STAT 16 bit ro Auxiliary Status Reg *****/ +/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/ #define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */ #define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */ #define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */ #define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */ #define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */ -#define PHY_B_AS_AN_RES (7<<8) /* Bit 10..8: AN HDC */ -#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault*/ +#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */ +#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */ #define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */ #define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */ #define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */ @@ -958,8 +1066,10 @@ #define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */ #define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */ -/***** PHY_BCOM_INT_STAT 16 bit ro Interrupt Status Reg *****/ -/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/ +#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT) + +/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/ +/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/ /* Bit 15: reserved */ #define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */ #define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */ @@ -979,125 +1089,123 @@ #define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) -/* - * Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding - */ -#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */ -#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */ -#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ -#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ +/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ +#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */ +#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */ +#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ +#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ /* * Resolved Duplex mode and Capabilities (Aux Status Summary Reg) */ -#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */ -#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */ +#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */ +#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */ /* others: 100/10: invalid for us */ /* * Level One-Specific */ -/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ -#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ -#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ -#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ - /* Bit 7..0: reserved */ - -/***** PHY_LONE_1000T_STAT 16 bit ro 1000Base-T Status Reg *****/ -#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ -#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ -#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/ -#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ -#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ - /* Bit 9..8: reserved */ -#define PHY_B_1000S_IEC (255<<0)/* Bit 7..0: Idle Error Count */ +/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ +#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ +#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ +#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ +#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ +#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ +#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ + /* Bit 7..0: reserved */ + +/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ +#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ +#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ +#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ +#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/ +#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ +#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ + /* Bit 9..8: reserved */ +#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */ -/***** PHY_LONE_EXT_STAT 16 bit ro Extended Status Register *****/ +/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/ #define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */ #define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */ #define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */ #define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */ /* Bit 11..0: reserved */ -/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/ +/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/ #define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */ /* Bit 14: reserved */ #define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */ #define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */ #define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */ #define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */ -#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */ -#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */ -#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */ -#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */ -#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */ -#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */ -#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */ -#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */ -#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */ -#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */ +#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */ +#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */ +#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */ +#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */ +#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */ +#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */ +#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */ +#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */ +#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */ +#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */ -/***** PHY_LONE_Q_STAT 16 bit ro Quick Status Reg *****/ +/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/ #define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */ #define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */ #define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */ #define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */ #define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */ -#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */ -#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */ -#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */ -#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */ -#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */ -#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */ -#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */ -#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */ +#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */ +#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */ +#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */ +#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */ +#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */ +#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */ +#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */ +#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */ -/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/ -/***** PHY_LONE_INT_STAT 16 bit ro Interrupt Status Reg *****/ +/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/ +/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/ /* Bit 15..14: reserved */ -#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Autoneg fault */ +#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */ /* Bit 12: not described */ #define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */ #define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used*/ -#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade*/ -#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */ -#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */ -#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */ -#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */ -#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */ -#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */ -#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */ -#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */ -#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */ +#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade*/ +#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */ +#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */ +#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */ +#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */ +#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */ +#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */ +#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */ +#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */ +#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */ /* int. mask */ #define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN) -/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/ +/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/ #define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */ #define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */ #define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */ -#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */ -#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */ -#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */ -#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */ -#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */ -#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */ +#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */ +#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */ +#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */ +#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */ +#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */ +#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */ -/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/ +/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/ #define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */ /* Bit 14: reserved */ #define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */ #define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */ /* Bit 11: reserved */ #define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/ - /* Bit 9..0: not described */ + /* Bit 9..0: not described */ -/***** PHY_LONE_CIM 16 bit ro CIM Reg *****/ +/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/ #define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */ #define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */ @@ -1105,37 +1213,37 @@ /* * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding */ -#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */ -#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */ -#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ -#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ +#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */ +#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */ +#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ +#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ /* * National-Specific */ -/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ -#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ -#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ -#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ -#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymetric Pause Cap. */ - /* Bit 6..0: reserved */ - -/***** PHY_NAT_1000T_STAT 16 bit ro 1000Base-T Status Reg *****/ -#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ -#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ -#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/ -#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ -#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ -#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */ - /* Bit 8: reserved */ -#define PHY_N_1000S_IEC (255<<0)/* Bit 7..0: Idle Error Count */ +/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ +#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ +#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ +#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ +#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ +#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ +#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ +#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */ + /* Bit 6..0: reserved */ + +/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ +#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ +#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ +#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ +#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/ +#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ +#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ +#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */ + /* Bit 8: reserved */ +#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */ -/***** PHY_NAT_EXT_STAT 16 bit ro Extended Status Register *****/ +/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/ #define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */ #define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */ #define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */ @@ -1143,12 +1251,461 @@ /* Bit 11..0: reserved */ /* todo: those are still missing */ -/***** PHY_NAT_EXT_CTRL1 16 bit ro Extended Control Reg1 *****/ -/***** PHY_NAT_Q_STAT1 16 bit ro Quick Status Reg1 *****/ -/***** PHY_NAT_10B_OP 16 bit ro 10Base-T Operations Reg *****/ -/***** PHY_NAT_EXT_CTRL2 16 bit ro Extended Control Reg1 *****/ -/***** PHY_NAT_Q_STAT2 16 bit ro Quick Status Reg2 *****/ -/***** PHY_NAT_PHY_ADDR 16 bit ro PHY Address Register *****/ +/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/ +/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/ +/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/ +/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/ +/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/ +/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/ + +/* + * Marvell-Specific + */ +/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */ + /* Bit 14: reserved */ +#define PHY_M_AN_RF BIT_13 /* Remote Fault */ + /* Bit 12: reserved */ +#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */ +#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */ +#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */ +#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */ +#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */ +#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */ + +/* special defines for FIBER (88E1011S only) */ +#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */ +#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */ +#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */ +#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */ + +/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */ +#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */ +#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */ +#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */ +#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */ + +/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ +#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ +#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */ +#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */ +#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */ +#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ +#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ + /* Bit 7..0: reserved */ + +/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/ + +#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */ +#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */ +#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */ +#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */ +#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */ +#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */ +#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */ +#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */ +#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */ +#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */ +#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */ +#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */ + + +/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/ +#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */ +#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */ +#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */ +#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */ +#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */ +#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */ +#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */ +#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */ +#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */ +#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */ +#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */ +#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */ +#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */ +#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */ +#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */ +#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */ + +#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN) + +/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/ +/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/ +#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */ +#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */ +#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */ +#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */ +#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */ +#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */ +#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */ +#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */ +#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */ +#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */ +#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */ +#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */ + /* Bit 3..2: reserved */ +#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */ +#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */ + +#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \ + PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR) + +/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/ +#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */ +#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */ +#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */ + +#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */ +#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */ +#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */ + +#define MAC_TX_CLK_0_MHZ 2 +#define MAC_TX_CLK_2_5_MHZ 6 +#define MAC_TX_CLK_25_MHZ 7 + +/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/ +#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */ + +#define PHY_M_LED_BL_RATE(x) SHIFT12(x) /* Bit 12..14: Blink Rate */ + +/* values for PHY_M_LED_BL_RATE() */ +#define BL_DEFAULT 0 /* no pulse stretching */ +#define BL_21MS 1 /* 21 ms to 42ms */ +#define BL_42MS 2 /* 42 ms to 84ms */ +#define BL_84MS 3 /* 84 ms to 170ms */ +#define BL_170MS 4 /* 170 ms to340ms */ +#define BL_340MS 5 /* 340 ms to670ms */ +#define BL_670MS 6 /* 670 ms to 1.3s */ +#define BL_1300MS 7 /* 1.3s to 2.7s */ + +#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */ + +#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4..3: Link Control */ +#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */ +#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */ +#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */ + +/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ +#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */ +#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */ +#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */ +#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */ +#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */ +#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */ + +#define MO_LED_NORM 0 +#define MO_LED_BLINK 1 +#define MO_LED_OFF 2 +#define MO_LED_ON 3 + +/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/ + /* Bit 15.. 7: reserved */ +#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */ +#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */ +#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */ +#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */ +#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */ + +/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/ +#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */ +#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */ + /* Bit 12.. 8: reserved */ +#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */ + +/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */ +#define CABD_STAT_NORMAL 0 +#define CABD_STAT_SHORT 1 +#define CABD_STAT_OPEN 2 +#define CABD_STAT_FAIL 3 + + +/* + * GMAC registers + * + * The GMAC registers are 16 or 32 bits wide. + * The GMACs host processor interface is 16 bits wide, + * therefore ALL registers will be addressed with 16 bit accesses. + * + * The following macros are provided to access the GMAC registers + * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(), + * GM_INHASH(), and GM_OUTHASH(). + * The macros are defined in SkGeHw.h. + * + * Note: NA reg = Network Address e.g DA, SA etc. + * + */ + +/* Port Registers */ +#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */ +#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */ +#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */ +#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */ +#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow Control */ +#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */ +#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */ + +/* Source Address Registers */ +#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */ +#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */ +#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */ +#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */ +#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */ +#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */ + +/* Multicast Address Hash Registers */ +#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */ +#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */ +#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */ +#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */ + +/* Interrupt Source Registers */ +#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */ +#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */ +#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */ + +/* Interrupt Mask Registers */ +#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */ +#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */ +#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */ + +/* Serial Management Interface (SMI) Registers */ +#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */ +#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */ +#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */ + +/* MIB Counters */ +#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ +#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ + +/* + * MIB Counters base address definitions (low word) - + * use offset 4 for access to high word (32 bit r/o) + */ +#define GM_RXF_UC_OK \ + (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */ +#define GM_RXF_BC_OK \ + (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */ +#define GM_RXF_MPAUSE \ + (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */ +#define GM_RXF_MC_OK \ + (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */ +#define GM_RXF_FCS_ERR \ + (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */ + /* GM_MIB_CNT_BASE + 40: reserved */ +#define GM_RXO_OK_LO \ + (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */ +#define GM_RXO_OK_HI \ + (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */ +#define GM_RXO_ERR_LO \ + (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */ +#define GM_RXO_ERR_HI \ + (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */ +#define GM_RXF_SHT \ + (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */ +#define GM_RXE_FRAG \ + (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Receeived with FCS Err */ +#define GM_RXF_64B \ + (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */ +#define GM_RXF_127B \ + (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */ +#define GM_RXF_255B \ + (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */ +#define GM_RXF_511B \ + (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */ +#define GM_RXF_1023B \ + (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */ +#define GM_RXF_1518B \ + (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */ +#define GM_RXF_MAX_SZ \ + (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */ +#define GM_RXF_LNG_ERR \ + (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */ +#define GM_RXF_JAB_PKT \ + (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */ + /* GM_MIB_CNT_BASE + 168: reserved */ +#define GM_RXE_FIFO_OV \ + (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */ + /* GM_MIB_CNT_BASE + 184: reserved */ +#define GM_TXF_UC_OK \ + (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */ +#define GM_TXF_BC_OK \ + (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */ +#define GM_TXF_MPAUSE \ + (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */ +#define GM_TXF_MC_OK \ + (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */ +#define GM_TXO_OK_LO \ + (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */ +#define GM_TXO_OK_HI \ + (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */ +#define GM_TXF_64B \ + (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */ +#define GM_TXF_127B \ + (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */ +#define GM_TXF_255B \ + (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */ +#define GM_TXF_511B \ + (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */ +#define GM_TXF_1023B \ + (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */ +#define GM_TXF_1518B \ + (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */ +#define GM_TXF_MAX_SZ \ + (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */ + /* GM_MIB_CNT_BASE + 296: reserved */ +#define GM_TXF_COL \ + (GM_MIB_CNT_BASE + 304) /* Tx Collision */ +#define GM_TXF_LAT_COL \ + (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */ +#define GM_TXF_ABO_COL \ + (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */ +#define GM_TXF_MUL_COL \ + (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */ +#define GM_TXF_SNG_COL \ + (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */ +#define GM_TXE_FIFO_UR \ + (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */ + +/*----------------------------------------------------------------------------*/ +/* + * GMAC Bit Definitions + * + * If the bit access behaviour differs from the register access behaviour + * (r/w, r/o) this is documented after the bit number. + * The following bit access behaviours are used: + * (sc) self clearing + * (r/o) read only + */ + +/* GM_GP_STAT 16 bit r/o General Purpose Status Register */ + +#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */ +#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */ +#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow Control Mode Disabled */ +#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */ +#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */ +#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */ +#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */ +#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */ + /* Bit 7..6: reserved */ +#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */ +#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */ +#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */ +#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow Control Mode Disabled */ +#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */ + /* Bit 0: reserved */ + +/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ + /* Bit 15: reserved */ +#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */ +#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow Control Mode */ +#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */ +#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */ +#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */ +#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */ +#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */ +#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */ +#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */ +#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */ +#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow Control Mode */ +#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */ +#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update for Duplex */ +#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update for Flow-c. */ +#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update for Speed */ + +#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) +#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\ + GM_GPCR_AU_SPD_DIS) + +/* GM_TX_CTRL 16 bit r/w Transmit Control Register */ + +#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */ +#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */ +#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */ +#define GM_TXCR_COL_THR (4<<10) /* Bit 12..10: Collision Threshold */ + +/* GM_RX_CTRL 16 bit r/w Receive Control Register */ +#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */ +#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */ +#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */ +#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */ + +/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ +#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */ +#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */ +#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */ + /* Bit 3..0: reserved */ +#define JAM_LEN_VAL(x) SHIFT14(x) +#define JAM_IPG_VAL(x) SHIFT9(x) +#define IPG_JAM_DATA(x) SHIFT4(x) + +/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */ +#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder */ +#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive transmit trials */ +#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Length) */ +#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Length) */ + /* Bit 7..5: reserved */ +#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ + +#define DATA_BLIND_VAL(x) SHIFT11(x) +#define DATA_BLIND_FAST_ETH 0x1c +#define DATA_BLIND_GIGABIT 4 + +#define IPG_VAL_FAST_ETH 0x1e +#define IPG_VAL_GIGABIT 6 + +/* GM_SMI_CTRL 16 bit r/w SMI Control Register */ + +#define GM_SMI_CT_PHY_AD(x) SHIFT11(x) +#define GM_SMI_CT_REG_AD(x) SHIFT6(x) +#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/ +#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */ +#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */ + /* Bit 2..0: reserved */ + +/* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ + /* Bit 15..6: reserved */ +#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */ +#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */ + /* Bit 3..0: reserved */ + +/* Receive Frame Status Encoding */ +#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */ + /* Bit 15..14: reserved */ +#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */ +#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */ +#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */ +#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */ +#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */ +#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */ +#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */ +#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */ +#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */ +#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */ +#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */ + /* Bit 2: reserved */ +#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */ +#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */ + +/* + * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) + */ +#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \ + GMR_FS_LONG_ERR | \ + GMR_FS_MII_ERR | \ + GMR_FS_BAD_FC | \ + GMR_FS_GOOD_FC | \ + GMR_FS_JABBER) + +/* Rx GMAC FIFO Flush Mask (default) */ +#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \ + GMR_FS_RX_FF_OV | \ + GMR_FS_MII_ERR | \ + GMR_FS_BAD_FC | \ + GMR_FS_GOOD_FC | \ + GMR_FS_UN_SIZE | \ + GMR_FS_JABBER) /* typedefs *******************************************************************/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skaddr.c linux.21pre4-ac6/drivers/net/sk98lin/skaddr.c --- linux.21pre4/drivers/net/sk98lin/skaddr.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skaddr.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skaddr.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.40 $ - * Date: $Date: 2001/02/14 14:04:59 $ + * Version: $Revision: 1.47 $ + * Date: $Date: 2002/09/17 06:31:10 $ * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,39 @@ * History: * * $Log: skaddr.c,v $ + * Revision 1.47 2002/09/17 06:31:10 tschilli + * Handling of SK_PROM_MODE_ALL_MC flag in SkAddrGmacMcUpdate() + * and SkAddrGmacPromiscuousChange() fixed. + * Editorial changes. + * + * Revision 1.46 2002/08/22 07:55:41 tschilli + * New function SkGmacMcHash() for GMAC multicast hashing algorithm added. + * Editorial changes. + * + * Revision 1.45 2002/08/15 12:29:35 tschilli + * SkAddrGmacMcUpdate() and SkAddrGmacPromiscuousChange() changed. + * + * Revision 1.44 2002/08/14 12:18:03 rschmidt + * Replaced direct handling of MAC Hashing (XMAC and GMAC) + * with routine SkMacHashing(). + * Replaced wrong 3rd para 'i' with 'PortNumber' in SkMacPromiscMode(). + * + * Revision 1.43 2002/08/13 09:37:43 rschmidt + * Corrected some SK_DBG_MSG outputs. + * Replaced wrong 2nd para pAC with IoC in SkMacPromiscMode(). + * Editorial changes. + * + * Revision 1.42 2002/08/12 11:24:36 rschmidt + * Remove setting of logical MAC address GM_SRC_ADDR_2 in SkAddrInit(). + * Replaced direct handling of MAC Promiscuous Mode (XMAC and GMAC) + * with routine SkMacPromiscMode(). + * Editorial changes. + * + * Revision 1.41 2002/06/10 13:52:18 tschilli + * Changes for handling YUKON. + * All changes are internally and not visible to the programmer + * using this module. + * * Revision 1.40 2001/02/14 14:04:59 rassmann * Editorial changes. * @@ -166,13 +199,13 @@ * Description: * * This module is intended to manage multicast addresses, address override, - * and promiscuous mode on GEnesis adapters. + * and promiscuous mode on GEnesis and Yukon adapters. * * Address Layout: * port address: physical MAC address - * 1st exact match: logical MAC address - * 2nd exact match: RLMT multicast - * exact match 3-13: OS-specific multicasts + * 1st exact match: logical MAC address (GEnesis only) + * 2nd exact match: RLMT multicast (GEnesis only) + * exact match 3-13: OS-specific multicasts (GEnesis only) * * Include File Hierarchy: * @@ -183,7 +216,7 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skaddr.c,v 1.40 2001/02/14 14:04:59 rassmann Exp $ (C) SysKonnect."; + "@(#) $Id: skaddr.c,v 1.47 2002/09/17 06:31:10 tschilli Exp $ (C) SysKonnect."; #endif /* !defined(lint) */ #define __SKADDR_C @@ -199,6 +232,8 @@ /* defines ********************************************************************/ +#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */ +#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */ #define HASH_BITS 6 /* #bits in hash */ #define SK_MC_BIT 0x01 @@ -247,7 +282,7 @@ * All permanent MAC addresses are read from EPROM. * If the current MAC addresses are not already set in software, * they are set to the values of the permanent addresses. - * The current addresses are written to the corresponding XMAC. + * The current addresses are written to the corresponding MAC. * * * SK_INIT_RUN @@ -266,38 +301,26 @@ SK_IOC IoC, /* I/O context */ int Level) /* initialization level */ { - int j; - SK_U32 i; - SK_U8 *InAddr; - SK_U16 *OutAddr; + int j; + SK_U32 i; + SK_U8 *InAddr; + SK_U16 *OutAddr; SK_ADDR_PORT *pAPort; switch (Level) { case SK_INIT_DATA: - SK_MEMSET((char *)&pAC->Addr, 0, sizeof(SK_ADDR)); + SK_MEMSET((char *) &pAC->Addr, 0, sizeof(SK_ADDR)); for (i = 0; i < SK_MAX_MACS; i++) { pAPort = &pAC->Addr.Port[i]; pAPort->PromMode = SK_PROM_MODE_NONE; - - pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; - pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; - pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; - pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; - -#if 0 - /* Don't do this here ... */ - - /* Reset Promiscuous mode. */ - (void)SkAddrPromiscuousChange( - pAC, - IoC, - i, - SK_PROM_MODE_NONE); -#endif /* 0 */ + + pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; + pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; + pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; + pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; } - -#ifdef DEBUG +#ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { @@ -305,7 +328,6 @@ } } #endif /* DEBUG */ - /* pAC->Addr.InitDone = SK_INIT_DATA; */ break; @@ -313,8 +335,7 @@ for (i = 0; i < SK_MAX_NETS; i++) { pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; } - -#ifdef DEBUG +#ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { @@ -322,10 +343,10 @@ } } #endif /* DEBUG */ - + /* Read permanent logical MAC address from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { - InAddr = (SK_U8 *)&pAC->Addr.Net[0].PermanentMacAddress.a[j]; + InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j]; SK_IN8(IoC, B2_MAC_1 + j, InAddr); } @@ -339,7 +360,6 @@ /* Set the current logical MAC address. */ pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] = pAC->Addr.Net[0].CurrentMacAddress; - #if SK_MAX_NETS > 1 /* Set logical MAC address for net 2 to (log | 3). */ if (!pAC->Addr.Net[1].CurrentMacAddressSet) { @@ -353,43 +373,36 @@ } #endif /* SK_MAX_NETS > 1 */ -#ifdef xDEBUG - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_INIT, - ("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.PermanentMacAddress.a[0], - pAC->Addr.PermanentMacAddress.a[1], - pAC->Addr.PermanentMacAddress.a[2], - pAC->Addr.PermanentMacAddress.a[3], - pAC->Addr.PermanentMacAddress.a[4], - pAC->Addr.PermanentMacAddress.a[5])) - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_INIT, - ("Logical MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.CurrentMacAddress.a[0], - pAC->Addr.CurrentMacAddress.a[1], - pAC->Addr.CurrentMacAddress.a[2], - pAC->Addr.CurrentMacAddress.a[3], - pAC->Addr.CurrentMacAddress.a[4], - pAC->Addr.CurrentMacAddress.a[5])) +#ifdef DEBUG + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, + ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", + i, + pAC->Addr.Net[i].PermanentMacAddress.a[0], + pAC->Addr.Net[i].PermanentMacAddress.a[1], + pAC->Addr.Net[i].PermanentMacAddress.a[2], + pAC->Addr.Net[i].PermanentMacAddress.a[3], + pAC->Addr.Net[i].PermanentMacAddress.a[4], + pAC->Addr.Net[i].PermanentMacAddress.a[5])) + + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, + ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", + i, + pAC->Addr.Net[i].CurrentMacAddress.a[0], + pAC->Addr.Net[i].CurrentMacAddress.a[1], + pAC->Addr.Net[i].CurrentMacAddress.a[2], + pAC->Addr.Net[i].CurrentMacAddress.a[3], + pAC->Addr.Net[i].CurrentMacAddress.a[4], + pAC->Addr.Net[i].CurrentMacAddress.a[5])) + } #endif /* DEBUG */ -#if 0 - /* Don't do this here ... */ - - (void)SkAddrMcUpdate(pAC, IoC, pAC->Addr.ActivePort); -#endif /* 0 */ - - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { pAPort = &pAC->Addr.Port[i]; /* Read permanent port addresses from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { - InAddr = (SK_U8 *)&pAPort->PermanentMacAddress.a[j]; + InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j]; SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr); } @@ -403,27 +416,27 @@ pAPort->CurrentMacAddressSet = SK_TRUE; } - /* Set port's current MAC addresses. */ - OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0]; - XM_OUTADDR(IoC, i, XM_SA, OutAddr); - -#ifdef xDEBUG - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_INIT, - ("Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", + /* Set port's current physical MAC address. */ + OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + XM_OUTADDR(IoC, i, XM_SA, OutAddr); + } + else { + GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr); + } +#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, + ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAPort->PermanentMacAddress.a[0], pAPort->PermanentMacAddress.a[1], pAPort->PermanentMacAddress.a[2], pAPort->PermanentMacAddress.a[3], pAPort->PermanentMacAddress.a[4], pAPort->PermanentMacAddress.a[5])) - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_INIT, - ("Phsical MAC Address: %02X %02X %02X %02X %02X %02X\n", + + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, + ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAPort->CurrentMacAddress.a[0], pAPort->CurrentMacAddress.a[1], pAPort->CurrentMacAddress.a[2], @@ -436,7 +449,7 @@ break; case SK_INIT_RUN: -#ifdef DEBUG +#ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { @@ -453,6 +466,7 @@ } return (SK_ADDR_SUCCESS); + } /* SkAddrInit */ @@ -461,11 +475,14 @@ * SkAddrMcClear - clear the multicast table * * Description: - * This routine clears the multicast table - * (either entry 2 or entries 3-16 and InexactFilter) of the given port. + * This routine clears the multicast table. + * * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated * immediately. * + * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according + * to the adapter in use. The real work is done there. + * * Context: * runtime, pageable * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY @@ -481,21 +498,59 @@ SK_U32 PortNumber, /* Index of affected port */ int Flags) /* permanent/non-perm, sw-only */ { - int i; - - if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { + int ReturnCode; + + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); + } + else { + ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); + } + + return (ReturnCode); + +} /* SkAddrMcClear */ + + +/****************************************************************************** + * + * SkAddrXmacMcClear - clear the multicast table + * + * Description: + * This routine clears the multicast table + * (either entry 2 or entries 3-16 and InexactFilter) of the given port. + * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated + * immediately. + * + * Context: + * runtime, pageable + * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY + * may be called after SK_INIT_IO without limitation + * + * Returns: + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrXmacMcClear( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* Index of affected port */ +int Flags) /* permanent/non-perm, sw-only */ +{ + int i; - if (Flags & SK_ADDR_PERMANENT) { + if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ /* Clear RLMT multicast addresses. */ pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; } else { /* not permanent => DRV */ - /* Clear InexactFilter. */ - + /* Clear InexactFilter */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; } @@ -506,20 +561,114 @@ } if (!(Flags & SK_MC_SW_ONLY)) { - (void)SkAddrMcUpdate(pAC, IoC, PortNumber); + (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber); } return (SK_ADDR_SUCCESS); -} /* SkAddrMcClear */ + +} /* SkAddrXmacMcClear */ + + +/****************************************************************************** + * + * SkAddrGmacMcClear - clear the multicast table + * + * Description: + * This routine clears the multicast hashing table (InexactFilter) + * (either the RLMT or the driver bits) of the given port. + * + * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated + * immediately. + * + * Context: + * runtime, pageable + * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY + * may be called after SK_INIT_IO without limitation + * + * Returns: + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrGmacMcClear( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* Index of affected port */ +int Flags) /* permanent/non-perm, sw-only */ +{ + int i; + +#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) +#endif /* DEBUG */ + + /* Clear InexactFilter */ + for (i = 0; i < 8; i++) { + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; + } + + if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ + + /* Copy DRV bits to InexactFilter. */ + for (i = 0; i < 8; i++) { + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; + + /* Clear InexactRlmtFilter. */ + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; + + } + } + else { /* not permanent => DRV */ + + /* Copy RLMT bits to InexactFilter. */ + for (i = 0; i < 8; i++) { + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; + + /* Clear InexactDrvFilter. */ + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; + } + } + +#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) +#endif /* DEBUG */ + + if (!(Flags & SK_MC_SW_ONLY)) { + (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber); + } + + return (SK_ADDR_SUCCESS); + +} /* SkAddrGmacMcClear */ #ifndef SK_ADDR_CHEAT /****************************************************************************** * - * SkCrc32McHash - hash multicast address + * SkXmacMcHash - hash multicast address * * Description: * This routine computes the hash value for a multicast address. + * A CRC32 algorithm is used. * * Notes: * The code was adapted from the XaQti data sheet. @@ -530,15 +679,84 @@ * Returns: * Hash value of multicast address. */ -unsigned SkCrc32McHash( +SK_U32 SkXmacMcHash( unsigned char *pMc) /* Multicast address */ { - u32 Crc; + SK_U32 Idx; + SK_U32 Bit; + SK_U32 Data; + SK_U32 Crc; + + Crc = 0xFFFFFFFFUL; + for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) { + Data = *pMc++; + for (Bit = 0; Bit < 8; Bit++, Data >>= 1) { + Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0); + } + } - Crc = ether_crc_le(SK_MAC_ADDR_LEN, pMc); + return (Crc & ((1 << HASH_BITS) - 1)); + +} /* SkXmacMcHash */ + +/****************************************************************************** + * + * SkGmacMcHash - hash multicast address + * + * Description: + * This routine computes the hash value for a multicast address. + * A CRC16 algorithm is used. + * + * Notes: + * + * + * Context: + * runtime, pageable + * + * Returns: + * Hash value of multicast address. + */ +SK_U32 SkGmacMcHash( +unsigned char *pMc) /* Multicast address */ +{ + SK_U32 Data; + SK_U32 TmpData; + SK_U32 Crc; + int Byte; + int Bit; + + Crc = 0xFFFFFFFFUL; + for (Byte = 0; Byte < 6; Byte++) { + /* Get next byte. */ + Data = (SK_U32) pMc[Byte]; + + /* Change bit order in byte. */ + TmpData = Data; + for (Bit = 0; Bit < 8; Bit++) { + if (TmpData & 1L) { + Data |= 1L << (7 - Bit); + } + else { + Data &= ~(1L << (7 - Bit)); + } + TmpData >>= 1; + } + + Crc ^= (Data << 24); + for (Bit = 0; Bit < 8; Bit++) { + if (Crc & 0x80000000) { + Crc = (Crc << 1) ^ GMAC_POLY; + } + else { + Crc <<= 1; + } + } + } + return (Crc & ((1 << HASH_BITS) - 1)); -} /* SkCrc32McHash */ + +} /* SkGmacMcHash */ #endif /* not SK_ADDR_CHEAT */ @@ -549,11 +767,57 @@ * Description: * This routine enables reception for a given address on the given port. * + * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the + * adapter in use. The real work is done there. + * * Notes: * The return code is only valid for SK_PROM_MODE_NONE. * - * In the current version, only RLMT may add addresses to the non-active - * port. + * Context: + * runtime, pageable + * may be called after SK_INIT_DATA + * + * Returns: + * SK_MC_FILTERING_EXACT + * SK_MC_FILTERING_INEXACT + * SK_MC_ILLEGAL_ADDRESS + * SK_MC_ILLEGAL_PORT + * SK_MC_RLMT_OVERFLOW + */ +int SkAddrMcAdd( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* Port Number */ +SK_MAC_ADDR *pMc, /* multicast address to be added */ +int Flags) /* permanent/non-permanent */ +{ + int ReturnCode; + + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { + return (SK_ADDR_ILLEGAL_PORT); + } + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); + } + else { + ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); + } + + return (ReturnCode); + +} /* SkAddrMcAdd */ + + +/****************************************************************************** + * + * SkAddrXmacMcAdd - add a multicast address to a port + * + * Description: + * This routine enables reception for a given address on the given port. + * + * Notes: + * The return code is only valid for SK_PROM_MODE_NONE. * * The multicast bit is only checked if there are no free exact match * entries. @@ -566,28 +830,23 @@ * SK_MC_FILTERING_EXACT * SK_MC_FILTERING_INEXACT * SK_MC_ILLEGAL_ADDRESS - * SK_MC_ILLEGAL_PORT * SK_MC_RLMT_OVERFLOW */ -int SkAddrMcAdd( +int SkAddrXmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ SK_MAC_ADDR *pMc, /* multicast address to be added */ -int Flags) /* permanent/non-permanent */ +int Flags) /* permanent/non-permanent */ { int i; SK_U8 Inexact; #ifndef SK_ADDR_CHEAT - unsigned HashBit; + SK_U32 HashBit; #endif /* !defined(SK_ADDR_CHEAT) */ - if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } - - if (Flags & SK_ADDR_PERMANENT) { -#ifdef DEBUG + if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ +#ifdef xDEBUG if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { Next0[PortNumber] |= 1; @@ -600,7 +859,7 @@ return (SK_MC_RLMT_OVERFLOW); } - /* Set an RLMT multicast address. */ + /* Set a RLMT multicast address. */ pAC->Addr.Port[PortNumber].Exact[ pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc; @@ -608,15 +867,7 @@ return (SK_MC_FILTERING_EXACT); } -#if 0 - /* Not PERMANENT => DRV */ - if (PortNumber != pAC->Addr.ActivePort) { - /* Only RLMT is allowed to do this. */ - return (SK_MC_ILLEGAL_PORT); - } -#endif /* 0 */ - -#ifdef DEBUG +#ifdef xDEBUG if (pAC->Addr.Port[PortNumber].NextExactMatchDrv < SK_ADDR_FIRST_MATCH_DRV) { Next0[PortNumber] |= 2; @@ -630,22 +881,19 @@ pAC->Addr.Port[PortNumber].Exact[ pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc; - /* Clear InexactFilter. */ + /* Clear InexactFilter */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; } } else { if (!(pMc->a[0] & SK_MC_BIT)) { - /* - * Hashing only possible with - * multicast addresses. - */ + /* Hashing only possible with multicast addresses. */ return (SK_MC_ILLEGAL_ADDRESS); } #ifndef SK_ADDR_CHEAT /* Compute hash value of address. */ - HashBit = 63 - SkCrc32McHash(&pMc->a[0]); + HashBit = 63 - SkXmacMcHash(&pMc->a[0]); /* Add bit to InexactFilter. */ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |= @@ -668,90 +916,223 @@ else { return (SK_MC_FILTERING_INEXACT); } -} /* SkAddrMcAdd */ + +} /* SkAddrXmacMcAdd */ /****************************************************************************** * - * SkAddrMcUpdate - update the HW MC address table and set the MAC address + * SkAddrGmacMcAdd - add a multicast address to a port * * Description: - * This routine enables reception of the addresses contained in a local - * table for a given port. - * It also programs the port's current physical MAC address. + * This routine enables reception for a given address on the given port. * * Notes: * The return code is only valid for SK_PROM_MODE_NONE. * * Context: * runtime, pageable - * may be called after SK_INIT_IO + * may be called after SK_INIT_DATA * * Returns: - * SK_MC_FILTERING_EXACT * SK_MC_FILTERING_INEXACT - * SK_ADDR_ILLEGAL_PORT + * SK_MC_ILLEGAL_ADDRESS */ -int SkAddrMcUpdate( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber) /* Port Number */ +int SkAddrGmacMcAdd( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* Port Number */ +SK_MAC_ADDR *pMc, /* multicast address to be added */ +int Flags) /* permanent/non-permanent */ { - SK_U32 i; - SK_U8 Inexact; - SK_U16 *OutAddr; - SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Reg. */ - SK_ADDR_PORT *pAPort; - - if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); + int i; +#ifndef SK_ADDR_CHEAT + SK_U32 HashBit; +#endif /* !defined(SK_ADDR_CHEAT) */ + + if (!(pMc->a[0] & SK_MC_BIT)) { + /* Hashing only possible with multicast addresses. */ + return (SK_MC_ILLEGAL_ADDRESS); } - - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_CTRL, - ("SkAddrMcUpdate on Port %u.\n", PortNumber)) - pAPort = &pAC->Addr.Port[PortNumber]; - +#ifndef SK_ADDR_CHEAT + + /* Compute hash value of address. */ + HashBit = SkGmacMcHash(&pMc->a[0]); + + if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ + + /* Add bit to InexactRlmtFilter. */ + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |= + 1 << (HashBit % 8); + + /* Copy bit to InexactFilter. */ + for (i = 0; i < 8; i++) { + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; + } #ifdef DEBUG - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_CTRL, - ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6], + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7])) #endif /* DEBUG */ - - /* Start with 0 to also program the logical MAC address. */ - for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { - /* Set exact match address i on HW. */ - OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0]; - XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); + } + else { /* not permanent => DRV */ + + /* Add bit to InexactDrvFilter. */ + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |= + 1 << (HashBit % 8); + + /* Copy bit to InexactFilter. */ + for (i = 0; i < 8; i++) { + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; + } +#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6], + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7])) +#endif /* DEBUG */ + } + +#else /* SK_ADDR_CHEAT */ + + /* Set all bits in InexactFilter. */ + for (i = 0; i < 8; i++) { + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; + } +#endif /* SK_ADDR_CHEAT */ + + return (SK_MC_FILTERING_INEXACT); + +} /* SkAddrGmacMcAdd */ + + +/****************************************************************************** + * + * SkAddrMcUpdate - update the HW MC address table and set the MAC address + * + * Description: + * This routine enables reception of the addresses contained in a local + * table for a given port. + * It also programs the port's current physical MAC address. + * + * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according + * to the adapter in use. The real work is done there. + * + * Notes: + * The return code is only valid for SK_PROM_MODE_NONE. + * + * Context: + * runtime, pageable + * may be called after SK_INIT_IO + * + * Returns: + * SK_MC_FILTERING_EXACT + * SK_MC_FILTERING_INEXACT + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrMcUpdate( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber) /* Port Number */ +{ + int ReturnCode; + + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { + return (SK_ADDR_ILLEGAL_PORT); + } + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber); + } + else { + ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber); + } + + return (ReturnCode); + +} /* SkAddrMcUpdate */ + + +/****************************************************************************** + * + * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address + * + * Description: + * This routine enables reception of the addresses contained in a local + * table for a given port. + * It also programs the port's current physical MAC address. + * + * Notes: + * The return code is only valid for SK_PROM_MODE_NONE. + * + * Context: + * runtime, pageable + * may be called after SK_INIT_IO + * + * Returns: + * SK_MC_FILTERING_EXACT + * SK_MC_FILTERING_INEXACT + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrXmacMcUpdate( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber) /* Port Number */ +{ + SK_U32 i; + SK_U8 Inexact; + SK_U16 *OutAddr; + SK_ADDR_PORT *pAPort; + + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)) + + pAPort = &pAC->Addr.Port[PortNumber]; + +#ifdef DEBUG + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) +#endif /* DEBUG */ + + /* Start with 0 to also program the logical MAC address. */ + for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { + /* Set exact match address i on XMAC */ + OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; + XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); } - /* Clear other permanent exact match addresses on HW. */ + /* Clear other permanent exact match addresses on XMAC */ if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) { - SkXmClrExactAddr( - pAC, - IoC, - PortNumber, - pAPort->NextExactMatchRlmt, + + SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt, SK_ADDR_LAST_MATCH_RLMT); } for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) { - OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0]; + OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); } - /* Clear other non-permanent exact match addresses on HW. */ + /* Clear other non-permanent exact match addresses on XMAC */ if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { - SkXmClrExactAddr( - pAC, - IoC, - PortNumber, - pAPort->NextExactMatchDrv, + + SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv, SK_ADDR_LAST_MATCH_DRV); } @@ -760,36 +1141,33 @@ } if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { + /* Set all bits in 64-bit hash register. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); - - /* Set bit 15 in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - LoMode |= XM_MD_ENA_HSH; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + + /* Enable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } else if (Inexact != 0) { + /* Set 64-bit hash register to InexactFilter. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]); - - /* Set bit 15 in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - LoMode |= XM_MD_ENA_HSH; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + + /* Enable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } else { - /* Clear bit 15 in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - LoMode &= ~XM_MD_ENA_HSH; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + /* Disable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_FALSE); } if (pAPort->PromMode != SK_PROM_MODE_NONE) { - (void)SkAddrPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); + (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); } - /* Set port's current MAC address. */ - OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0]; + /* Set port's current physical MAC address. */ + OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; + XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); #ifdef xDEBUG @@ -798,13 +1176,13 @@ SK_U16 *InAddr; /* Get exact match address i from port PortNumber. */ - InAddr = (SK_U16 *)&InAddr8[0]; + InAddr = (SK_U16 *) &InAddr8[0]; + XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr); - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_CTRL, - ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n", + + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrXmacMcUpdate: MC address %d on Port %u: ", + "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n", i, PortNumber, InAddr8[0], @@ -829,7 +1207,113 @@ else { return (SK_MC_FILTERING_INEXACT); } -} /* SkAddrMcUpdate */ + +} /* SkAddrXmacMcUpdate */ + + +/****************************************************************************** + * + * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address + * + * Description: + * This routine enables reception of the addresses contained in a local + * table for a given port. + * It also programs the port's current physical MAC address. + * + * Notes: + * The return code is only valid for SK_PROM_MODE_NONE. + * + * Context: + * runtime, pageable + * may be called after SK_INIT_IO + * + * Returns: + * SK_MC_FILTERING_EXACT + * SK_MC_FILTERING_INEXACT + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrGmacMcUpdate( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber) /* Port Number */ +{ + SK_U32 i; + SK_U8 Inexact; + SK_U16 *OutAddr; + SK_ADDR_PORT *pAPort; + + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)) + + pAPort = &pAC->Addr.Port[PortNumber]; + +#ifdef DEBUG + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) +#endif /* DEBUG */ + + for (Inexact = 0, i = 0; i < 8; i++) { + Inexact |= pAPort->InexactFilter.Bytes[i]; + } + + /* Set 64-bit hash register to InexactFilter. */ + GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, + &pAPort->InexactFilter.Bytes[0]); + + if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { + + /* Set all bits in 64-bit hash register. */ + GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); + + /* Enable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + } + else { + /* Enable Hashing. */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + } + + if (pAPort->PromMode != SK_PROM_MODE_NONE) { + (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); + } + + /* Set port's current physical MAC address. */ + OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; + GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); + + /* Set port's current logical MAC address. */ + OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0]; + GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr); + +#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", + pAPort->Exact[0].a[0], + pAPort->Exact[0].a[1], + pAPort->Exact[0].a[2], + pAPort->Exact[0].a[3], + pAPort->Exact[0].a[4], + pAPort->Exact[0].a[5])) + + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", + pAPort->CurrentMacAddress.a[0], + pAPort->CurrentMacAddress.a[1], + pAPort->CurrentMacAddress.a[2], + pAPort->CurrentMacAddress.a[3], + pAPort->CurrentMacAddress.a[4], + pAPort->CurrentMacAddress.a[5])) +#endif /* DEBUG */ + + /* Determine return value. */ + if (Inexact == 0 && pAPort->PromMode == 0) { + return (SK_MC_FILTERING_EXACT); + } + else { + return (SK_MC_FILTERING_INEXACT); + } + +} /* SkAddrGmacMcUpdate */ /****************************************************************************** @@ -863,7 +1347,7 @@ NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber; - if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } @@ -877,7 +1361,7 @@ if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */ /* Parameter *pNewAddr is ignored. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { if (!pAC->Addr.Port[i].CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } @@ -891,12 +1375,12 @@ pAC->Addr.Net[NetNumber].CurrentMacAddress; /* Write address to first exact match entry of active port. */ - (void)SkAddrMcUpdate(pAC, IoC, PortNumber); + (void) SkAddrMcUpdate(pAC, IoC, PortNumber); } else if (Flags & SK_ADDR_CLEAR_LOGICAL) { /* Deactivate logical MAC address. */ /* Parameter *pNewAddr is ignored. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { if (!pAC->Addr.Port[i].CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } @@ -911,7 +1395,7 @@ } /* Write address to first exact match entry of active port. */ - (void)SkAddrMcUpdate(pAC, IoC, PortNumber); + (void) SkAddrMcUpdate(pAC, IoC, PortNumber); } else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */ if (SK_ADDR_EQUAL(pNewAddr->a, @@ -919,7 +1403,7 @@ return (SK_ADDR_DUPLICATE_ADDRESS); } - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { if (!pAC->Addr.Port[i].CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } @@ -939,9 +1423,15 @@ pAC->Addr.Port[PortNumber].CurrentMacAddress; pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; - /* Change port's address. */ - OutAddr = (SK_U16 *)pNewAddr; - XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); + /* Change port's physical MAC address. */ + OutAddr = (SK_U16 *) pNewAddr; + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); + } + else { + GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); + } /* Report address change to RLMT. */ Para.Para32[0] = PortNumber; @@ -954,7 +1444,7 @@ return (SK_ADDR_SUCCESS); } - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { if (!pAC->Addr.Port[i].CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } @@ -971,24 +1461,18 @@ pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr; pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr; - #ifdef DEBUG - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_CTRL, - ("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n", + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])) - SK_DBG_MSG( - pAC, - SK_DBGMOD_ADDR, - SK_DBGCAT_CTRL, - ("New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", + + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, + ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2], @@ -998,10 +1482,11 @@ #endif /* DEBUG */ /* Write address to first exact match entry of active port. */ - (void)SkAddrMcUpdate(pAC, IoC, PortNumber); + (void) SkAddrMcUpdate(pAC, IoC, PortNumber); } return (SK_ADDR_SUCCESS); + } /* SkAddrOverride */ @@ -1015,6 +1500,10 @@ * - all LLC frames * - all MC frames * + * It calls either SkAddrXmacPromiscuousChange or + * SkAddrGmacPromiscuousChange, according to the adapter in use. + * The real work is done there. + * * Context: * runtime, pageable * may be called after SK_INIT_IO @@ -1029,6 +1518,48 @@ SK_U32 PortNumber, /* port whose promiscuous mode changes */ int NewPromMode) /* new promiscuous mode */ { + int ReturnCode; + + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { + return (SK_ADDR_ILLEGAL_PORT); + } + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + ReturnCode = SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); + } + else { + ReturnCode = SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); + } + + return (ReturnCode); + +} /* SkAddrPromiscuousChange */ + + +/****************************************************************************** + * + * SkAddrXmacPromiscuousChange - set promiscuous mode for given port + * + * Description: + * This routine manages promiscuous mode: + * - none + * - all LLC frames + * - all MC frames + * + * Context: + * runtime, pageable + * may be called after SK_INIT_IO + * + * Returns: + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrXmacPromiscuousChange( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* port whose promiscuous mode changes */ +int NewPromMode) /* new promiscuous mode */ +{ int i; SK_BOOL InexactModeBit; SK_U8 Inexact; @@ -1037,14 +1568,11 @@ SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */ int CurPromMode = SK_PROM_MODE_NONE; - if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } - /* Read CurPromMode from Hardware. */ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - if (LoMode & XM_MD_ENA_PROM) { + if ((LoMode & XM_MD_ENA_PROM) != 0) { + /* Promiscuous mode! */ CurPromMode |= SK_PROM_MODE_LLC; } @@ -1055,12 +1583,12 @@ CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); } else { - /* Read InexactModeBit (bit 15 in mode register). */ + /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - InexactModeBit = (LoMode & XM_MD_ENA_HSH) != 0; + InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0; - /* Read 64-bit hash register from HW. */ + /* Read 64-bit hash register from XMAC */ XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]); for (HwInexact = 0xFF, i = 0; i < 8; i++) { @@ -1080,13 +1608,12 @@ if ((NewPromMode & SK_PROM_MODE_ALL_MC) && !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */ + /* Set all bits in 64-bit hash register. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); - /* Set bit 15 in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - LoMode |= XM_MD_ENA_HSH; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + /* Enable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_ALL_MC) && !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */ @@ -1094,55 +1621,118 @@ Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; } if (Inexact == 0) { - /* Clear bit 15 in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - LoMode &= ~XM_MD_ENA_HSH; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + /* Disable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_FALSE); } else { /* Set 64-bit hash register to InexactFilter. */ - XM_OUTHASH( - IoC, - PortNumber, - XM_HSM, + XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); - /* Set bit 15 in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - LoMode |= XM_MD_ENA_HSH; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + /* Enable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } } if ((NewPromMode & SK_PROM_MODE_LLC) && !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ - /* Set promiscuous bit in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - -#if 0 - /* Receive MAC frames. */ - LoMode |= XM_MD_RX_MCTRL; -#endif /* 0 */ - - LoMode |= XM_MD_ENA_PROM; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + /* Set the MAC in Promiscuous Mode */ + SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_LLC) && !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */ - /* Clear promiscuous bit in mode register. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); + /* Clear Promiscuous Mode */ + SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE); + } + + return (SK_ADDR_SUCCESS); + +} /* SkAddrXmacPromiscuousChange */ + + +/****************************************************************************** + * + * SkAddrGmacPromiscuousChange - set promiscuous mode for given port + * + * Description: + * This routine manages promiscuous mode: + * - none + * - all LLC frames + * - all MC frames + * + * Context: + * runtime, pageable + * may be called after SK_INIT_IO + * + * Returns: + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +int SkAddrGmacPromiscuousChange( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* port whose promiscuous mode changes */ +int NewPromMode) /* new promiscuous mode */ +{ + SK_U16 ReceiveControl; /* GMAC Receive Control Register */ + int CurPromMode = SK_PROM_MODE_NONE; + + /* Read CurPromMode from Hardware. */ + GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl); + + if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) { + /* Promiscuous mode! */ + CurPromMode |= SK_PROM_MODE_LLC; + } + + if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) { + /* All Multicast mode! */ + CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); + } -#if 0 - /* Don't receive MAC frames. */ - LoMode &= ~XM_MD_RX_MCTRL; -#endif /* 0 */ + pAC->Addr.Port[PortNumber].PromMode = NewPromMode; + + if (NewPromMode == CurPromMode) { + return (SK_ADDR_SUCCESS); + } + + if ((NewPromMode & SK_PROM_MODE_ALL_MC) && + !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */ - LoMode &= ~XM_MD_ENA_PROM; - XM_OUT16(IoC, PortNumber, XM_MODE, LoMode); + /* Set all bits in 64-bit hash register. */ + GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); + + /* Enable Hashing */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } + if ((CurPromMode & SK_PROM_MODE_ALL_MC) && + !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */ + + /* Set 64-bit hash register to InexactFilter. */ + GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, + &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); + + /* Enable Hashing. */ + SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + } + + if ((NewPromMode & SK_PROM_MODE_LLC) && + !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ + + /* Set the MAC to Promiscuous Mode. */ + SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE); + } + else if ((CurPromMode & SK_PROM_MODE_LLC) && + !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ + + /* Clear Promiscuous Mode. */ + SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE); + } + return (SK_ADDR_SUCCESS); -} /* SkAddrPromiscuousChange */ + +} /* SkAddrGmacPromiscuousChange */ /****************************************************************************** @@ -1163,7 +1753,7 @@ int SkAddrSwap( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ -SK_U32 FromPortNumber, /* Port1 Index */ +SK_U32 FromPortNumber, /* Port1 Index */ SK_U32 ToPortNumber) /* Port2 Index */ { int i; @@ -1171,11 +1761,11 @@ SK_MAC_ADDR MacAddr; SK_U32 DWord; - if (FromPortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { + if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } - if (ToPortNumber >= (SK_U32)pAC->GIni.GIMacsFound) { + if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } @@ -1184,13 +1774,15 @@ } /* - * Swap - * - Exact Match Entries - * - FirstExactMatchRlmt; - * - NextExactMatchRlmt; - * - FirstExactMatchDrv; - * - NextExactMatchDrv; - * - 64-bit filter + * Swap: + * - Exact Match Entries (GEnesis and Yukon) + * Yukon uses first entry for the logical MAC + * address (stored in the second GMAC register). + * - FirstExactMatchRlmt (GEnesis only) + * - NextExactMatchRlmt (GEnesis only) + * - FirstExactMatchDrv (GEnesis only) + * - NextExactMatchDrv (GEnesis only) + * - 64-bit filter (InexactFilter) * - Promiscuous Mode * of ports. */ @@ -1208,46 +1800,49 @@ pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i]; pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte; } - + i = pAC->Addr.Port[FromPortNumber].PromMode; pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode; pAC->Addr.Port[ToPortNumber].PromMode = i; - - DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; - pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = - pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; - pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord; - - DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt; - pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt = - pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt; - pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord; - - DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv; - pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv = - pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv; - pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord; - - DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv; - pAC->Addr.Port[FromPortNumber].NextExactMatchDrv = - pAC->Addr.Port[ToPortNumber].NextExactMatchDrv; - pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord; - + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; + pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = + pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; + pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord; + + DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt; + pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt = + pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt; + pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord; + + DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv; + pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv = + pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv; + pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord; + + DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv; + pAC->Addr.Port[FromPortNumber].NextExactMatchDrv = + pAC->Addr.Port[ToPortNumber].NextExactMatchDrv; + pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord; + } + /* CAUTION: Solution works if only ports of one adapter are in use. */ - for (i = 0; (SK_U32)i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber]. + for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber]. Net->NetNumber].NumPorts; i++) { if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. Port[i]->PortNumber == ToPortNumber) { pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. ActivePort = i; /* 20001207 RA: Was "ToPortNumber;". */ - } } - (void)SkAddrMcUpdate(pAC, IoC, FromPortNumber); - (void)SkAddrMcUpdate(pAC, IoC, ToPortNumber); + + (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber); + (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber); return (SK_ADDR_SUCCESS); + } /* SkAddrSwap */ #ifdef __cplusplus diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skcsum.c linux.21pre4-ac6/drivers/net/sk98lin/skcsum.c --- linux.21pre4/drivers/net/sk98lin/skcsum.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skcsum.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skcsum.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.8 $ - * Date: $Date: 2001/02/06 11:15:36 $ + * Version: $Revision: 1.10 $ + * Date: $Date: 2002/04/11 10:02:04 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -26,6 +26,15 @@ * History: * * $Log: skcsum.c,v $ + * Revision 1.10 2002/04/11 10:02:04 rwahl + * Fix in SkCsGetSendInfo(): + * - function did not return ProtocolFlags in every case. + * - pseudo header csum calculated wrong for big endian. + * + * Revision 1.9 2001/06/13 07:42:08 gklug + * fix: NetNumber was wrong in CLEAR_STAT event + * add: check for good NetNumber in Clear STAT + * * Revision 1.8 2001/02/06 11:15:36 rassmann * Supporting two nets on dual-port adapters. * @@ -65,7 +74,7 @@ #ifndef lint static const char SysKonnectFileId[] = "@(#)" - "$Id: skcsum.c,v 1.8 2001/02/06 11:15:36 rassmann Exp $" + "$Id: skcsum.c,v 1.10 2002/04/11 10:02:04 rwahl Exp $" " (C) SysKonnect."; #endif /* !lint */ @@ -195,7 +204,7 @@ * zero.) * * Note: - * There is a bug in the ASIC whic may lead to wrong checksums. + * There is a bug in the ASIC which may lead to wrong checksums. * * Arguments: * pAc - A pointer to the adapter context struct. @@ -411,9 +420,9 @@ SKCS_OFS_IP_DESTINATION_ADDRESS + 0) + (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_DESTINATION_ADDRESS + 2) + - (unsigned long) (NextLevelProtocol << 8) + + (unsigned long) SKCS_HTON16(NextLevelProtocol) + (unsigned long) SKCS_HTON16(IpDataLength); - + /* Add-in any carries. */ SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0); @@ -422,6 +431,7 @@ SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0); + pPacketInfo->ProtocolFlags = ProtocolFlags; NextLevelProtoStats->TxOkCts++; /* Success. */ } /* SkCsGetSendInfo */ @@ -889,11 +899,13 @@ */ case SK_CSUM_EVENT_CLEAR_PROTO_STATS: - ProtoIndex = (int)Param.Para32[0]; - NetNumber = (int)Param.Para32[1]; + ProtoIndex = (int)Param.Para32[1]; + NetNumber = (int)Param.Para32[0]; if (ProtoIndex < 0) { /* Clear for all protocols. */ - memset(&pAc->Csum.ProtoStats[NetNumber][0], 0, - sizeof(pAc->Csum.ProtoStats[NetNumber])); + if (NetNumber >= 0) { + memset(&pAc->Csum.ProtoStats[NetNumber][0], 0, + sizeof(pAc->Csum.ProtoStats[NetNumber])); + } } else { /* Clear for individual protocol. */ memset(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skge.c linux.21pre4-ac6/drivers/net/sk98lin/skge.c --- linux.21pre4/drivers/net/sk98lin/skge.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skge.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,18 +2,20 @@ * * Name: skge.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.29.2.6 $ - * Date: $Date: 2001/05/21 07:59:29 $ + * Version: $Revision: 1.43 $ + * Date: $Date: 2002/11/29 08:42:41 $ * Purpose: The main driver source module * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * Driver for SysKonnect Gigabit Ethernet Server Adapters: * + * SK-9871 (single link 1000Base-ZX) + * SK-9872 (dual link 1000Base-ZX) * SK-9861 (single link 1000Base-SX, VF45 Volition Plug) * SK-9862 (dual link 1000Base-SX, VF45 Volition Plug) * SK-9841 (single link 1000Base-LX) @@ -22,6 +24,12 @@ * SK-9844 (dual link 1000Base-SX) * SK-9821 (single link 1000Base-T) * SK-9822 (dual link 1000Base-T) + * SK-9881 (single link 1000Base-SX V2 LC) + * SK-9871 (single link 1000Base-ZX V2) + * SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug) + * SK-9841 (single link 1000Base-LX V2) + * SK-9843 (single link 1000Base-SX V2) + * SK-9821 (single link 1000Base-T V2) * * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and * SysKonnects GEnesis Solaris driver @@ -48,6 +56,62 @@ * History: * * $Log: skge.c,v $ + * Revision 1.43 2002/11/29 08:42:41 mlindner + * Fix: Boot message + * + * Revision 1.42 2002/11/28 13:30:23 mlindner + * Add: New frame check + * + * Revision 1.41 2002/11/27 13:55:18 mlindner + * Fix: Drop wrong csum packets + * Fix: Initialize proc_entry after hw check + * + * Revision 1.40 2002/10/31 07:50:37 tschilli + * Function SkGeInitAssignRamToQueues() from common module inserted. + * Autonegotiation is set to ON for all adapters. + * LinkSpeedUsed is used in link up status report. + * Role parameter will show up for 1000 Mbps links only. + * GetConfiguration() inserted after init level 1 in SkGeChangeMtu(). + * All return values of SkGeInit() and SkGeInitPort() are checked. + * + * Revision 1.39 2002/10/02 12:56:05 mlindner + * Add: Support for Yukon + * Add: Support for ZEROCOPY, scatter-gather and hw checksum + * Add: New transmit ring function (use SG and TCP/UDP hardware checksumming) + * Add: New init function + * Add: Speed check and setup + * Add: Merge source for kernel 2.2.x and 2.4.x + * Add: Opcode check for tcp + * Add: Frame length check + * Fix: Transmit complete interrupt + * Fix: Interrupt moderation + * + * Revision 1.29.2.13 2002/01/14 12:44:52 mlindner + * Fix: Rlmt modes + * + * Revision 1.29.2.12 2001/12/07 12:06:18 mlindner + * Fix: malloc -> slab changes + * + * Revision 1.29.2.11 2001/12/06 15:19:20 mlindner + * Add: DMA attributes + * Fix: Module initialisation + * Fix: pci_map_single and pci_unmap_single replaced + * + * Revision 1.29.2.10 2001/12/06 09:56:50 mlindner + * Corrected some printk's + * + * Revision 1.29.2.9 2001/09/05 12:15:34 mlindner + * Add: LBFO Changes + * Fix: Counter Errors (Jumbo == to long errors) + * Fix: Changed pAC->PciDev declaration + * Fix: too short counters + * + * Revision 1.29.2.8 2001/06/25 12:10:44 mlindner + * fix: ReceiveIrq() changed. + * + * Revision 1.29.2.7 2001/06/25 08:07:05 mlindner + * fix: RLMT locking in ReceiveIrq() changed. + * * Revision 1.29.2.6 2001/05/21 07:59:29 mlindner * fix: MTU init problems * @@ -266,24 +330,26 @@ ******************************************************************************/ #include "h/skversion.h" - #include #include #include - #include "h/skdrv1st.h" #include "h/skdrv2nd.h" + /* defines ******************************************************************/ /* for debuging on x86 only */ /* #define BREAKPOINT() asm(" int $3"); */ +/* use the scatter-gather functionality with sendfile() */ +#define SK_ZEROCOPY + /* use of a transmit complete interrupt */ #define USE_TX_COMPLETE /* use interrupt moderation (for tx complete only) */ -// #define USE_INT_MOD -#define INTS_PER_SEC 1000 +#define USE_INT_MOD +#define INTS_PER_SEC 1800 /* * threshold for copying small receive frames @@ -294,10 +360,13 @@ /* number of adapters that can be configured via command line params */ #define SK_MAX_CARD_PARAM 16 + /* * use those defines for a compile-in version of the driver instead * of command line parameters */ +// #define LINK_SPEED_A {"Auto", } +// #define LINK_SPEED_B {"Auto", } // #define AUTO_NEG_A {"Sense", } // #define AUTO_NEG_B {"Sense", } // #define DUP_CAP_A {"Both", } @@ -314,10 +383,8 @@ #define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) /* function prototypes ******************************************************/ -static void FreeResources(struct net_device *dev); -int init_module(void); -void cleanup_module(void); -static int SkGeBoardInit(struct net_device *dev, SK_AC *pAC); +static void FreeResources(struct SK_NET_DEVICE *dev); +static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC); static SK_BOOL BoardAllocMem(SK_AC *pAC); static void BoardFreeMem(SK_AC *pAC); static void BoardInitMem(SK_AC *pAC); @@ -326,66 +393,62 @@ static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs); static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs); -static int SkGeOpen(struct net_device *dev); -static int SkGeClose(struct net_device *dev); -static int SkGeXmit(struct sk_buff *skb, struct net_device *dev); -static int SkGeSetMacAddr(struct net_device *dev, void *p); -static void SkGeSetRxMode(struct net_device *dev); -static struct net_device_stats *SkGeStats(struct net_device *dev); -static int SkGeIoctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int SkGeOpen(struct SK_NET_DEVICE *dev); +static int SkGeClose(struct SK_NET_DEVICE *dev); +static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev); +static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p); +static void SkGeSetRxMode(struct SK_NET_DEVICE *dev); +static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev); +static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd); static void GetConfiguration(SK_AC*); static void ProductStr(SK_AC*); static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*); static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*); static void FillRxRing(SK_AC*, RX_PORT*); static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*); -static void ReceiveIrq(SK_AC*, RX_PORT*); -static void ClearAndStartRx(SK_AC*, int); +static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); +static void ClearAndStartRx(SK_AC*, int); static void ClearTxIrq(SK_AC*, int, int); static void ClearRxRing(SK_AC*, RX_PORT*); static void ClearTxRing(SK_AC*, TX_PORT*); static void SetQueueSizes(SK_AC *pAC); -static int SkGeChangeMtu(struct net_device *dev, int new_mtu); +static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu); static void PortReInitBmu(SK_AC*, int); static int SkGeIocMib(DEV_NET*, unsigned int, int); - +static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); /*Extern */ -extern struct proc_dir_entry *pSkRootDir; - -//extern struct proc_dir_entry Our_Proc_Dir; -extern int proc_read(char *buffer, char **buffer_location, - off_t offset, int buffer_length, int *eof, void *data); - +/* external Proc function */ +extern int proc_read( + char *buffer, + char **buffer_location, + off_t offset, + int buffer_length, + int *eof, + void *data); #ifdef DEBUG static void DumpMsg(struct sk_buff*, char*); static void DumpData(char*, int); static void DumpLong(char*, int); #endif - +void dump_frag( SK_U8 *data, int length); /* global variables *********************************************************/ static const char *BootString = BOOT_STRING; -struct net_device *sk98lin_root_dev = NULL; +struct SK_NET_DEVICE *SkGeRootDev = NULL; static int probed __initdata = 0; -struct inode_operations SkInodeOps; -//static struct file_operations SkFileOps; /* with open/relase */ /* local variables **********************************************************/ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; +/* local variables **********************************************************/ +const char SK_Root_Dir_entry[8]; -void proc_fill_inode(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} +static struct proc_dir_entry *pSkRootDir; @@ -405,51 +468,53 @@ static int __init skge_probe (void) { int proc_root_initialized = 0; - int boards_found = 0; - int version_disp = 0; - SK_AC *pAC; - DEV_NET *pNet = NULL; - struct pci_dev *pdev = NULL; - unsigned long base_address; - struct net_device *dev = NULL; + int boards_found = 0; + SK_AC *pAC; + DEV_NET *pNet = NULL; struct proc_dir_entry *pProcFile; + struct pci_dev *pdev = NULL; + unsigned long base_address; + struct SK_NET_DEVICE *dev = NULL; + SK_BOOL DeviceFound = SK_FALSE; + SK_BOOL BootStringCount = SK_FALSE; if (probed) return -ENODEV; probed++; - - /* display driver info */ - if (!version_disp) - { - /* set display flag to TRUE so that */ - /* we only display this string ONCE */ - version_disp = 1; - printk("%s\n", BootString); - } if (!pci_present()) /* is PCI support present? */ return -ENODEV; - while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT, - PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) { + while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) + { dev = NULL; pNet = NULL; - if (pci_enable_device(pdev)) + if ((pdev->vendor != PCI_VENDOR_ID_SYSKONNECT) && + ((pdev->device != PCI_DEVICE_ID_SYSKONNECT_GE) || + (pdev->device != PCI_DEVICE_ID_SYSKONNECT_YU))){ continue; + } /* Configure DMA attributes. */ if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) && - pci_set_dma_mask(pdev, (u64) 0xffffffff)) - continue; + pci_set_dma_mask(pdev, (u64) 0xffffffff)) + continue; + - if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) { + if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) { printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); break; } + if (dev->priv == NULL) { + printk(KERN_ERR "Unable to allocate adapter " + "structure!\n"); + break; + } + pNet = dev->priv; pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); if (pNet->pAC == NULL){ @@ -459,15 +524,23 @@ break; } + /* Print message */ + if (!BootStringCount) { + /* set display flag to TRUE so that */ + /* we only display this string ONCE */ + BootStringCount = SK_TRUE; + printk("%s\n", BootString); + } + memset(pNet->pAC, 0, sizeof(SK_AC)); pAC = pNet->pAC; - pAC->PciDev = *pdev; + pAC->PciDev = pdev; pAC->PciDevId = pdev->device; pAC->dev[0] = dev; pAC->dev[1] = dev; sprintf(pAC->Name, "SysKonnect SK-98xx"); pAC->CheckQueue = SK_FALSE; - + pNet->Mtu = 1500; pNet->Up = 0; dev->irq = pdev->irq; @@ -480,28 +553,23 @@ dev->set_mac_address = &SkGeSetMacAddr; dev->do_ioctl = &SkGeIoctl; dev->change_mtu = &SkGeChangeMtu; + dev->flags &= ~IFF_RUNNING; - if(!proc_root_initialized) { - pSkRootDir = create_proc_entry("sk98lin", - S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); - pSkRootDir->owner = THIS_MODULE; - - proc_root_initialized = 1; +#ifdef SK_ZEROCOPY + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + /* Use only if yukon hardware */ + /* SK and ZEROCOPY - fly baby... */ + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; } - - pProcFile = create_proc_entry(dev->name, - S_IFREG | 0444, pSkRootDir); - pProcFile->read_proc = proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name+1); - pProcFile->data = (void*)pProcFile; +#endif /* * Dummy value. */ dev->base_addr = 42; pci_set_master(pdev); + + pci_set_master(pdev); base_address = pci_resource_start (pdev, 0); #ifdef SK_BIG_ENDIAN @@ -515,13 +583,13 @@ our2 |= PCI_REV_DESC; SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); } -#endif /* BIG ENDIAN */ +#endif /* * Remap the regs into kernel space. */ - pAC->IoBase = (char*)ioremap(base_address, 0x4000); + if (!pAC->IoBase){ printk(KERN_ERR "%s: Unable to map I/O register, " "SK 98xx No. %i will be disabled.\n", @@ -529,8 +597,8 @@ kfree(dev); break; } - pAC->Index = boards_found; + pAC->Index = boards_found; if (SkGeBoardInit(dev, pAC)) { FreeResources(dev); kfree(dev); @@ -540,9 +608,46 @@ memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); + /* First adapter... Create proc and print message */ + if (!DeviceFound) { + DeviceFound = SK_TRUE; + SK_MEMCPY(&SK_Root_Dir_entry, BootString, + sizeof(SK_Root_Dir_entry) - 1); + + /*Create proc (directory)*/ + if(!proc_root_initialized) { + pSkRootDir = create_proc_entry(SK_Root_Dir_entry, + S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); + proc_root_initialized = 1; + } + + pSkRootDir->owner = THIS_MODULE; + } + + + + /* Create proc file */ + pProcFile = create_proc_entry(dev->name, + S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, + pSkRootDir); + + + pProcFile->read_proc = proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pNet->PortNr = 0; pNet->NetNr = 0; +#ifdef SK_ZEROCOPY + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + /* SG and ZEROCOPY - fly baby... */ + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + } +#endif + boards_found++; /* More then one port found */ @@ -569,24 +674,39 @@ dev->set_mac_address = &SkGeSetMacAddr; dev->do_ioctl = &SkGeIoctl; dev->change_mtu = &SkGeChangeMtu; + dev->flags &= ~IFF_RUNNING; - pProcFile = create_proc_entry(dev->name, - S_IFREG | 0444, pSkRootDir); +#ifdef SK_ZEROCOPY + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + /* SG and ZEROCOPY - fly baby... */ + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + } +#endif + + pProcFile = create_proc_entry(dev->name, + S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, + pSkRootDir); + + pProcFile->read_proc = proc_read; pProcFile->write_proc = NULL; pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name+1); - pProcFile->data = (void*)pProcFile; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); printk("%s: %s\n", dev->name, pAC->DeviceStr); printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); - + } + /* Save the hardware revision */ + pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + + (pAC->GIni.GIPciHwRev & 0x0F); + /* * This is bollocks, but we need to tell the net-init * code that it shall go for the next device. @@ -617,7 +737,7 @@ * Returns: N/A * */ -static void FreeResources(struct net_device *dev) +static void FreeResources(struct SK_NET_DEVICE *dev) { SK_U32 AllocFlag; DEV_NET *pNet; @@ -640,17 +760,19 @@ } /* FreeResources */ -MODULE_AUTHOR("Christoph Goos "); +MODULE_AUTHOR("Mirko Lindner "); MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); MODULE_LICENSE("GPL"); +MODULE_PARM(Speed_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Speed_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); /* not used, just there because every driver should have them: */ @@ -658,6 +780,18 @@ MODULE_PARM(debug, "i"); +#ifdef LINK_SPEED_A +static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED; +#else +static char *Speed_A[SK_MAX_CARD_PARAM] = {"", }; +#endif + +#ifdef LINK_SPEED_B +static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED; +#else +static char *Speed_B[SK_MAX_CARD_PARAM] = {"", }; +#endif + #ifdef AUTO_NEG_A static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A; #else @@ -718,7 +852,6 @@ static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; #endif - static int debug = 0; /* not used */ static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ @@ -737,7 +870,7 @@ static int __init skge_init_module(void) { int cards; - sk98lin_root_dev = NULL; + SkGeRootDev = NULL; /* just to avoid warnings ... */ debug = 0; @@ -745,7 +878,7 @@ cards = skge_probe(); if (cards == 0) { - printk("No adapter found\n"); + printk("No adapter found.\n"); } return cards ? 0 : -ENODEV; } /* skge_init_module */ @@ -765,16 +898,16 @@ { DEV_NET *pNet; SK_AC *pAC; -struct net_device *next; +struct SK_NET_DEVICE *next; unsigned long Flags; SK_EVPARA EvPara; - while (sk98lin_root_dev) { - pNet = (DEV_NET*) sk98lin_root_dev->priv; + while (SkGeRootDev) { + pNet = (DEV_NET*) SkGeRootDev->priv; pAC = pNet->pAC; next = pAC->Next; - netif_stop_queue(sk98lin_root_dev); + netif_stop_queue(SkGeRootDev); SkGeYellowLED(pAC, pAC->IoBase, 0); if(pAC->BoardLevel == 2) { @@ -806,17 +939,17 @@ kfree(pAC->dev[1]); } - FreeResources(sk98lin_root_dev); + FreeResources(SkGeRootDev); - sk98lin_root_dev->get_stats = NULL; + SkGeRootDev->get_stats = NULL; /* * otherwise unregister_netdev calls get_stats with * invalid IO ... :-( */ - unregister_netdev(sk98lin_root_dev); - kfree(sk98lin_root_dev); + unregister_netdev(SkGeRootDev); + kfree(SkGeRootDev); kfree(pAC); - sk98lin_root_dev = next; + SkGeRootDev = next; } /* clear proc-dir */ @@ -840,13 +973,14 @@ * 0, if everything is ok * !=0, on error */ -static int __init SkGeBoardInit(struct net_device *dev, SK_AC *pAC) +static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) { short i; unsigned long Flags; char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */ char *VerStr = VER_STRING; int Ret; /* return code of request_irq */ +SK_BOOL DualNet; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("IoBase: %08lX\n", (unsigned long)pAC->IoBase)); @@ -858,7 +992,6 @@ } /* Initialize the mutexes */ - for (i=0; iTxPort[i][0].TxDesRingLock); spin_lock_init(&pAC->RxPort[i].RxDesRingLock); @@ -908,7 +1041,6 @@ pAC->GIni.GIPortUsage = SK_MUL_LINK; } - pAC->BoardLevel = 1; spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); @@ -918,12 +1050,13 @@ Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev); } else { - printk(KERN_WARNING "%s: illegal number of ports: %d\n", + printk(KERN_WARNING "%s: Illegal number of ports: %d\n", dev->name, pAC->GIni.GIMacsFound); return -EAGAIN; } + if (Ret) { - printk(KERN_WARNING "%s: Requested IRQ %d is busy\n", + printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n", dev->name, dev->irq); return -EAGAIN; } @@ -931,7 +1064,7 @@ /* Alloc memory for this board (Mem for RxD/TxD) : */ if(!BoardAllocMem(pAC)) { - printk("No memory for descriptor rings\n"); + printk("No memory for descriptor rings.\n"); return(-EAGAIN); } @@ -941,8 +1074,24 @@ pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1; BoardInitMem(pAC); - +#if 0 SetQueueSizes(pAC); +#else + /* tschilling: New common function with minimum size check. */ + DualNet = SK_FALSE; + if (pAC->RlmtNets == 2) { + DualNet = SK_TRUE; + } + + if (SkGeInitAssignRamToQueues( + pAC, + pAC->ActivePort, + DualNet)) { + BoardFreeMem(pAC); + printk("SkGeInitAssignRamToQueues failed.\n"); + return(-EAGAIN); + } +#endif /* Print adapter specific string from vpd */ ProductStr(pAC); @@ -957,14 +1106,13 @@ ((pAC->RlmtMode==7) ? "Check Segmentation" : ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); - SkGeYellowLED(pAC, pAC->IoBase, 1); /* * Register the device here */ - pAC->Next = sk98lin_root_dev; - sk98lin_root_dev = dev; + pAC->Next = SkGeRootDev; + SkGeRootDev = dev; return (0); } /* SkGeBoardInit */ @@ -1001,17 +1149,19 @@ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + RX_RING_SIZE + 8; #endif - pDescrMem = pci_alloc_consistent(&pAC->PciDev, AllocLength, + + pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength, &pAC->pDescrMemDMA); + if (pDescrMem == NULL) { return (SK_FALSE); } pAC->pDescrMem = pDescrMem; + BusAddr = (unsigned long) pAC->pDescrMemDMA; /* Descriptors need 8 byte alignment, and this is ensured * by pci_alloc_consistent. */ - BusAddr = (unsigned long) pAC->pDescrMemDMA; for (i=0; iGIni.GIMacsFound; i++) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n", @@ -1059,7 +1209,8 @@ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + RX_RING_SIZE + 8; #endif - pci_free_consistent(&pAC->PciDev, AllocLength, + + pci_free_consistent(pAC->PciDev, AllocLength, pAC->pDescrMem, pAC->pDescrMemDMA); pAC->pDescrMem = NULL; } /* BoardFreeMem */ @@ -1146,8 +1297,7 @@ DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; DescrNum = TX_RING_SIZE / DescrSize; - } - else { + } else { DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; DescrNum = RX_RING_SIZE / DescrSize; @@ -1156,7 +1306,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("Descriptor size: %d Descriptor Number: %d\n", DescrSize,DescrNum)); - + pDescr = (RXD*) pMemArea; pPrevDescr = NULL; pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); @@ -1166,7 +1316,8 @@ pDescr->VNextRxd = VNextDescr & 0xffffffffULL; pDescr->pNextRxd = pNextDescr; pDescr->TcpSumStarts = pAC->CsOfs; - /* advance on step */ + + /* advance one step */ pPrevDescr = pDescr; pDescr = pNextDescr; pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); @@ -1240,8 +1391,7 @@ */ static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs) { -struct net_device *dev = (struct net_device *)dev_id; - +struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; DEV_NET *pNet; SK_AC *pAC; SK_U32 IntSrc; /* interrupts source register contents */ @@ -1269,22 +1419,22 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF RX1 IRQ\n")); - ReceiveIrq(pAC, &pAC->RxPort[0]); - SK_PNMI_CNT_RX_INTR(pAC,0); + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); + SK_PNMI_CNT_RX_INTR(pAC, 0); } if (IntSrc & IRQ_EOF_RX2) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF RX2 IRQ\n")); - ReceiveIrq(pAC, &pAC->RxPort[1]); - SK_PNMI_CNT_RX_INTR(pAC,1); + ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); + SK_PNMI_CNT_RX_INTR(pAC, 1); } #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ if (IntSrc & IRQ_EOF_AS_TX1) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC,0); + SK_PNMI_CNT_TX_INTR(pAC, 0); spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); @@ -1293,7 +1443,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX2 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC,1); + SK_PNMI_CNT_TX_INTR(pAC, 1); spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); @@ -1303,7 +1453,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC,0); + SK_PNMI_CNT_TX_INTR(pAC, 1); spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); @@ -1313,14 +1463,14 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX2 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC,1); + SK_PNMI_CNT_TX_INTR(pAC, 1); spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH); spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); ClearTxIrq(pAC, 1, TX_PRIO_HIGH); } -#endif /* 0 */ -#endif /* USE_TX_COMPLETE */ +#endif +#endif /* do all IO at once */ if (IntSrc & IRQ_EOF_RX1) @@ -1338,11 +1488,12 @@ if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, - ("SPECIAL IRQ\n")); + ("SPECIAL IRQ DP-Cards => %x\n", IntSrc)); pAC->CheckQueue = SK_FALSE; spin_lock(&pAC->SlowPathLock); if (IntSrc & SPECIAL_IRQS) SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); + SkEventDispatcher(pAC, pAC->IoBase); spin_unlock(&pAC->SlowPathLock); } @@ -1351,33 +1502,17 @@ * came in after handling the ring (OUTs may be delayed * in hardware buffers, but are through after IN) */ - // ReceiveIrq(pAC, &pAC->RxPort[pAC->ActivePort]); - ReceiveIrq(pAC, &pAC->RxPort[0]); - ReceiveIrq(pAC, &pAC->RxPort[1]); - + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); + ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); + if (pAC->CheckQueue) { + pAC->CheckQueue = SK_FALSE; + spin_lock(&pAC->SlowPathLock); + SkEventDispatcher(pAC, pAC->IoBase); + spin_unlock(&pAC->SlowPathLock); + } -#if 0 -// #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); - spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - - spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); - FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); - spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); - -#if 0 /* only if sync. queues used */ - spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); - spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - - spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); - FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH); - spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); -#endif /* 0 */ -#endif /* USE_TX_COMPLETE */ /* IRQ is processed - Enable IRQs again*/ SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK); @@ -1401,7 +1536,7 @@ */ static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs) { -struct net_device *dev = (struct net_device *)dev_id; +struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; DEV_NET *pNet; SK_AC *pAC; SK_U32 IntSrc; /* interrupts source register contents */ @@ -1416,7 +1551,7 @@ if (IntSrc == 0) { return; } - + while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { #if 0 /* software irq currently not used */ if (IntSrc & IRQ_SW) { @@ -1429,15 +1564,15 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF RX1 IRQ\n")); - ReceiveIrq(pAC, &pAC->RxPort[0]); - SK_PNMI_CNT_RX_INTR(pAC,0); + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); + SK_PNMI_CNT_RX_INTR(pAC, 0); } #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ if (IntSrc & IRQ_EOF_AS_TX1) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC,0); + SK_PNMI_CNT_TX_INTR(pAC, 0); spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); @@ -1447,14 +1582,14 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC,1); + SK_PNMI_CNT_TX_INTR(pAC, 0); spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); ClearTxIrq(pAC, 0, TX_PRIO_HIGH); } -#endif /* 0 */ -#endif /* USE_TX_COMPLETE */ +#endif +#endif /* do all IO at once */ if (IntSrc & IRQ_EOF_RX1) @@ -1468,11 +1603,12 @@ if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, - ("SPECIAL IRQ\n")); + ("SPECIAL IRQ SP-Cards => %x\n", IntSrc)); pAC->CheckQueue = SK_FALSE; spin_lock(&pAC->SlowPathLock); if (IntSrc & SPECIAL_IRQS) SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); + SkEventDispatcher(pAC, pAC->IoBase); spin_unlock(&pAC->SlowPathLock); } @@ -1481,21 +1617,7 @@ * came in after handling the ring (OUTs may be delayed * in hardware buffers, but are through after IN) */ - ReceiveIrq(pAC, &pAC->RxPort[0]); - -#if 0 -// #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); - spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - -#if 0 /* only if sync. queues used */ - spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); - spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - -#endif /* 0 */ -#endif /* USE_TX_COMPLETE */ + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); /* IRQ is processed - Enable IRQs again*/ SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK); @@ -1521,13 +1643,13 @@ * != 0 on error */ static int SkGeOpen( -struct net_device *dev) +struct SK_NET_DEVICE *dev) { -DEV_NET *pNet; -SK_AC *pAC; -unsigned long Flags; /* for spin lock */ -int i; -SK_EVPARA EvPara; /* an event parameter union */ + DEV_NET *pNet; + SK_AC *pAC; + unsigned long Flags; /* for spin lock */ + int i; + SK_EVPARA EvPara; /* an event parameter union */ pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; @@ -1538,7 +1660,7 @@ if (pAC->BoardLevel == 0) { /* level 1 init common modules here */ if (SkGeInit(pAC, pAC->IoBase, 1) != 0) { - printk("%s: HWInit(1) failed\n", pAC->dev[pNet->PortNr]->name); + printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name); return (-1); } SkI2cInit (pAC, pAC->IoBase, 1); @@ -1551,8 +1673,11 @@ } if (pAC->BoardLevel != 2) { - /* level 2 init modules here */ - SkGeInit (pAC, pAC->IoBase, 2); + /* tschilling: Level 2 init modules here, check return value. */ + if (SkGeInit(pAC, pAC->IoBase, 2) != 0) { + printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name); + return (-1); + } SkI2cInit (pAC, pAC->IoBase, 2); SkEventInit (pAC, pAC->IoBase, 2); SkPnmiInit (pAC, pAC->IoBase, 2); @@ -1561,6 +1686,7 @@ SkTimerInit (pAC, pAC->IoBase, 2); pAC->BoardLevel = 2; } + for (i=0; iGIni.GIMacsFound; i++) { /* Enable transmit descriptor polling. */ SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); @@ -1627,18 +1753,17 @@ * error code - on error */ static int SkGeClose( -struct net_device *dev) +struct SK_NET_DEVICE *dev) { -DEV_NET *pNet; -SK_AC *pAC; + DEV_NET *pNet; + SK_AC *pAC; -unsigned long Flags; /* for spin lock */ -int i; -int PortIdx; -SK_EVPARA EvPara; + unsigned long Flags; /* for spin lock */ + int i; + int PortIdx; + SK_EVPARA EvPara; netif_stop_queue(dev); - pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; @@ -1653,7 +1778,6 @@ /* * Clear multicast table, promiscuous mode .... */ - SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0); SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, SK_PROM_MODE_NONE); @@ -1688,16 +1812,17 @@ spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr] [TX_PRIO_LOW].TxDesRingLock, Flags); } + if (pAC->RlmtNets == 1) { /* clear all descriptor rings */ for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i]); + ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); ClearRxRing(pAC, &pAC->RxPort[i]); ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]); } } else { /* clear port descriptor rings */ - ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr]); + ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); } @@ -1712,6 +1837,7 @@ return (0); } /* SkGeClose */ + /***************************************************************************** * * SkGeXmit - Linux frame transmit function @@ -1727,23 +1853,47 @@ * WARNING: returning 1 in 'tbusy' case caused system crashes (double * allocated skb's) !!! */ -static int SkGeXmit(struct sk_buff *skb, struct net_device *dev) +static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev) { DEV_NET *pNet; SK_AC *pAC; int Rc; /* return code of XmitFrame */ - + pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; - if (pAC->RlmtNets == 2) - Rc = XmitFrame(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], skb); - else - Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb); + if ((!skb_shinfo(skb)->nr_frags) || + (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) { + /* Don't activate scatter-gather and hardware checksum */ + + if (pAC->RlmtNets == 2) + Rc = XmitFrame( + pAC, + &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], + skb); + else + Rc = XmitFrame( + pAC, + &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], + skb); + } else { + /* scatter-gather and hardware TCP checksumming anabled*/ + if (pAC->RlmtNets == 2) + Rc = XmitFrameSG( + pAC, + &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], + skb); + else + Rc = XmitFrameSG( + pAC, + &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], + skb); + } /* Transmitter out of resources? */ - if (Rc <= 0) + if (Rc <= 0) { netif_stop_queue(dev); + } /* If not taken, give buffer ownership back to the * queueing layer. @@ -1773,10 +1923,10 @@ * if necessary. * * Returns: - * > 0 - on succes: the number of bytes in the message - * = 0 - on resource shortage: this frame sent or dropped, now - * the ring is full ( -> set tbusy) - * < 0 - on failure: other problems ( -> return failure to upper layers) + * > 0 - on succes: the number of bytes in the message + * = 0 - on resource shortage: this frame sent or dropped, now + * the ring is full ( -> set tbusy) + * < 0 - on failure: other problems ( -> return failure to upper layers) */ static int XmitFrame( SK_AC *pAC, /* pointer to adapter context */ @@ -1792,7 +1942,9 @@ ("X")); spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); - +#ifndef USE_TX_COMPLETE + FreeTxDescriptors(pAC, pTxPort); +#endif if (pTxPort->TxdRingFree == 0) { /* no enough free descriptors in ring at the moment */ FreeTxDescriptors(pAC, pTxPort); @@ -1803,6 +1955,8 @@ SK_DBGCAT_DRV_TX_PROGRESS, ("XmitFrame failed\n")); /* this message can not be sent now */ + /* Because tbusy seems to be set, the message should not be freed here */ + /* It will be used by the scheduler of the ethernet handler */ return (-1); } } @@ -1821,12 +1975,12 @@ #endif /* set up descriptor and CONTROL dword */ - PhysAddr = (SK_U64) pci_map_page(&pAC->PciDev, - virt_to_page(pMessage->data), - ((unsigned long) pMessage->data & - ~PAGE_MASK), - pMessage->len, - PCI_DMA_TODEVICE); + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + virt_to_page(pMessage->data), + ((unsigned long) pMessage->data & + ~PAGE_MASK), + pMessage->len, + PCI_DMA_TODEVICE); pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pTxd->pMBuf = pMessage; @@ -1847,18 +2001,200 @@ BytesSend = pMessage->len; + spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); /* after releasing the lock, the skb may be immidiately freed */ - if (pTxPort->TxdRingFree != 0) { - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); + if (pTxPort->TxdRingFree != 0) return (BytesSend); - } - else { - /* ring full: set tbusy on return */ - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); + else return (0); - } + } /* XmitFrame */ +/***************************************************************************** + * + * XmitFrameSG - fill one socket buffer into the transmit ring + * (use SG and TCP/UDP hardware checksumming) + * + * Description: + * This function puts a message into the transmit descriptor ring + * if there is a descriptors left. + * + * Returns: + * > 0 - on succes: the number of bytes in the message + * = 0 - on resource shortage: this frame sent or dropped, now + * the ring is full ( -> set tbusy) + * < 0 - on failure: other problems ( -> return failure to upper layers) + */ +static int XmitFrameSG( +SK_AC *pAC, /* pointer to adapter context */ +TX_PORT *pTxPort, /* pointer to struct of port to send to */ +struct sk_buff *pMessage) /* pointer to send-message */ +{ + + int i; + int BytesSend; + int hlength; + int protocol; + skb_frag_t *sk_frag; + TXD *pTxd; + TXD *pTxdFst; + TXD *pTxdLst; + SK_U64 PhysAddr; + unsigned long Flags; + + spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); +#ifndef USE_TX_COMPLETE + FreeTxDescriptors(pAC, pTxPort); +#endif + if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) { + FreeTxDescriptors(pAC, pTxPort); + if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) { + spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); + SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex); + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_TX_PROGRESS, + ("XmitFrameSG failed - Ring full\n")); + /* this message can not be sent now */ + return(-1); + } + } + + + pTxd = pTxPort->pTxdRingHead; + pTxdFst = pTxd; + pTxdLst = pTxd; + BytesSend = 0; + protocol = 0; + + /* map first fragment (header) */ + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + virt_to_page(pMessage->data), + ((unsigned long) pMessage->data & ~PAGE_MASK), + skb_headlen(pMessage), + PCI_DMA_TODEVICE); + + pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); + pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); + + /* HW checksum? */ + if (pMessage->ip_summed == CHECKSUM_HW) { + pTxd->TBControl = TX_CTRL_STF | + TX_CTRL_ST_FWD | + skb_headlen(pMessage); + + /* We have to use the opcode for tcp here because the opcode for + udp is not working in the hardware yet (revision 2.0)*/ + protocol = ((SK_U8)pMessage->data[23] & 0xf); + if ((protocol == 17) && (pAC->GIni.GIChipRev != 0)) + pTxd->TBControl |= BMU_UDP_CHECK; + else + pTxd->TBControl |= BMU_TCP_CHECK ; + + hlength = ((SK_U8)pMessage->data[14] & 0xf) * 4; + pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */ + pTxd->TcpSumSt = 14+hlength+16; + pTxd->TcpSumWr = 14+hlength; + + } else { + pTxd->TBControl = TX_CTRL_CHECK_DEFAULT | + TX_CTRL_SOFTWARE | + TX_CTRL_STF | + skb_headlen(pMessage); + } + + pTxd = pTxd->pNextTxd; + pTxPort->TxdRingFree--; + BytesSend += skb_headlen(pMessage); + + + /* Map SG fragments */ + for (i = 0; i < skb_shinfo(pMessage)->nr_frags; i++) { + sk_frag = &skb_shinfo(pMessage)->frags[i]; + + /* we already have the proper value in entry */ + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + sk_frag->page, + sk_frag->page_offset, + sk_frag->size, + PCI_DMA_TODEVICE); + + pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); + pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); + pTxd->pMBuf = pMessage; + + /* HW checksum */ + if (pMessage->ip_summed == CHECKSUM_HW) { + pTxd->TBControl = TX_CTRL_OWN_BMU | + TX_CTRL_SOFTWARE | + TX_CTRL_ST_FWD; + + /* We have to use the opcode for tcp here because the opcode for + udp is not working in the hardware yet (revision 2.0)*/ + if ((protocol == 17) && (pAC->GIni.GIChipRev != 0)) + pTxd->TBControl |= BMU_UDP_CHECK ; + else + pTxd->TBControl |= BMU_TCP_CHECK ; + + } else { + pTxd->TBControl = TX_CTRL_CHECK_DEFAULT | + TX_CTRL_SOFTWARE | + TX_CTRL_OWN_BMU; + } + + /* Last fragment */ + if( (i+1) == skb_shinfo(pMessage)->nr_frags ) { +#ifdef USE_TX_COMPLETE + pTxd->TBControl |= TX_CTRL_EOF | + TX_CTRL_EOF_IRQ | + sk_frag->size; +#else + pTxd->TBControl |= TX_CTRL_EOF | + sk_frag->size; +#endif + pTxdFst->TBControl |= TX_CTRL_OWN_BMU | + TX_CTRL_SOFTWARE; + + } else { + pTxd->TBControl |= sk_frag->size; + } + pTxdLst = pTxd; + pTxd = pTxd->pNextTxd; + pTxPort->TxdRingFree--; + BytesSend += sk_frag->size; + } + + if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) { + /* previous descriptor already done, so give tx start cmd */ + /* StartTx(pAC, pTxPort->HwAddr); */ + SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START); + } + + pTxPort->pTxdRingPrev = pTxdLst; + pTxPort->pTxdRingHead = pTxd; + + spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); + + if (pTxPort->TxdRingFree > 0) + return (BytesSend); + else + return (0); +} + + +void dump_frag( SK_U8 *data, int length) +{ + int i; + + printk("Length: %d\n", length); + for( i=0; i < length; i++ ) { + printk(" %02x", (SK_U8)*(data + i) ); + if( !((i+1) % 20) ) + printk("\n"); + } + printk("\n\n"); + +} + /***************************************************************************** * @@ -1889,7 +2225,6 @@ pNewTail = pTxPort->pTxdRingTail; pTxd = pNewTail; - /* * loop forever; exits if TX_CTRL_SOFTWARE bit not set in start frame * or TX_CTRL_OWN_BMU bit set in any frame @@ -1918,19 +2253,19 @@ /* release the DMA mapping */ PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32; PhysAddr |= (SK_U64) pTxd->VDataLow; - pci_unmap_page(&pAC->PciDev, PhysAddr, - pTxd->pMBuf->len, - PCI_DMA_TODEVICE); + pci_unmap_page(pAC->PciDev, PhysAddr, + pTxd->pMBuf->len, + PCI_DMA_TODEVICE); + + if (Control & TX_CTRL_EOF) + DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */ - /* free message */ - DEV_KFREE_SKB_ANY(pTxd->pMBuf); pTxPort->TxdRingFree++; pTxd->TBControl &= ~TX_CTRL_SOFTWARE; pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */ } /* while(forever) */ } /* FreeTxDescriptors */ - /***************************************************************************** * * FillRxRing - fill the receive ring with valid descriptors @@ -1999,12 +2334,12 @@ pRxPort->pRxdRingTail = pRxd->pNextRxd; pRxPort->RxdRingFree--; Length = pAC->RxBufSize; - PhysAddr = (SK_U64) pci_map_page(&pAC->PciDev, - virt_to_page(pMsgBlock->data), - ((unsigned long) pMsgBlock->data & - ~PAGE_MASK), - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + virt_to_page(pMsgBlock->data), + ((unsigned long) pMsgBlock->data & + ~PAGE_MASK), + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pRxd->pMBuf = pMsgBlock; @@ -2061,28 +2396,32 @@ * Returns: N/A */ static void ReceiveIrq( -SK_AC *pAC, /* pointer to adapter context */ -RX_PORT *pRxPort) /* pointer to receive port struct */ -{ -RXD *pRxd; /* pointer to receive descriptors */ -SK_U32 Control; /* control field of descriptor */ -struct sk_buff *pMsg; /* pointer to message holding frame */ -struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ -int FrameLength; /* total length of received frame */ -SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ -SK_EVPARA EvPara; /* an event parameter union */ -int PortIndex = pRxPort->PortIndex; + SK_AC *pAC, /* pointer to adapter context */ + RX_PORT *pRxPort, /* pointer to receive port struct */ + SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */ +{ +RXD *pRxd; /* pointer to receive descriptors */ +SK_U32 Control; /* control field of descriptor */ +struct sk_buff *pMsg; /* pointer to message holding frame */ +struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ +int FrameLength; /* total length of received frame */ +SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ +SK_EVPARA EvPara; /* an event parameter union */ +unsigned long Flags; /* for spin lock */ +int PortIndex = pRxPort->PortIndex; unsigned int Offset; unsigned int NumBytes; unsigned int ForRlmt; -SK_BOOL IsBc; -SK_BOOL IsMc; -SK_U32 FrameStat; +SK_BOOL IsBc; +SK_BOOL IsMc; +SK_BOOL IsBadFrame; /* Bad frame */ + +SK_U32 FrameStat; unsigned short Csum1; unsigned short Csum2; unsigned short Type; -int Result; -SK_U64 PhysAddr; +int Result; +SK_U64 PhysAddr; rx_start: /* do forever; exit if RX_CTRL_OWN_BMU found */ @@ -2124,33 +2463,75 @@ (RX_CTRL_STF | RX_CTRL_EOF)) { goto rx_failed; } - + /* here we have a complete frame in the ring */ pMsg = pRxd->pMBuf; FrameStat = pRxd->FrameStat; + + /* check for frame length mismatch */ +#define XMR_FS_LEN_SHIFT 18 +#define GMR_FS_LEN_SHIFT 16 + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS, + ("skge: Frame length mismatch (%u/%u).\n", + FrameLength, + (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); + goto rx_failed; + } + } + else { + if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS, + ("skge: Frame length mismatch (%u/%u).\n", + FrameLength, + (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); + goto rx_failed; + } + } + + /* Set Rx Status */ + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + IsBc = (FrameStat & XMR_FS_BC) != 0; + IsMc = (FrameStat & XMR_FS_MC) != 0; + IsBadFrame = (FrameStat & + (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0; + } else { + IsBc = (FrameStat & GMR_FS_BC) != 0; + IsMc = (FrameStat & GMR_FS_MC) != 0; + IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) || + ((FrameStat & GMR_FS_RX_OK) == 0)); + } + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0, ("Received frame of length %d on port %d\n", FrameLength, PortIndex)); SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0, ("Number of free rx descriptors: %d\n", pRxPort->RxdRingFree)); - /*DumpMsg(pMsg, "Rx"); */ - +/* DumpMsg(pMsg, "Rx"); */ + if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID || + (IsBadFrame)) { +#if 0 (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) { +#endif /* there is a receive error in this frame */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ("skge: Error in received frame, dropped!\n" "Control: %x\nRxStat: %x\n", Control, FrameStat)); + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_dma_sync_single(&pAC->PciDev, - (dma_addr_t) PhysAddr, - FrameLength, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single(pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength, + PCI_DMA_FROMDEVICE); ReQueueRxBuffer(pAC, pRxPort, pMsg, pRxd->VDataHigh, pRxd->VDataLow); @@ -2165,16 +2546,16 @@ /* * Short frame detected and allocation successfull */ - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; - PhysAddr |= (SK_U64) pRxd->VDataLow; - /* use new skb and copy data */ skb_reserve(pNewMsg, 2); skb_put(pNewMsg, FrameLength); - pci_dma_sync_single(&pAC->PciDev, - (dma_addr_t) PhysAddr, - FrameLength, - PCI_DMA_FROMDEVICE); + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; + PhysAddr |= (SK_U64) pRxd->VDataLow; + + pci_dma_sync_single(pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(pNewMsg, pMsg->data, FrameLength, 0); ReQueueRxBuffer(pAC, pRxPort, pMsg, @@ -2192,10 +2573,10 @@ PhysAddr |= (SK_U64) pRxd->VDataLow; /* release the DMA mapping */ - pci_unmap_page(&pAC->PciDev, - PhysAddr, - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); + pci_unmap_single(pAC->PciDev, + PhysAddr, + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); /* set length in message */ skb_put(pMsg, FrameLength); @@ -2204,11 +2585,13 @@ if (Type == 0x800) { Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff); Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff); - if ((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) { + if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) && + (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { Result = SkCsGetReceiveInfo(pAC, &pMsg->data[14], Csum1, Csum2, pRxPort->PortIndex); - if (Result == + if (Result == SKCS_STATUS_IP_FRAGMENT || Result == SKCS_STATUS_IP_CSUM_OK || @@ -2216,20 +2599,29 @@ SKCS_STATUS_TCP_CSUM_OK || Result == SKCS_STATUS_UDP_CSUM_OK) { - pMsg->ip_summed = - CHECKSUM_UNNECESSARY; + pMsg->ip_summed = + CHECKSUM_UNNECESSARY; + } else { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS, + ("skge: CRC error. Frame dropped!\n")); + goto rx_failed; } - } /* checksum calculation valid */ + }/* checksumControl calculation valid */ } /* IP frame */ } /* frame > SK_COPY_TRESHOLD */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V")); ForRlmt = SK_RLMT_RX_PROTOCOL; +#if 0 IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC; +#endif SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength, IsBc, &Offset, &NumBytes); if (NumBytes != 0) { +#if 0 IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC; +#endif SK_RLMT_LOOKAHEAD(pAC, PortIndex, &pMsg->data[Offset], IsBc, IsMc, &ForRlmt); @@ -2276,10 +2668,22 @@ memcpy((char*)(pRlmtMbuf->pData), (char*)(pMsg->data), FrameLength); - SkEventQueue(pAC, SKGE_RLMT, - SK_RLMT_PACKET_RECEIVED, - EvPara); - pAC->CheckQueue = SK_TRUE; + + /* SlowPathLock needed? */ + if (SlowPathLock == SK_TRUE) { + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + SkEventQueue(pAC, SKGE_RLMT, + SK_RLMT_PACKET_RECEIVED, + EvPara); + pAC->CheckQueue = SK_TRUE; + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + } else { + SkEventQueue(pAC, SKGE_RLMT, + SK_RLMT_PACKET_RECEIVED, + EvPara); + pAC->CheckQueue = SK_TRUE; + } + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ("Q")); @@ -2315,12 +2719,13 @@ ("Schrottdescriptor, length: 0x%x\n", FrameLength)); /* release the DMA mapping */ + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_unmap_page(&pAC->PciDev, - PhysAddr, - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); + pci_unmap_page(pAC->PciDev, + PhysAddr, + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); DEV_KFREE_SKB_IRQ(pRxd->pMBuf); pRxd->pMBuf = NULL; pRxPort->RxdRingFree++; @@ -2386,7 +2791,7 @@ { RXD *pRxd; /* pointer to the current descriptor */ unsigned long Flags; - SK_U64 PhysAddr; +SK_U64 PhysAddr; if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) { return; @@ -2395,12 +2800,13 @@ pRxd = pRxPort->pRxdRingHead; do { if (pRxd->pMBuf != NULL) { + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_unmap_page(&pAC->PciDev, - PhysAddr, - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); + pci_unmap_page(pAC->PciDev, + PhysAddr, + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); DEV_KFREE_SKB(pRxd->pMBuf); pRxd->pMBuf = NULL; } @@ -2549,7 +2955,7 @@ * 0, if everything is ok * !=0, on error */ -static int SkGeSetMacAddr(struct net_device *dev, void *p) +static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p) { DEV_NET *pNet = (DEV_NET*) dev->priv; @@ -2557,12 +2963,12 @@ struct sockaddr *addr = p; unsigned long Flags; - + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeSetMacAddr starts now...\n")); - if(netif_running(dev)) { + if(netif_running(dev)) return -EBUSY; - } + memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); spin_lock_irqsave(&pAC->SlowPathLock, Flags); @@ -2595,7 +3001,7 @@ * 0, if everything is ok * !=0, on error */ -static void SkGeSetRxMode(struct net_device *dev) +static void SkGeSetRxMode(struct SK_NET_DEVICE *dev) { DEV_NET *pNet; @@ -2649,7 +3055,6 @@ pMcList->dmi_addr[5])); } SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx); - } spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); @@ -2670,7 +3075,7 @@ * 0, if everything is ok * !=0, on error */ -static int SkGeChangeMtu(struct net_device *dev, int NewMtu) +static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu) { DEV_NET *pNet; DEV_NET *pOtherNet; @@ -2689,6 +3094,10 @@ return -EINVAL; } + if(pAC->BoardLevel != 2) { + return -EINVAL; + } + pNet->Mtu = NewMtu; pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv; if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) { @@ -2704,10 +3113,6 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("New MTU: %d\n", NewMtu)); - if(pAC->BoardLevel != 2) { - return 0; - } - /* prevent reconfiguration while changing the MTU */ /* disable interrupts */ @@ -2732,6 +3137,7 @@ spin_lock_irqsave( &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags); netif_stop_queue(pAC->dev[i]); + } /* @@ -2756,7 +3162,7 @@ } } else { - /* use normal anoumt of rx buffers */ + /* use normal amount of rx buffers */ for (i=0; iGIni.GIMacsFound; i++) { /* Found more than one port */ if ((pAC->GIni.GIMacsFound == 2 ) && @@ -2780,10 +3186,6 @@ if (NewMtu > 1500) { // pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ pAC->GIni.GIPortUsage = SK_JUMBO_LINK; - for (i=0; iGIni.GIMacsFound; i++) { - pAC->GIni.GP[i].PRxCmd = - XM_RX_STRIP_FCS | XM_RX_LENERR_OK; - } } else { if ((pAC->GIni.GIMacsFound == 2 ) && @@ -2792,9 +3194,6 @@ } else { pAC->GIni.GIPortUsage = SK_RED_LINK; } - for (i=0; iGIni.GIMacsFound; i++) { - pAC->GIni.GP[i].PRxCmd = XM_RX_STRIP_FCS; - } } SkGeInit( pAC, pAC->IoBase, 1); @@ -2805,6 +3204,12 @@ SkRlmtInit( pAC, pAC->IoBase, 1); SkTimerInit(pAC, pAC->IoBase, 1); + /* + * tschilling: + * Speed and others are set back to default in level 1 init! + */ + GetConfiguration(pAC); + SkGeInit( pAC, pAC->IoBase, 2); SkI2cInit( pAC, pAC->IoBase, 2); SkEventInit(pAC, pAC->IoBase, 2); @@ -2817,7 +3222,7 @@ * clear and reinit the rx rings here */ for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i]); + ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); ClearRxRing(pAC, &pAC->RxPort[i]); FillRxRing(pAC, &pAC->RxPort[i]); @@ -2891,12 +3296,13 @@ * Returns: * pointer to the statistic structure. */ -static struct net_device_stats *SkGeStats(struct net_device *dev) +static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev) { DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */ -SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */ +SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */ +SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */ unsigned int Size; /* size of pnmi struct */ unsigned long Flags; /* for spin lock */ @@ -2915,7 +3321,18 @@ pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF; pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts; pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts; - pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF; + + if (pNet->Mtu <= 1500) { + pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF; + } else { + pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts - + pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF); + } + + + if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12) + pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts; + pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF; pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF; @@ -2954,7 +3371,7 @@ * 0, if everything is ok * !=0, on error */ -static int SkGeIoctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd) { DEV_NET *pNet; SK_AC *pAC; @@ -3068,6 +3485,7 @@ SK_AC *pAC) /* pointer to the adapter context structure */ { SK_I32 Port; /* preferred port */ +int LinkSpeed; /* Link speed */ int AutoNeg; /* auto negotiation off (0) or on (1) */ int DuplexCap; /* duplex capabilities (0=both, 1=full, 2=half */ int MSMode; /* master / slave mode selection */ @@ -3097,7 +3515,44 @@ #define AN_SENS 2 /* settings for port A */ - AutoNeg = AN_SENS; /* default: do auto Sense */ + /* settings link speed */ + LinkSpeed = SK_LSPEED_AUTO; /* default: do auto select */ + if (Speed_A != NULL && pAC->IndexIndex] != NULL) { + if (strcmp(Speed_A[pAC->Index],"")==0) { + LinkSpeed = SK_LSPEED_AUTO; + } + else if (strcmp(Speed_A[pAC->Index],"Auto")==0) { + LinkSpeed = SK_LSPEED_AUTO; + } + else if (strcmp(Speed_A[pAC->Index],"10")==0) { + LinkSpeed = SK_LSPEED_10MBPS; + } + else if (strcmp(Speed_A[pAC->Index],"100")==0) { + LinkSpeed = SK_LSPEED_100MBPS; + } + else if (strcmp(Speed_A[pAC->Index],"1000")==0) { + LinkSpeed = SK_LSPEED_1000MBPS; + } + else printk("%s: Illegal value for Speed_A\n", + pAC->dev[0]->name); + } + + /* Check speed parameter */ + /* Only copper type adapter and GE V2 cards */ + if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) || + (pAC->GIni.GICopperType != SK_TRUE)) && + ((LinkSpeed != SK_LSPEED_AUTO) && + (LinkSpeed != SK_LSPEED_1000MBPS))) { + printk("%s: Illegal value for Speed_A. " + "Not a copper card or GE V2 card\n Using " + "speed 1000\n", pAC->dev[0]->name); + LinkSpeed = SK_LSPEED_1000MBPS; + } + pAC->GIni.GP[0].PLinkSpeed = LinkSpeed; + + /* Autonegotiation */ + AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */ AutoSet = SK_FALSE; if (AutoNeg_A != NULL && pAC->IndexIndex] != NULL) { @@ -3219,6 +3674,43 @@ /* settings for port B */ + /* settings link speed */ + LinkSpeed = SK_LSPEED_AUTO; /* default: do auto select */ + if (Speed_B != NULL && pAC->IndexIndex] != NULL) { + if (strcmp(Speed_B[pAC->Index],"")==0) { + LinkSpeed = SK_LSPEED_AUTO; + } + else if (strcmp(Speed_B[pAC->Index],"Auto")==0) { + LinkSpeed = SK_LSPEED_AUTO; + } + else if (strcmp(Speed_B[pAC->Index],"10")==0) { + LinkSpeed = SK_LSPEED_10MBPS; + } + else if (strcmp(Speed_B[pAC->Index],"100")==0) { + LinkSpeed = SK_LSPEED_100MBPS; + } + else if (strcmp(Speed_B[pAC->Index],"1000")==0) { + LinkSpeed = SK_LSPEED_1000MBPS; + } + else printk("%s: Illegal value for Speed_B\n", + pAC->dev[1]->name); + } + + /* Check speed parameter */ + /* Only copper type adapter and GE V2 cards */ + if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) || + (pAC->GIni.GICopperType != SK_TRUE)) && + ((LinkSpeed != SK_LSPEED_AUTO) && + (LinkSpeed != SK_LSPEED_1000MBPS))) { + printk("%s: Illegal value for Speed_B. " + "Not a copper card or GE V2 card\n Using " + "speed 1000\n", pAC->dev[1]->name); + LinkSpeed = SK_LSPEED_1000MBPS; + } + pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; + + /* Auto negotiation */ AutoNeg = AN_SENS; /* default: do auto Sense */ AutoSet = SK_FALSE; if (AutoNeg_B != NULL && pAC->IndexRlmtNets = 1; - + if (RlmtMode != NULL && pAC->IndexIndex] != NULL) { if (strcmp(RlmtMode[pAC->Index], "") == 0) { @@ -3396,10 +3888,6 @@ else { printk("%s: Illegal value for" " RlmtMode, using default\n", pAC->dev[0]->name); - -printk("MacFound = %d\nRlmtMode = %s", pAC->GIni.GIMacsFound, RlmtMode[pAC->Index]); - - pAC->RlmtMode = 0; } } @@ -3551,7 +4039,7 @@ int PciAddr, /* PCI register address */ SK_U32 *pVal) /* pointer to store the read value */ { - pci_read_config_dword(&pAC->PciDev, PciAddr, pVal); + pci_read_config_dword(pAC->PciDev, PciAddr, pVal); return(0); } /* SkPciReadCfgDWord */ @@ -3573,7 +4061,7 @@ int PciAddr, /* PCI register address */ SK_U16 *pVal) /* pointer to store the read value */ { - pci_read_config_word(&pAC->PciDev, PciAddr, pVal); + pci_read_config_word(pAC->PciDev, PciAddr, pVal); return(0); } /* SkPciReadCfgWord */ @@ -3595,7 +4083,7 @@ int PciAddr, /* PCI register address */ SK_U8 *pVal) /* pointer to store the read value */ { - pci_read_config_byte(&pAC->PciDev, PciAddr, pVal); + pci_read_config_byte(pAC->PciDev, PciAddr, pVal); return(0); } /* SkPciReadCfgByte */ @@ -3617,7 +4105,7 @@ int PciAddr, /* PCI register address */ SK_U32 Val) /* pointer to store the read value */ { - pci_write_config_dword(&pAC->PciDev, PciAddr, Val); + pci_write_config_dword(pAC->PciDev, PciAddr, Val); return(0); } /* SkPciWriteCfgDWord */ @@ -3640,7 +4128,7 @@ int PciAddr, /* PCI register address */ SK_U16 Val) /* pointer to store the read value */ { - pci_write_config_word(&pAC->PciDev, PciAddr, Val); + pci_write_config_word(pAC->PciDev, PciAddr, Val); return(0); } /* SkPciWriteCfgWord */ @@ -3663,7 +4151,7 @@ int PciAddr, /* PCI register address */ SK_U8 Val) /* pointer to store the read value */ { - pci_write_config_byte(&pAC->PciDev, PciAddr, Val); + pci_write_config_byte(pAC->PciDev, PciAddr, Val); return(0); } /* SkPciWriteCfgByte */ @@ -3696,6 +4184,7 @@ SK_EVPARA NewPara; /* parameter for further events */ int Stat; unsigned long Flags; +SK_BOOL DualNet; switch (Event) { case SK_DRV_ADAP_FAIL: @@ -3728,18 +4217,27 @@ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); + pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING; spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); /* clear rx ring from received frames */ - ReceiveIrq(pAC, &pAC->RxPort[FromPort]); + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - SkGeInitPort(pAC, IoC, FromPort); + + /* tschilling: Handling of return value inserted. */ + if (SkGeInitPort(pAC, IoC, FromPort)) { + if (FromPort == 0) { + printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name); + } else { + printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); + } + } SkAddrMcUpdate(pAC,IoC, FromPort); PortReInitBmu(pAC, FromPort); SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); @@ -3755,7 +4253,19 @@ ("NET UP EVENT, Port: %d ", Param.Para32[0])); printk("%s: network connection up using" " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); - printk(" speed: 1000\n"); + + /* tschilling: Values changed according to LinkSpeedUsed. */ + Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed; + if (Stat == SK_LSPEED_STAT_10MBPS) { + printk(" speed: 10\n"); + } else if (Stat == SK_LSPEED_STAT_100MBPS) { + printk(" speed: 100\n"); + } else if (Stat == SK_LSPEED_STAT_1000MBPS) { + printk(" speed: 1000\n"); + } else { + printk(" speed: unknown\n"); + } + Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; if (Stat == SK_LMODE_STAT_AUTOHALF || Stat == SK_LMODE_STAT_AUTOFULL) { @@ -3784,8 +4294,12 @@ else { printk(" flowctrl: none\n"); } - if (pAC->GIni.GP[FromPort].PhyType != SK_PHY_XMAC) { - Stat = pAC->GIni.GP[FromPort].PMSStatus; + + /* tschilling: Check against CopperType now. */ + if ((pAC->GIni.GICopperType == SK_TRUE) && + (pAC->GIni.GP[FromPort].PLinkSpeedUsed == + SK_LSPEED_STAT_1000MBPS)) { + Stat = pAC->GIni.GP[FromPort].PMSStatus; if (Stat == SK_MS_STAT_MASTER ) { printk(" role: master\n"); } @@ -3796,6 +4310,16 @@ printk(" role: ???\n"); } } + +#ifdef SK_ZEROCOPY + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) + printk(" scatter-gather: enabled\n"); + else + printk(" scatter-gather: disabled\n"); + +#else + printk(" scatter-gather: disabled\n"); +#endif if ((Param.Para32[0] != pAC->ActivePort) && (pAC->RlmtNets == 1)) { @@ -3804,12 +4328,17 @@ SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN, NewPara); } + + /* Inform the world that link protocol is up. */ + pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING; + break; case SK_DRV_NET_DOWN: /* SK_U32 Reason */ /* action list 7 */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("NET DOWN EVENT ")); printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name); + pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING; break; case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, @@ -3841,8 +4370,8 @@ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - ReceiveIrq(pAC, &pAC->RxPort[FromPort]); /* clears rx ring */ - ReceiveIrq(pAC, &pAC->RxPort[ToPort]); /* clears rx ring */ + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */ + ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */ ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]); @@ -3852,13 +4381,37 @@ spin_lock_irqsave( &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); pAC->ActivePort = ToPort; +#if 0 SetQueueSizes(pAC); - SkGeInitPort(pAC, IoC, FromPort); - SkGeInitPort(pAC, IoC, ToPort); +#else + /* tschilling: New common function with minimum size check. */ + DualNet = SK_FALSE; + if (pAC->RlmtNets == 2) { + DualNet = SK_TRUE; + } + + if (SkGeInitAssignRamToQueues( + pAC, + pAC->ActivePort, + DualNet)) { + spin_unlock_irqrestore( + &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_unlock_irqrestore( + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + Flags); + printk("SkGeInitAssignRamToQueues failed.\n"); + break; + } +#endif + /* tschilling: Handling of return values inserted. */ + if (SkGeInitPort(pAC, IoC, FromPort) || + SkGeInitPort(pAC, IoC, ToPort)) { + printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name); + } if (Event == SK_DRV_SWITCH_SOFT) { - SkXmRxTxEnable(pAC, IoC, FromPort); + SkMacRxTxEnable(pAC, IoC, FromPort); } - SkXmRxTxEnable(pAC, IoC, ToPort); + SkMacRxTxEnable(pAC, IoC, ToPort); SkAddrSwap(pAC, IoC, FromPort, ToPort); SkAddrMcUpdate(pAC, IoC, FromPort); SkAddrMcUpdate(pAC, IoC, ToPort); @@ -3881,7 +4434,8 @@ pMsg = (struct sk_buff*) pRlmtMbuf->pOs; skb_put(pMsg, pRlmtMbuf->Length); if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], - pMsg) < 0) + pMsg) < 0) + DEV_KFREE_SKB_ANY(pMsg); break; default: @@ -3943,7 +4497,8 @@ } /* SkErrorLog */ -#ifdef DEBUG /***************************************************************/ +#ifdef DEBUG +/****************************************************************************/ /* "debug only" section *****************************************************/ /****************************************************************************/ @@ -4090,7 +4645,7 @@ printk("------------------------\n"); } /* DumpLong */ -#endif /* DEBUG */ +#endif /* * Local variables: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skgehwt.c linux.21pre4-ac6/drivers/net/sk98lin/skgehwt.c --- linux.21pre4/drivers/net/sk98lin/skgehwt.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skgehwt.c 2003-01-06 15:38:18.000000000 +0000 @@ -1,32 +1,23 @@ /****************************************************************************** * * Name: skgehwt.c - * Project: PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.12 $ - * Date: $Date: 1998/10/15 15:11:34 $ + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.13 $ + * Date: $Date: 1999/11/22 13:31:12 $ * Purpose: Hardware Timer. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1989-1998 SysKonnect, + * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. - * All Rights Reserved * - * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT - * The copyright notice above does not evidence any - * actual or intended publication of such source code. - * - * This Module contains Proprietary Information of SysKonnect - * and should be treated as Confidential. - * - * The information in this file is provided for the exclusive use of - * the licensees of SysKonnect. - * Such users have the right to use, modify, and incorporate this code - * into products for purposes authorized by the license agreement - * provided they include this notice and the associated copyright notice - * with any such product. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -36,6 +27,9 @@ * History: * * $Log: skgehwt.c,v $ + * Revision 1.13 1999/11/22 13:31:12 cgoos + * Changed license header to GPL. + * * Revision 1.12 1998/10/15 15:11:34 gklug * fix: ID_sccs to SysKonnectFileId * @@ -83,7 +77,7 @@ Event queue and dispatcher */ static const char SysKonnectFileId[] = - "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.12 1998/10/15 15:11:34 gklug Exp $" ; + "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skgeinit.c linux.21pre4-ac6/drivers/net/sk98lin/skgeinit.c --- linux.21pre4/drivers/net/sk98lin/skgeinit.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skgeinit.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skgeinit.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.63 $ - * Date: $Date: 2001/04/05 11:02:09 $ + * Version: $Revision: 1.82 $ + * Date: $Date: 2002/12/05 13:40:21 $ * Purpose: Contains functions to initialize the GE HW * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,108 @@ * History: * * $Log: skgeinit.c,v $ + * Revision 1.82 2002/12/05 13:40:21 rschmidt + * Added setting of Rx GMAC FIFO Flush Mask register. + * Corrected PhyType with new define SK_PHY_MARV_FIBER when + * YUKON Fiber board was found. + * Editorial changes. + * + * Revision 1.81 2002/11/15 12:48:35 rschmidt + * Replaced message SKERR_HWI_E018 with SKERR_HWI_E024 for Rx queue error + * in SkGeStopPort(). + * Added init for pAC->GIni.GIGenesis with SK_FALSE in YUKON-branch. + * Editorial changes. + * + * Revision 1.80 2002/11/12 17:28:30 rschmidt + * Initialized GIPciSlot64 and GIPciClock66 in SkGeInit1(). + * Reduced PCI FIFO watermarks for 32bit/33MHz bus in SkGeInitBmu(). + * Editorial changes. + * + * Revision 1.79 2002/10/21 09:31:02 mkarl + * Changed SkGeInitAssignRamToQueues(), removed call to + * SkGeInitAssignRamToQueues in SkGeInit1 and fixed compiler warning in + * SkGeInit1. + * + * Revision 1.78 2002/10/16 15:55:07 mkarl + * Fixed a bug in SkGeInitAssignRamToQueues. + * + * Revision 1.77 2002/10/14 15:07:22 rschmidt + * Corrected timeout handling for Rx queue in SkGeStopPort() (#10748) + * Editorial changes. + * + * Revision 1.76 2002/10/11 09:24:38 mkarl + * Added check for HW self test results. + * + * Revision 1.75 2002/10/09 16:56:44 mkarl + * Now call SkGeInitAssignRamToQueues() in Init Level 1 in order to assign + * the adapter memory to the queues. This default assignment is not suitable + * for dual net mode. + * + * Revision 1.74 2002/09/12 08:45:06 rwahl + * Set defaults for PMSCap, PLinkSpeed & PLinkSpeedCap dependent on PHY. + * + * Revision 1.73 2002/08/16 15:19:45 rschmidt + * Corrected check for Tx queues in SkGeCheckQSize(). + * Added init for new entry GIGenesis and GICopperType + * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. + * Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros. + * + * Revision 1.72 2002/08/12 13:38:55 rschmidt + * Added check if VAUX is available (stored in GIVauxAvail) + * Initialized PLinkSpeedCap in Port struct with SK_LSPEED_CAP_1000MBPS + * Editorial changes. + * + * Revision 1.71 2002/08/08 16:32:58 rschmidt + * Added check for Tx queues in SkGeCheckQSize(). + * Added start of Time Stamp Timer (YUKON) in SkGeInit2(). + * Editorial changes. + * + * Revision 1.70 2002/07/23 16:04:26 rschmidt + * Added init for GIWolOffs (HW-Bug in YUKON 1st rev.) + * Minor changes + * + * Revision 1.69 2002/07/17 17:07:08 rwahl + * - SkGeInit1(): fixed PHY type debug output; corrected init of GIFunc + * table & GIMacType. + * - Editorial changes. + * + * Revision 1.68 2002/07/15 18:38:31 rwahl + * Added initialization for MAC type dependent function table. + * + * Revision 1.67 2002/07/15 15:45:39 rschmidt + * Added Tx Store & Forward for YUKON (GMAC Tx FIFO is only 1 kB) + * Replaced SK_PHY_MARV by SK_PHY_MARV_COPPER + * Editorial changes + * + * Revision 1.66 2002/06/10 09:35:08 rschmidt + * Replaced C++ comments (//) + * Editorial changes + * + * Revision 1.65 2002/06/05 08:33:37 rschmidt + * Changed GIRamSize and Reset sequence for YUKON. + * SkMacInit() replaced by SkXmInitMac() resp. SkGmInitMac() + * + * Revision 1.64 2002/04/25 13:03:20 rschmidt + * Changes for handling YUKON. + * Removed reference to xmac_ii.h (not necessary). + * Moved all defines into header file. + * Replaced all SkXm...() functions with SkMac...() to handle also + * YUKON's GMAC. + * Added handling for GMAC FIFO in SkGeInitMacFifo(), SkGeStopPort(). + * Removed 'goto'-directive from SkGeCfgSync(), SkGeCheckQSize(). + * Replaced all XMAC-access macros by functions: SkMacRxTxDisable(), + * SkMacFlushTxFifo(). + * Optimized timeout handling in SkGeStopPort(). + * Initialized PLinkSpeed in Port struct with SK_LSPEED_AUTO. + * Release of GMAC Link Control reset in SkGeInit1(). + * Initialized GIChipId and GIChipRev in GE Init structure. + * Added GIRamSize and PhyType values for YUKON. + * Removed use of PRxCmd to setup XMAC. + * Moved setting of XM_RX_DIS_CEXT to SkXmInitMac(). + * Use of SkGeXmitLED() only for GENESIS. + * Changes for V-CPU support. + * Editorial changes. + * * Revision 1.63 2001/04/05 11:02:09 rassmann * Stop Port check of the STOP bit did not take 2/18 sec as wanted. * @@ -139,7 +241,7 @@ * chg: Default is autosensing with AUTOFULL mode * * Revision 1.31 1998/11/25 15:36:16 gklug - * fix: do NOT stop LED Timer when port should be stoped + * fix: do NOT stop LED Timer when port should be stopped * * Revision 1.30 1998/11/24 13:15:28 gklug * add: Init PCkeckPar struct member @@ -150,8 +252,8 @@ * transmit timeouts. * Add TestStopBit() function to handle stop RX/TX * problem with active descriptor poll timers. - * Bug Fix: Descriptor Poll Timer not started, beacuse - * GIPollTimerVal was initilaized with 0. + * Bug Fix: Descriptor Poll Timer not started, because + * GIPollTimerVal was initialized with 0. * * Revision 1.28 1998/11/13 14:24:26 malthoff * Bug Fix: SkGeStopPort() may hang if a Packet Arbiter Timout @@ -181,7 +283,7 @@ * * Revision 1.21 1998/10/20 12:11:56 malthoff * Don't dendy the Queue config if the size of the unused - * rx qeueu is zero. + * Rx qeueu is zero. * * Revision 1.20 1998/10/19 07:27:58 malthoff * SkGeInitRamIface() is public to be called by diagnostics. @@ -268,39 +370,21 @@ * * Revision 1.1 1998/07/23 09:48:57 malthoff * Creation. First dummy 'C' file. - * SkGeInit(Level 0) is card_start for ML. - * SkGeDeInit() is card_stop for ML. + * SkGeInit(Level 0) is card_start for GE. + * SkGeDeInit() is card_stop for GE. * * ******************************************************************************/ #include "h/skdrv1st.h" -#include "h/xmac_ii.h" #include "h/skdrv2nd.h" -/* defines ********************************************************************/ - -/* defines for SkGeXmitLed() */ -#define XMIT_LED_INI 0 -#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI) -#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI) -#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI) - -/* Queue Size units */ -#define QZ_UNITS 0x7 - -/* Types of RAM Buffer Queues */ -#define SK_RX_SRAM_Q 1 /* small receive queue */ -#define SK_RX_BRAM_Q 2 /* big receive queue */ -#define SK_TX_RAM_Q 3 /* small or big transmit queue */ - -/* typedefs *******************************************************************/ /* global variables ***********************************************************/ /* local variables ************************************************************/ static const char SysKonnectFileId[] = - "@(#)$Id: skgeinit.c,v 1.63 2001/04/05 11:02:09 rassmann Exp $ (C) SK "; + "@(#)$Id: skgeinit.c,v 1.82 2002/12/05 13:40:21 rschmidt Exp $ (C) SK "; struct s_QOffTab { int RxQOff; /* Receive Queue Address Offset */ @@ -314,11 +398,11 @@ /****************************************************************************** * - * SkGePollRxD() - Enable/Disable Descriptor Polling of RxD Ring + * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring * * Description: * Enable or disable the descriptor polling the receive descriptor - * ring (RxD) of port 'port'. + * ring (RxD) of port 'Port'. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * @@ -335,22 +419,18 @@ pPrt = &pAC->GIni.GP[Port]; - if (PollRxD) { - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_ENA_POL); - } - else { - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_DIS_POL); - } + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ? + CSR_ENA_POL : CSR_DIS_POL); } /* SkGePollRxD */ /****************************************************************************** * - * SkGePollTxD() - Enable/Disable Descriptor Polling of TxD Rings + * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings * * Description: * Enable or disable the descriptor polling the transmit descriptor - * ring(s) (RxD) of port 'port'. + * ring(s) (TxD) of port 'Port'. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * @@ -368,16 +448,12 @@ pPrt = &pAC->GIni.GP[Port]; - if (PollTxD) { - DWord = CSR_ENA_POL; - } - else { - DWord = CSR_DIS_POL; - } + DWord = (PollTxD) ? CSR_ENA_POL : CSR_DIS_POL; if (pPrt->PXSQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); } + if (pPrt->PXAQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); } @@ -397,7 +473,7 @@ * Returns: * nothing */ -void SkGeYellowLED( +void SkGeYellowLED( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int State) /* yellow LED state, 0 = OFF, 0 != ON */ @@ -430,7 +506,7 @@ * Returns: * nothing */ -void SkGeXmitLED( +void SkGeXmitLED( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Led, /* offset to the LED Init Value register */ @@ -475,9 +551,8 @@ * DoCalcAddr() - Calculates the start and the end address of a queue. * * Description: - * This function calculates the start- end the end address - * of a queue. Afterwards the 'StartVal' is incremented to the - * next start position. + * This function calculates the start and the end address of a queue. + * Afterwards the 'StartVal' is incremented to the next start position. * If the port is already initialized the calculated values * will be checked against the configured values and an * error will be returned, if they are not equal. @@ -498,7 +573,7 @@ { SK_U32 EndVal; SK_U32 NextStart; - int Rtv; + int Rtv; Rtv = 0; if (QuSize == 0) { @@ -521,9 +596,125 @@ } *StartVal = NextStart; - return (Rtv); + return(Rtv); } /* DoCalcAddr */ +/****************************************************************************** + * + * SkGeInitAssignRamToQueues() - allocate default queue sizes + * + * Description: + * This function assigns the memory to the different queues and ports. + * When DualNet is set to SK_TRUE all ports get the same amount of memory. + * Otherwise the first port gets most of the memory and all the + * other ports just the required minimum. + * This function can only be called when pAC->GIni.GIRamSize and + * pAC->GIni.GIMacsFound have been initialized, usually this happens + * at init level 1 + * + * Returns: + * 0 - ok + * 1 - invalid input values + * 2 - not enough memory + */ + +int SkGeInitAssignRamToQueues( +SK_AC *pAC, /* Adapter context */ +int ActivePort, /* Active Port in RLMT mode */ +SK_BOOL DualNet) /* adapter context */ +{ + int i; + int UsedKilobytes; /* memory already assigned */ + int ActivePortKilobytes; /* memory available for active port */ + SK_GEPORT *pGePort; + + UsedKilobytes = 0; + + if (ActivePort >= pAC->GIni.GIMacsFound) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", + ActivePort)); + return(1); + } + if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) + + ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", + pAC->GIni.GIRamSize)); + return(2); + } + + + if (DualNet) { + /* every port gets the same amount of memory */ + ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + pGePort = &pAC->GIni.GP[i]; + + /* take away the minimum memory for active queues */ + ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); + + /* receive queue gets the minimum + 80% of the rest */ + pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB(( + ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100)) + + SK_MIN_RXQ_SIZE; + + ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); + + /* synchronous transmit queue */ + pGePort->PXSQSize = 0; + + /* asynchronous transmit queue */ + pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes + + SK_MIN_TXQ_SIZE); + } + } + else { + /* Rlmt Mode or single link adapter */ + + /* Set standby queue size defaults for all standby ports */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + if (i != ActivePort) { + pGePort = &pAC->GIni.GP[i]; + + pGePort->PRxQSize = SK_MIN_RXQ_SIZE; + pGePort->PXAQSize = SK_MIN_TXQ_SIZE; + pGePort->PXSQSize = 0; + + /* Count used RAM */ + UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize; + } + } + /* what's left? */ + ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes; + + /* assign it to the active port */ + /* first take away the minimum memory */ + ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); + pGePort = &pAC->GIni.GP[ActivePort]; + + /* receive queue get's the minimum + 80% of the rest */ + pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes * + (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE; + + ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); + + /* synchronous transmit queue */ + pGePort->PXSQSize = 0; + + /* asynchronous transmit queue */ + pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) + + SK_MIN_TXQ_SIZE; + } +#ifdef VCPU + VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n", + pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize); +#endif /* VCPU */ + + return(0); +} /* SkGeInitAssignRamToQueues */ /****************************************************************************** * @@ -531,18 +722,20 @@ * * Description: * This function verifies the Queue Size Configuration specified - * in the variabels PRxQSize, PXSQSize, and PXAQSize of all + * in the variables PRxQSize, PXSQSize, and PXAQSize of all * used ports. * This requirements must be fullfilled to have a valid configuration: * - The size of all queues must not exceed GIRamSize. * - The queue sizes must be specified in units of 8 kB. - * - The size of rx queues of available ports must not be - * smaller than 16kB. + * - The size of Rx queues of available ports must not be + * smaller than 16 kB. + * - The size of at least one Tx queue (synch. or asynch.) + * of available ports must not be smaller than 16 kB + * when Jumbo Frames are used. * - The RAM start and end addresses must not be changed * for ports which are already initialized. - * Furthermore SkGeCheckQSize() defines the Start and End - * Addresses of all ports and stores them into the HWAC port - * structure. + * Furthermore SkGeCheckQSize() defines the Start and End Addresses + * of all ports and stores them into the HWAC port structure. * * Returns: * 0: Queue Size Configuration valid @@ -553,7 +746,7 @@ int Port) /* port index */ { SK_GEPORT *pPrt; - int UsedMem; + int UsedMem; /* total memory used (max. found ports) */ int i; int Rtv; int Rtv2; @@ -564,27 +757,37 @@ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; - if (( pPrt->PRxQSize & QZ_UNITS) || - (pPrt->PXSQSize & QZ_UNITS) || - (pPrt->PXAQSize & QZ_UNITS)) { + if ((pPrt->PRxQSize & QZ_UNITS) != 0 || + (pPrt->PXSQSize & QZ_UNITS) != 0 || + (pPrt->PXAQSize & QZ_UNITS) != 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); - Rtv = 1; - goto CheckQSizeEnd; + return(1); } - UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; - if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); - Rtv = 1; - goto CheckQSizeEnd; + return(1); } + + /* + * the size of at least one Tx queue (synch. or asynch.) has to be > 0. + * if Jumbo Frames are used, this size has to be >= 16 kB. + */ + if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || + (pAC->GIni.GIPortUsage == SK_JUMBO_LINK && + ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || + (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); + return(1); + } + + UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; } + if (UsedMem > pAC->GIni.GIRamSize) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); - Rtv = 1; - goto CheckQSizeEnd; + return(1); } /* Now start address calculation */ @@ -597,24 +800,23 @@ &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); Rtv |= Rtv2; - /* Calculate/Check values for the synchronous tx queue */ + /* Calculate/Check values for the synchronous Tx queue */ Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr, &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd); Rtv |= Rtv2; - /* Calculate/Check values for the asynchronous tx queue */ + /* Calculate/Check values for the asynchronous Tx queue */ Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr, &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd); Rtv |= Rtv2; if (Rtv) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG); - break; + return(1); } } -CheckQSizeEnd: - return (Rtv); + return(0); } /* SkGeCheckQSize */ @@ -625,10 +827,10 @@ * Description: * This function initializes the MAC Arbiter. * It must not be called if there is still an - * initilaized or active port. + * initialized or active port. * * Returns: - * nothing: + * nothing */ static void SkGeInitMacArb( SK_AC *pAC, /* adapter context */ @@ -652,7 +854,7 @@ /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */ /* - * There is not start or enable buttom to push, therefore + * There is not start or enable button to push, therefore * the MAC arbiter is configured and enabled now. */ } /* SkGeInitMacArb */ @@ -665,10 +867,10 @@ * Description: * This function initializes the Packet Arbiter. * It must not be called if there is still an - * initilaized or active port. + * initialized or active port. * * Returns: - * nothing: + * nothing */ static void SkGeInitPktArb( SK_AC *pAC, /* adapter context */ @@ -693,7 +895,7 @@ SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); } else { - SK_OUT16(IoC, B3_PA_CTRL,(PA_ENA_TO_TX1 | PA_ENA_TO_TX2)); + SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2); } } } /* SkGeInitPktArb */ @@ -714,6 +916,9 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { +#ifdef VCPU + SK_U32 DWord; +#endif /* VCPU */ /* * For each FIFO: * - release local reset @@ -721,19 +926,45 @@ * - setup defaults for the control register * - enable the FIFO */ - /* Configure RX MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); - SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); - SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); - - /* Configure TX MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); - SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); - - /* Enable frame flushing if jumbo frames used */ - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); + + if (pAC->GIni.GIGenesis) { + /* Configure Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); + + /* Configure Tx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); + SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); + + /* Enable frame flushing if jumbo frames used */ + if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); + } + } + else { + /* Configure Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); + SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), GMF_RX_CTRL_DEF | + GMF_RX_F_FL_ON); /* enable Rx GMAC FIFO Flush */ + + /* set Rx GMAC FIFO Flush Mask */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); + + /* use Rx GMAC FIFO Flush Threshold default value (0x0a == 56 bytes) */ + + /* Configure Tx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); + SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), GMF_TX_CTRL_DEF); + +#ifdef VCPU + SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); + SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord); +#endif /* VCPU */ + + /* set Tx GMAC FIFO Almost Empty Threshold */ +/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ } } /* SkGeInitMacFifo */ @@ -750,11 +981,11 @@ * * Note: * o To ensure receiving the Link Sync Event the LinkSyncCounter - * should be initialized BEFORE clearing the XMACs reset! + * should be initialized BEFORE clearing the XMAC's reset! * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this * function. * - * Retruns: + * Returns: * nothing */ void SkGeLoadLnkSyncCnt( @@ -784,13 +1015,13 @@ SK_IN32(IoC, B0_IMSK, &OrgIMsk); if (Port == MAC_1) { NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; - if (ISrc & IS_LNK_SYNC_M1) { + if ((ISrc & IS_LNK_SYNC_M1) != 0) { IrqPend = SK_TRUE; } } else { NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2; - if (ISrc & IS_LNK_SYNC_M2) { + if ((ISrc & IS_LNK_SYNC_M2) != 0) { IrqPend = SK_TRUE; } } @@ -829,14 +1060,14 @@ * TXA_ENA_FSYNC. This means if the size of * the synchronous queue is unequal zero but no specific * synchronous bandwidth is configured, the synchronous queue - * will always have the 'unlimitted' transmit priority! + * will always have the 'unlimited' transmit priority! * * This mode will be restored if the synchronous bandwidth is * deallocated ('IntTime' = 0 and 'LimCount' = 0). * * Returns: * 0: success - * 1: paramter configuration error + * 1: parameter configuration error * 2: try to configure quality of service although no * synchronous queue is configured */ @@ -855,59 +1086,59 @@ /* check the parameters */ if (LimCount > IntTime || (LimCount == 0 && IntTime != 0) || - (LimCount !=0 && IntTime == 0)) { + (LimCount != 0 && IntTime == 0)) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); - Rtv = 1; - goto CfgSyncEnd; + return(1); } - if (pAC->GIni.GP[Port].PXSQSize != 0) { - /* calculate register values */ - IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; - LimCount = LimCount / 8; - if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); - Rtv = 1; - goto CfgSyncEnd; - } - - /* - * - Enable 'Force Sync' to ensure the synchronous queue - * has the priority while configuring the new values. - * - Also 'disable alloc' to ensure the settings complies - * to the SyncMode parameter. - * - Disable 'Rate Control' to configure the new values. - * - write IntTime and Limcount - * - start 'Rate Control' and disable 'Force Sync' - * if Interval Timer or Limit Counter not zero. - */ - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), - TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); - SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); - SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), - (SyncMode & (TXA_ENA_ALLOC|TXA_DIS_ALLOC))); - if (IntTime != 0 || LimCount != 0) { - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), - TXA_DIS_FSYNC|TXA_START_RC); - } - } - else { + + if (pAC->GIni.GP[Port].PXSQSize == 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); - Rtv = 2; + return(2); + } + + /* calculate register values */ + IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; + LimCount = LimCount / 8; + + if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); + return(1); + } + + /* + * - Enable 'Force Sync' to ensure the synchronous queue + * has the priority while configuring the new values. + * - Also 'disable alloc' to ensure the settings complies + * to the SyncMode parameter. + * - Disable 'Rate Control' to configure the new values. + * - write IntTime and LimCount + * - start 'Rate Control' and disable 'Force Sync' + * if Interval Timer or Limit Counter not zero. + */ + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), + TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); + + SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); + SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); + + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), + (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC))); + + if (IntTime != 0 || LimCount != 0) { + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC); } -CfgSyncEnd: - return (Rtv); + return(0); } /* SkGeCfgSync */ /****************************************************************************** * - * DoInitRamQueue() - Initilaize the RAM Buffer Address of a single Queue + * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue * * Desccription: - * If the queue is used, enable and initilaize it. + * If the queue is used, enable and initialize it. * Make sure the queue is still reset, if it is not used. * * Returns: @@ -952,22 +1183,21 @@ /* write threshold for Rx Queue */ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); - SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_RX_LTPP), RxLoThresVal); + SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); /* the high priority threshold not used */ break; case SK_TX_RAM_Q: /* - * Do NOT use Store and forward under normal - * operation due to performance optimization. - * But if Jumbo frames are configured we NEED - * the store and forward of the RAM buffer. + * Do NOT use Store & Forward under normal operation due to + * performance optimization (GENESIS only). + * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB) + * or YUKON is used ((GMAC Tx FIFO is only 1 kB) + * we NEED Store & Forward of the RAM buffer. */ - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - /* - * enable Store & Forward Mode for the - * Tx Side - */ + if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || + !pAC->GIni.GIGenesis) { + /* enable Store & Forward Mode for the Tx Side */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); } break; @@ -980,7 +1210,7 @@ /* ensure the queue is still disabled */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET); } -} /* DoInitRamQueue*/ +} /* DoInitRamQueue */ /****************************************************************************** @@ -1012,10 +1242,13 @@ DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, pPrt->PRxQRamEnd, RxQType); + DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, pPrt->PXsQRamEnd, SK_TX_RAM_Q); + DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, pPrt->PXaQRamEnd, SK_TX_RAM_Q); + } /* SkGeInitRamBufs */ @@ -1024,7 +1257,7 @@ * SkGeInitRamIface() - Initialize the RAM Interface * * Description: - * This function initializes the Adapbers RAM Interface. + * This function initializes the Adapters RAM Interface. * * Note: * This function is used in the diagnostics. @@ -1052,6 +1285,7 @@ SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53); SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53); SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53); + } /* SkGeInitRamIface */ @@ -1070,25 +1304,37 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { - SK_GEPORT *pPrt; + SK_GEPORT *pPrt; + SK_U32 RxWm; + SK_U32 TxWm; pPrt = &pAC->GIni.GP[Port]; + RxWm = SK_BMU_RX_WM; + TxWm = SK_BMU_TX_WM; + + if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { + /* for better performance */ + RxWm /= 2; + TxWm /= 2; + } + /* Rx Queue: Release all local resets and set the watermark */ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), SK_BMU_RX_WM); + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); /* - * Tx Queue: Release all local resets if the queue is used! + * Tx Queue: Release all local resets if the queue is used ! * set watermark */ if (pPrt->PXSQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), SK_BMU_TX_WM); + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); } + if (pPrt->PXAQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), SK_BMU_TX_WM); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); } /* * Do NOT enable the descriptor poll timers here, because @@ -1107,7 +1353,7 @@ * that RX/TX stop is done and SV idle is NOT set. * In this case we have to issue another stop command. * - * Retruns: + * Returns: * The queues control status register */ static SK_U32 TestStopBit( @@ -1118,12 +1364,16 @@ SK_U32 QuCsr; /* CSR contents */ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); - if ((QuCsr & (CSR_STOP|CSR_SV_IDLE)) == 0) { + + if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { + /* Stop Descriptor overridden by start command */ SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); + SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); } - return (QuCsr); -} /* TestStopBit*/ + + return(QuCsr); +} /* TestStopBit */ /****************************************************************************** @@ -1131,31 +1381,31 @@ * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'. * * Description: - * After calling this function the descriptor rings and rx and tx + * After calling this function the descriptor rings and Rx and Tx * queues of this port may be reconfigured. * - * It is possible to stop the receive and transmit path seperate or + * It is possible to stop the receive and transmit path separate or * both together. * - * Dir = SK_STOP_TX Stops the transmit path only and resets - * the XMAC. The receive queue is still and - * the pending rx frames may still transfered + * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC. + * The receive queue is still active and + * the pending Rx frames may be still transferred * into the RxD. * SK_STOP_RX Stop the receive path. The tansmit path - * has to be stoped once before. + * has to be stopped once before. * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX * - * RstMode=SK_SOFT_RST Resets the XMAC. The PHY is still alive. - * SK_HARD_RST Resets the XMAC and the PHY. + * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive. + * SK_HARD_RST Resets the MAC and the PHY. * * Example: * 1) A Link Down event was signaled for a port. Therefore the activity - * of this port should be stoped and a hardware reset should be issued + * of this port should be stopped and a hardware reset should be issued * to enable the workaround of XMAC errata #2. But the received frames * should not be discarded. * ... * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); - * (transfer all pending rx frames) + * (transfer all pending Rx frames) * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST); * ... * @@ -1170,29 +1420,29 @@ * * Extended Description: * If SK_STOP_TX is set, - * o disable the XMACs receive and transmiter to prevent + * o disable the MAC's receive and transmitter to prevent * from sending incomplete frames * o stop the port's transmit queues before terminating the * BMUs to prevent from performing incomplete PCI cycles * on the PCI bus - * - The network rx and tx activity and PCI tx transfer is + * - The network Rx and Tx activity and PCI Tx transfer is * disabled now. - * o reset the XMAC depending on the RstMode + * o reset the MAC depending on the RstMode * o Stop Interval Timer and Limit Counter of Tx Arbiter, * also disable Force Sync bit and Enable Alloc bit. - * o perform a local reset of the port's tx path - * - reset the PCI FIFO of the async tx queue - * - reset the PCI FIFO of the sync tx queue - * - reset the RAM Buffer async tx queue - * - reset the RAM Butter sync tx queue + * o perform a local reset of the port's Tx path + * - reset the PCI FIFO of the async Tx queue + * - reset the PCI FIFO of the sync Tx queue + * - reset the RAM Buffer async Tx queue + * - reset the RAM Buffer sync Tx queue * - reset the MAC Tx FIFO * o switch Link and Tx LED off, stop the LED counters * * If SK_STOP_RX is set, * o stop the port's receive queue * - The path data transfer activity is fully stopped now. - * o perform a local reset of the port's rx path - * - reset the PCI FIFO of the rx queue + * o perform a local reset of the port's Rx path + * - reset the PCI FIFO of the Rx queue * - reset the RAM Buffer receive queue * - reset the MAC Rx FIFO * o switch Rx LED off, stop the LED counter @@ -1204,36 +1454,30 @@ * o This function may be called during the driver states RESET_PORT and * SWITCH_PORT. */ -void SkGeStopPort( +void SkGeStopPort( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ int Port, /* port to stop (MAC_1 + n) */ int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ { -#ifndef SK_DIAG +#ifndef SK_DIAG SK_EVPARA Para; -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ SK_GEPORT *pPrt; SK_U32 DWord; - SK_U16 Word; SK_U32 XsCsr; SK_U32 XaCsr; int i; - SK_BOOL AllPortsDis; SK_U64 ToutStart; int ToutCnt; pPrt = &pAC->GIni.GP[Port]; - if (Dir & SK_STOP_TX) { - /* disable the XMACs receiver and transmitter */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - - /* dummy read to ensure writing */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - + if ((Dir & SK_STOP_TX) != 0) { + /* disable receiver and transmitter */ + SkMacRxTxDisable(pAC, IoC, Port); + /* stop both transmit queues */ /* * If the BMU is in the reset state CSR_STOP will terminate @@ -1249,21 +1493,14 @@ * Clear packet arbiter timeout to make sure * this loop will terminate. */ - if (Port == MAC_1) { - Word = PA_CLR_TO_TX1; - } - else { - Word = PA_CLR_TO_TX2; - } - SK_OUT16(IoC, B3_PA_CTRL, Word); + SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_TX1 : + PA_CLR_TO_TX2); /* - * If the transfer stucks at the XMAC the STOP command will not - * terminate if we don't flush the XMAC's transmit FIFO! + * If the transfer stucks at the MAC the STOP command will not + * terminate if we don't flush the XMAC's transmit FIFO ! */ - XM_IN32(IoC, Port, XM_MODE, &DWord); - DWord |= XM_MD_FTF; - XM_OUT32(IoC, Port, XM_MODE, DWord); + SkMacFlushTxFifo(pAC, IoC, Port); XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); @@ -1274,40 +1511,32 @@ * This needs to be checked at 1/18 sec only. */ ToutCnt++; - switch (ToutCnt) { - case 1: - /* - * Cache Incoherency workaround: Assume a start command - * has been lost while sending the frame. - */ - ToutStart = SkOsGetTime(pAC); - if (XsCsr & CSR_STOP) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); - } - if (XaCsr & CSR_STOP) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); - } - break; - case 2: - default: + if (ToutCnt > 1) { /* Might be a problem when the driver event handler - * calls StopPort again. - * XXX. + * calls StopPort again. XXX. */ /* Fatal Error, Loop aborted */ - /* Create an Error Log Entry */ - SK_ERR_LOG( - pAC, - SK_ERRCL_HW, - SKERR_HWI_E018, + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018, SKERR_HWI_E018MSG); #ifndef SK_DIAG Para.Para64 = Port; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ return; } + /* + * Cache incoherency workaround: Assume a start command + * has been lost while sending the frame. + */ + ToutStart = SkOsGetTime(pAC); + + if ((XsCsr & CSR_STOP) != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); + } + if ((XaCsr & CSR_STOP) != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); + } } /* @@ -1315,46 +1544,51 @@ * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. */ } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE || - (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); + (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); - /* reset the XMAC depending on the RstMode */ + /* Reset the MAC depending on the RstMode */ if (RstMode == SK_SOFT_RST) { - SkXmSoftRst(pAC, IoC, Port); + SkMacSoftRst(pAC, IoC, Port); } else { - SkXmHardRst(pAC, IoC, Port); + SkMacHardRst(pAC, IoC, Port); } - - /* - * Stop Interval Timer and Limit Counter of Tx Arbiter, - * also disable Force Sync bit and Enable Alloc bit. - */ + + /* Disable Force Sync bit and Enable Alloc bit */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); - SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0x00000000L); - SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0x00000000L); + + /* Stop Interval Timer and Limit Counter of Tx Arbiter */ + SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L); + SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L); - /* - * perform a local reset of the port's tx path - * - reset the PCI FIFO of the async tx queue - * - reset the PCI FIFO of the sync tx queue - * - reset the RAM Buffer async tx queue - * - reset the RAM Butter sync tx queue - * - reset the MAC Tx FIFO - */ + /* Perform a local reset of the port's Tx path */ + + /* Reset the PCI FIFO of the async Tx queue */ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); + /* Reset the PCI FIFO of the sync Tx queue */ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); + /* Reset the RAM Buffer async Tx queue */ SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET); + /* Reset the RAM Buffer sync Tx queue */ SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); - /* Note: MFF_RST_SET does NOT reset the XMAC! */ - SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET); - - /* switch Link and Tx LED off, stop the LED counters */ - /* Link LED is switched off by the RLMT and the Diag itself */ - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); + + /* Reset Tx MAC FIFO */ + if (pAC->GIni.GIGenesis) { + /* Note: MFF_RST_SET does NOT reset the XMAC ! */ + SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET); + + /* switch Link and Tx LED off, stop the LED counters */ + /* Link LED is switched off by the RLMT and the Diag itself */ + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); + } + else { + /* Reset TX MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); + } } - if (Dir & SK_STOP_RX) { + if ((Dir & SK_STOP_RX) != 0) { /* * The RX Stop Command will not terminate if no buffers * are queued in the RxD ring. But it will always reach @@ -1363,64 +1597,52 @@ */ /* stop the port's receive queue */ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP); + i = 100; do { /* * Clear packet arbiter timeout to make sure * this loop will terminate */ - if (Port == MAC_1) { - Word = PA_CLR_TO_RX1; - } - else { - Word = PA_CLR_TO_RX2; - } - SK_OUT16(IoC, B3_PA_CTRL, Word); - + SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_RX1 : + PA_CLR_TO_RX2); + DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); - if (i != 0) { - i--; - } - /* finish if CSR_STOP is done or CSR_SV_IDLE is true and i==0 */ + /* timeout if i==0 (bug fix for #10748) */ + if (--i == 0) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, + SKERR_HWI_E024MSG); + break; + } /* * because of the ASIC problem report entry from 21.08.98 * it is required to wait until CSR_STOP is reset and * CSR_SV_IDLE is set. */ - } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE && - ((DWord & CSR_SV_IDLE) == 0 || i != 0)); + } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); - /* The path data transfer activity is fully stopped now. */ + /* The path data transfer activity is fully stopped now */ - /* - * perform a local reset of the port's rx path - * - reset the PCI FIFO of the rx queue - * - reset the RAM Buffer receive queue - * - reset the MAC Rx FIFO - */ + /* Perform a local reset of the port's Rx path */ + + /* Reset the PCI FIFO of the Rx queue */ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); + /* Reset the RAM Buffer receive queue */ SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); - SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); - - /* switch Rx LED off, stop the LED counter */ - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); - - } - /* - * If all ports are stopped reset the RAM Interface. - */ - for (i = 0, AllPortsDis = SK_TRUE; i < pAC->GIni.GIMacsFound; i++) { - if (pAC->GIni.GP[i].PState != SK_PRT_RESET && - pAC->GIni.GP[i].PState != SK_PRT_STOP) { + /* Reset Rx MAC FIFO */ + if (pAC->GIni.GIGenesis) { + + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); - AllPortsDis = SK_FALSE; - break; + /* switch Rx LED off, stop the LED counter */ + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); + } + else { + /* Reset Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); } - } - if (AllPortsDis) { - pAC->GIni.GIAnyPortAct = SK_FALSE; } } /* SkGeStopPort */ @@ -1444,12 +1666,12 @@ for (i = 0; i < SK_MAX_MACS; i++) { pPrt = &pAC->GIni.GP[i]; + pPrt->PState = SK_PRT_RESET; pPrt->PRxQOff = QOffTab[i].RxQOff; pPrt->PXsQOff = QOffTab[i].XsQOff; pPrt->PXaQOff = QOffTab[i].XaQOff; pPrt->PCheckPar = SK_FALSE; - pPrt->PRxCmd = XM_RX_STRIP_FCS | XM_RX_LENERR_OK; pPrt->PIsave = 0; pPrt->PPrevShorts = 0; pPrt->PLinkResCt = 0; @@ -1458,6 +1680,9 @@ pPrt->PPrevFcs = 0; pPrt->PRxLim = SK_DEF_RX_WA_LIM; pPrt->PLinkMode = SK_LMODE_AUTOFULL; + pPrt->PLinkSpeedCap = SK_LSPEED_CAP_1000MBPS; + pPrt->PLinkSpeed = SK_LSPEED_1000MBPS; + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_UNKNOWN; pPrt->PLinkModeConf = SK_LMODE_AUTOSENSE; pPrt->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; pPrt->PLinkBroken = SK_TRUE; /* See WA code */ @@ -1466,8 +1691,7 @@ pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; pPrt->PFlowCtrlCap = SK_FLOW_MODE_SYM_OR_REM; pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - pPrt->PMSCap = (SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | - SK_MS_CAP_SLAVE); + pPrt->PMSCap = 0; pPrt->PMSMode = SK_MS_MODE_AUTO; pPrt->PMSStatus = SK_MS_STAT_UNSET; pPrt->PAutoNegFail = SK_FALSE; @@ -1476,7 +1700,7 @@ } pAC->GIni.GIPortUsage = SK_RED_LINK; - pAC->GIni.GIAnyPortAct = SK_FALSE; + } /* SkGeInit0*/ #ifdef SK_PCI_RESET @@ -1520,42 +1744,39 @@ /* We know the RAM Interface Arbiter is enabled. */ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - if ((PmCtlSts & PCI_PM_STATE) != PCI_PM_STATE_D3) { - return (1); + + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { + return(1); } - /* - * Return to D0 state. - */ + /* Return to D0 state. */ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0); /* Check for D0 state. */ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - if ((PmCtlSts & PCI_PM_STATE) != PCI_PM_STATE_D0) { - return (1); + + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { + return(1); } - /* - * Check PCI Config Registers. - */ + /* Check PCI Config Registers. */ SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); - SkPciReadCfgByte(pAC, PCI_LAT_TIM, &lat); + SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); + if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 || - Lat != 0 ) { - return (0); + Lat != 0) { + return(1); } - /* - * Restore Config Space. - */ + /* Restore PCI Config Space. */ for (i = 0; i < PCI_CFG_SIZE; i++) { SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]); } - return (0); + return(0); } /* SkGePciReset */ #endif /* SK_PCI_RESET */ @@ -1572,13 +1793,14 @@ * o Get the hardware configuration * + Read the number of MACs/Ports. * + Read the RAM size. - * + Read the PCI Revision ID. + * + Read the PCI Revision Id. * + Find out the adapters host clock speed * + Read and check the PHY type * * Returns: * 0: success * 5: Unexpected PHY type detected + * 6: HW self test failed */ static int SkGeInit1( SK_AC *pAC, /* adapter context */ @@ -1595,56 +1817,113 @@ (void)SkGePciReset(pAC, IoC); #endif /* SK_PCI_RESET */ - /* Do the reset */ + /* Do the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); - /* Release the reset */ + /* Release the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_CLR); /* Reset all error bits in the PCI STATUS register */ /* - * Note: Cfg cycles cannot be used, because they are not + * Note: PCI Cfg cycles cannot be used, because they are not * available on some platforms after 'boot time'. */ - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - /* Release Master_Reset */ + /* Release Master Reset */ SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); + /* Read Chip Identification Number */ + SK_IN8(IoC, B2_CHIP_ID, &Byte); + pAC->GIni.GIChipId = Byte; + /* Read number of MACs */ SK_IN8(IoC, B2_MAC_CFG, &Byte); - if (Byte & CFG_SNG_MAC) { - pAC->GIni.GIMacsFound = 1; - } - else { - pAC->GIni.GIMacsFound = 2; - } - SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); - pAC->GIni.GIPciHwRev = (int) Byte; + pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; + + /* Get Chip Revision Number */ + pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4); - /* Read the adapters RAM size */ + /* Read the adapters external SRAM size */ SK_IN8(IoC, B2_E_0, &Byte); - if (Byte == 3) { - pAC->GIni.GIRamSize = (int)(Byte-1) * 512; - pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + + pAC->GIni.GIGenesis = SK_TRUE; + + if (Byte == 3) { + /* special case: 4 x 64k x 36, offset = 0x80000 */ + pAC->GIni.GIRamSize = 1024; + pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; + } + else { + pAC->GIni.GIRamSize = (int)Byte * 512; + pAC->GIni.GIRamOffs = 0; + } } else { - pAC->GIni.GIRamSize = (int)Byte * 512; + + pAC->GIni.GIGenesis = SK_FALSE; + +#ifndef VCPU + pAC->GIni.GIRamSize = (Byte == 0) ? 128 : (int)Byte * 4; +#else + pAC->GIni.GIRamSize = 128; +#endif pAC->GIni.GIRamOffs = 0; + + pAC->GIni.GIWolOffs = (pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; + + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + /* set GMAC Link Control reset */ + SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); + + /* clear GMAC Link Control reset */ + SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + } } - /* All known GE Adapters works with 53.125 MHz host clock */ + /* get diff. PCI parameters */ + SK_IN16(IoC, B0_CTST, &Word); + + /* Check if 64-bit PCI Slot is present */ + pAC->GIni.GIPciSlot64 = (SK_BOOL)((Word & CS_BUS_SLOT_SZ) != 0); + + /* Check if 66 MHz PCI Clock is active */ + pAC->GIni.GIPciClock66 = (SK_BOOL)((Word & CS_BUS_CLOCK) != 0); + + /* Check if VAUX is available */ + pAC->GIni.GIVauxAvail = (SK_BOOL)((Word & CS_VAUX_AVAIL) != 0); + + /* Read PCI HW Revision Id. */ + SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); + pAC->GIni.GIPciHwRev = Byte; + + /* All known GE Adapters work with 53.125 MHz host clock */ pAC->GIni.GIHstClkFact = SK_FACT_53; pAC->GIni.GIPollTimerVal = SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; + /* Read the PMD type */ + SK_IN8(IoC, B2_PMD_TYP, &Byte); + pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); + /* Read the PHY type */ SK_IN8(IoC, B2_E_1, &Byte); + +#ifdef VCPU + if (!pAC->GIni.GIGenesis) { + pAC->GIni.GICopperType = SK_TRUE; + Byte = SK_PHY_MARV_COPPER; /* this field is not initialized */ + } +#endif + Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ - for (i=0; iGIni.GIMacsFound; i++) { + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pAC->GIni.GP[i].PhyType = Byte; switch (Byte) { case SK_PHY_XMAC: @@ -1652,25 +1931,71 @@ break; case SK_PHY_BCOM: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; + pAC->GIni.GP[i].PMSCap = + SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE; break; + case SK_PHY_MARV_COPPER: + pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; + if (pAC->GIni.GICopperType) { + pAC->GIni.GP[i].PLinkSpeedCap = SK_LSPEED_CAP_AUTO | + SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | + SK_LSPEED_CAP_1000MBPS; + pAC->GIni.GP[i].PLinkSpeed = SK_LSPEED_AUTO; + pAC->GIni.GP[i].PMSCap = + SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE; + } + else { + pAC->GIni.GP[i].PhyType = SK_PHY_MARV_FIBER; + } + break; +#ifdef OTHER_PHY case SK_PHY_LONE: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; break; case SK_PHY_NAT: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; break; +#endif /* OTHER_PHY */ default: - /* ERROR: unexpected PHY typ detected */ + /* ERROR: unexpected PHY type detected */ RetVal = 5; break; } + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("PHY type: %d PHY addr: %04x\n", pAC->GIni.GP[i].PhyType, + pAC->GIni.GP[i].PhyAddr)); } - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("PHY type: %d PHY addr: %x\n", pAC->GIni.GP[i].PhyType, - pAC->GIni.GP[i].PhyAddr)); + + /* Get Mac Type & set function pointers dependent on */ + if (pAC->GIni.GIGenesis) { + pAC->GIni.GIMacType = SK_MAC_XMAC; + + pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; + pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; + pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; + pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; + } + else { + pAC->GIni.GIMacType = SK_MAC_GMAC; - return (RetVal); -} /* SkGeInit1*/ + pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; + pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; + pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; + pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; + +#ifndef VCPU + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + /* check HW self test result */ + SK_IN8(IoC, B2_E_3, &Byte); + if ((Byte & B2_E3_RES_MASK) != 0) { + RetVal = 6; + } + } +#endif + } + return(RetVal); +} /* SkGeInit1 */ /****************************************************************************** @@ -1692,64 +2017,48 @@ SK_AC *pAC, /* adapter context */ SK_IOC IoC) /* IO context */ { - SK_GEPORT *pPrt; SK_U32 DWord; - int i; - - /* start the Blink Source Counter */ - DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; - SK_OUT32(IoC, B2_BSC_INI, DWord); - SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); + int i; /* start the Descriptor Poll Timer */ if (pAC->GIni.GIPollTimerVal != 0) { if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) { pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; - /* Create an Error Log Entry */ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG); } SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal); SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); } - /* - * Configure - * - the MAC-Arbiter and - * - the Paket Arbiter - * - * The MAC and the packet arbiter will be started once - * and never be stopped. - */ - SkGeInitMacArb(pAC, IoC); - SkGeInitPktArb(pAC, IoC); + if (pAC->GIni.GIGenesis) { + /* start the Blink Source Counter */ + DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; + + SK_OUT32(IoC, B2_BSC_INI, DWord); + SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); + + /* + * Configure the MAC Arbiter and the Packet Arbiter. + * They will be started once and never be stopped. + */ + SkGeInitMacArb(pAC, IoC); + + SkGeInitPktArb(pAC, IoC); + } + else { + /* Start Time Stamp Timer */ + SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); + } /* enable the Tx Arbiters */ - SK_OUT8(IoC, MR_ADDR(MAC_1, TXA_CTRL), TXA_ENA_ARB); - if (pAC->GIni.GIMacsFound > 1) { - SK_OUT8(IoC, MR_ADDR(MAC_2, TXA_CTRL), TXA_ENA_ARB); + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB); } /* enable the RAM Interface Arbiter */ SkGeInitRamIface(pAC, IoC); - for (i = 0; i < SK_MAX_MACS; i++) { - pPrt = &pAC->GIni.GP[i]; - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - pPrt->PRxCmd |= XM_RX_BIG_PK_OK; - } - - if (pPrt->PLinkModeConf == SK_LMODE_HALF) { - /* - * If in manual half duplex mode - * the other side might be in full duplex mode - * so ignore if a carrier extension is not seen on - * frames received - */ - pPrt->PRxCmd |= XM_RX_DIS_CEXT; - } - - } } /* SkGeInit2 */ /****************************************************************************** @@ -1758,9 +2067,8 @@ * * Description: * Level 0: Initialize the Module structures. - * Level 1: Generic Hardware Initialization. The - * IOP/MemBase pointer has to be set before - * calling this level. + * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has + * to be set before calling this level. * * o Do a software reset. * o Clear all reset bits. @@ -1780,18 +2088,19 @@ * * Returns: * 0: success - * 1: Number of MACs exceeds SK_MAX_MACS ( after level 1) - * 2: Adapter not present or not accessable + * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) + * 2: Adapter not present or not accessible * 3: Illegal initialization level * 4: Initialization Level 1 Call missing * 5: Unexpected PHY type detected + * 6: HW self test failed */ int SkGeInit( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Level) /* initialization level */ { - int RetVal; /* return value */ + int RetVal; /* return value */ SK_U32 DWord; RetVal = 0; @@ -1804,14 +2113,19 @@ SkGeInit0(pAC, IoC); pAC->GIni.GILevel = SK_INIT_DATA; break; + case SK_INIT_IO: /* Initialization Level 1 */ RetVal = SkGeInit1(pAC, IoC); + if (RetVal != 0) { + break; + } - /* Check if the adapter seems to be accessable */ + /* Check if the adapter seems to be accessible */ SK_OUT32(IoC, B2_IRQM_INI, 0x11335577L); SK_IN32(IoC, B2_IRQM_INI, &DWord); - SK_OUT32(IoC, B2_IRQM_INI, 0x00000000L); + SK_OUT32(IoC, B2_IRQM_INI, 0L); + if (DWord != 0x11335577L) { RetVal = 2; break; @@ -1826,12 +2140,13 @@ /* Level 1 successfully passed */ pAC->GIni.GILevel = SK_INIT_IO; break; + case SK_INIT_RUN: /* Initialization Level 2 */ if (pAC->GIni.GILevel != SK_INIT_IO) { -#ifndef SK_DIAG +#ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG); -#endif +#endif /* !SK_DIAG */ RetVal = 4; break; } @@ -1840,15 +2155,15 @@ /* Level 2 successfully passed */ pAC->GIni.GILevel = SK_INIT_RUN; break; + default: - /* Create an Error Log Entry */ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); RetVal = 3; break; } - return (RetVal); -} /* SkGeInit*/ + return(RetVal); +} /* SkGeInit */ /****************************************************************************** @@ -1862,15 +2177,17 @@ * Returns: * nothing */ -void SkGeDeInit( +void SkGeDeInit( SK_AC *pAC, /* adapter context */ SK_IOC IoC) /* IO context */ { int i; SK_U16 Word; - /* Ensure I2C is ready. */ +#ifndef VCPU + /* Ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); +#endif /* Stop all current transfer activity */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { @@ -1883,39 +2200,39 @@ /* Reset all bits in the PCI STATUS register */ /* - * Note: Cfg cycles cannot be used, because they are not + * Note: PCI Cfg cycles cannot be used, because they are not * available on some platforms after 'boot time'. */ - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); /* Do the reset, all LEDs are switched off now */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); -} /* SkGeDeInit*/ +} /* SkGeDeInit */ /****************************************************************************** * - * SkGeInitPort() Initialize the specified prot. + * SkGeInitPort() Initialize the specified port. * * Description: * PRxQSize, PXSQSize, and PXAQSize has to be - * configured for the specified port before calling this - * function. The descriptor rings has to be initialized, too. + * configured for the specified port before calling this function. + * The descriptor rings has to be initialized too. * * o (Re)configure queues of the specified port. - * o configure the XMAC of the specified port. - * o put ASIC and XMAC(s) in operational mode. + * o configure the MAC of the specified port. + * o put ASIC and MAC(s) in operational mode. * o initialize Rx/Tx and Sync LED * o initialize RAM Buffers and MAC FIFOs * * The port is ready to connect when returning. * * Note: - * The XMACs Rx and Tx state machine is still disabled when - * returning. + * The MAC's Rx and Tx state machine is still disabled when returning. * * Returns: * 0: success @@ -1936,45 +2253,48 @@ if (SkGeCheckQSize(pAC, Port) != 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); - return (1); + return(1); } + if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); - return (2); + return(2); } /* Configuration ok, initialize the Port now */ - /* Initialize Rx, Tx and Link LED */ - /* - * If 1000BT Phy needs LED initialization than swap - * LED and XMAC initialization order - */ - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); - /* The Link LED is initialized by RLMT or Diagnostics itself */ + if (pAC->GIni.GIGenesis) { + /* Initialize Rx, Tx and Link LED */ + /* + * If 1000BT Phy needs LED initialization than swap + * LED and XMAC initialization order + */ + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); + /* The Link LED is initialized by RLMT or Diagnostics itself */ + + SkXmInitMac(pAC, IoC, Port); + } + else { + SkGmInitMac(pAC, IoC, Port); + } + /* Do NOT initialize the Link Sync Counter */ - /* - * Configure - * - XMAC - * - MAC FIFOs - * - RAM Buffers - * - enable Force Sync bit if synchronous queue available - * - BMUs - */ - SkXmInitMac(pAC, IoC, Port); SkGeInitMacFifo(pAC, IoC, Port); + SkGeInitRamBufs(pAC, IoC, Port); + if (pPrt->PXSQSize != 0) { + /* enable Force Sync bit if synchronous queue available */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); } + SkGeInitBmu(pAC, IoC, Port); - /* Mark port as initialized. */ + /* Mark port as initialized */ pPrt->PState = SK_PRT_INIT; - pAC->GIni.GIAnyPortAct = SK_TRUE; - return (0); + return(0); } /* SkGeInitPort */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skgemib.c linux.21pre4-ac6/drivers/net/sk98lin/skgemib.c --- linux.21pre4/drivers/net/sk98lin/skgemib.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/net/sk98lin/skgemib.c 2003-01-06 15:38:18.000000000 +0000 @@ -0,0 +1,1056 @@ +/***************************************************************************** + * + * Name: skgemib.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.7 $ + * Date: $Date: 2002/12/16 09:04:34 $ + * Purpose: Private Network Management Interface Management Database + * + ****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 2002 SysKonnect GmbH. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +/***************************************************************************** + * + * History: + * + * $Log: skgemib.c,v $ + * Revision 1.7 2002/12/16 09:04:34 tschilli + * Code for VCT handling added. + * + * Revision 1.6 2002/08/09 15:40:21 rwahl + * Editorial change (renamed ConfSpeedCap). + * + * Revision 1.5 2002/08/09 11:05:34 rwahl + * Added oid handling for link speed cap. + * + * Revision 1.4 2002/08/09 09:40:27 rwahl + * Added support for NDIS OID_PNP_xxx. + * + * Revision 1.3 2002/07/17 19:39:54 rwahl + * Added handler for OID_SKGE_SPEED_MODE & OID_SKGE_SPEED_STATUS. + * + * Revision 1.2 2002/05/22 08:59:00 rwahl + * - static functions only for release build. + * - Source file must be included. + * + * Revision 1.1 2002/05/22 08:12:42 rwahl + * Initial version. + * + ****************************************************************************/ + +/* + * PRIVATE OID handler function prototypes + */ +PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action, + SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action, + SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int* pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); + +#ifdef SK_POWER_MGMT +PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +#endif + + + +/* defines *******************************************************************/ +#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0])) + + +/* global variables **********************************************************/ + +/* + * Table to correlate OID with handler function and index to + * hardware register stored in StatAddress if applicable. + */ +PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { + {OID_GEN_XMIT_OK, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX}, + {OID_GEN_RCV_OK, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX}, + {OID_GEN_XMIT_ERROR, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_GEN_RCV_ERROR, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_GEN_RCV_NO_BUFFER, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_GEN_DIRECTED_FRAMES_XMIT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST}, + {OID_GEN_MULTICAST_FRAMES_XMIT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST}, + {OID_GEN_BROADCAST_FRAMES_XMIT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST}, + {OID_GEN_DIRECTED_FRAMES_RCV, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST}, + {OID_GEN_MULTICAST_FRAMES_RCV, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST}, + {OID_GEN_BROADCAST_FRAMES_RCV, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST}, + {OID_GEN_RCV_CRC_ERROR, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS}, + {OID_GEN_TRANSMIT_QUEUE_LENGTH, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_802_3_PERMANENT_ADDRESS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, 0}, + {OID_802_3_CURRENT_ADDRESS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, 0}, + {OID_802_3_RCV_ERROR_ALIGNMENT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING}, + {OID_802_3_XMIT_ONE_COLLISION, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL}, + {OID_802_3_XMIT_MORE_COLLISIONS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL}, + {OID_802_3_XMIT_DEFERRED, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL}, + {OID_802_3_XMIT_MAX_COLLISIONS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL}, + {OID_802_3_RCV_OVERRUN, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW}, + {OID_802_3_XMIT_UNDERRUN, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN}, + {OID_802_3_XMIT_TIMES_CRS_LOST, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER}, + {OID_802_3_XMIT_LATE_COLLISIONS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL}, +#ifdef SK_POWER_MGMT + {OID_PNP_CAPABILITIES, + 0, + 0, + 0, + SK_PNMI_RO, PowerManagement, 0}, + {OID_PNP_SET_POWER, + 0, + 0, + 0, + SK_PNMI_WO, PowerManagement, 0}, + {OID_PNP_QUERY_POWER, + 0, + 0, + 0, + SK_PNMI_RO, PowerManagement, 0}, + {OID_PNP_ADD_WAKE_UP_PATTERN, + 0, + 0, + 0, + SK_PNMI_WO, PowerManagement, 0}, + {OID_PNP_REMOVE_WAKE_UP_PATTERN, + 0, + 0, + 0, + SK_PNMI_WO, PowerManagement, 0}, + {OID_PNP_ENABLE_WAKE_UP, + 0, + 0, + 0, + SK_PNMI_RW, PowerManagement, 0}, +#endif /* SK_POWER_MGMT */ + {OID_SKGE_MDB_VERSION, + 1, + 0, + SK_PNMI_MAI_OFF(MgmtDBVersion), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SUPPORTED_LIST, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_SKGE_ALL_DATA, + 0, + 0, + 0, + SK_PNMI_RW, OidStruct, 0}, + {OID_SKGE_VPD_FREE_BYTES, + 1, + 0, + SK_PNMI_MAI_OFF(VpdFreeBytes), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ENTRIES_LIST, + 1, + 0, + SK_PNMI_MAI_OFF(VpdEntriesList), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ENTRIES_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(VpdEntriesNumber), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_KEY, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_VALUE, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ACCESS, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ACTION, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction), + SK_PNMI_RW, Vpd, 0}, + {OID_SKGE_PORT_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(PortNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DEVICE_TYPE, + 1, + 0, + SK_PNMI_MAI_OFF(DeviceType), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_DESCR, + 1, + 0, + SK_PNMI_MAI_OFF(DriverDescr), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_VERSION, + 1, + 0, + SK_PNMI_MAI_OFF(DriverVersion), + SK_PNMI_RO, General, 0}, + {OID_SKGE_HW_DESCR, + 1, + 0, + SK_PNMI_MAI_OFF(HwDescr), + SK_PNMI_RO, General, 0}, + {OID_SKGE_HW_VERSION, + 1, + 0, + SK_PNMI_MAI_OFF(HwVersion), + SK_PNMI_RO, General, 0}, + {OID_SKGE_CHIPSET, + 1, + 0, + SK_PNMI_MAI_OFF(Chipset), + SK_PNMI_RO, General, 0}, + {OID_SKGE_ACTION, + 1, + 0, + SK_PNMI_MAI_OFF(Action), + SK_PNMI_RW, Perform, 0}, + {OID_SKGE_RESULT, + 1, + 0, + SK_PNMI_MAI_OFF(TestResult), + SK_PNMI_RO, General, 0}, + {OID_SKGE_BUS_TYPE, + 1, + 0, + SK_PNMI_MAI_OFF(BusType), + SK_PNMI_RO, General, 0}, + {OID_SKGE_BUS_SPEED, + 1, + 0, + SK_PNMI_MAI_OFF(BusSpeed), + SK_PNMI_RO, General, 0}, + {OID_SKGE_BUS_WIDTH, + 1, + 0, + SK_PNMI_MAI_OFF(BusWidth), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_SW_QUEUE_LEN, + 1, + 0, + SK_PNMI_MAI_OFF(TxSwQueueLen), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_SW_QUEUE_MAX, + 1, + 0, + SK_PNMI_MAI_OFF(TxSwQueueMax), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_RETRY, + 1, + 0, + SK_PNMI_MAI_OFF(TxRetryCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_INTR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxIntrCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_INTR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(TxIntrCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_NO_BUF_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxNoBufCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_NO_BUF_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(TxNoBufCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_USED_DESCR_NO, + 1, + 0, + SK_PNMI_MAI_OFF(TxUsedDescrNo), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_DELIVERED_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxDeliveredCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_OCTETS_DELIV_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxOctetsDeliveredCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_HW_ERROR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxHwErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_HW_ERROR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(TxHwErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_IN_ERRORS_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(InErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_OUT_ERROR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(OutErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_ERR_RECOVERY_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(ErrRecoveryCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SYSUPTIME, + 1, + 0, + SK_PNMI_MAI_OFF(SysUpTime), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SENSOR_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(SensorNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SENSOR_INDEX, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_DESCR, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_TYPE, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_VALUE, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_THRES_LOW, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_THRES_UPP, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_THRES_LOW, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_THRES_UPP, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_STATUS, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_CTS, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_CTS, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_TIME, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_TIME, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_CHKSM_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(ChecksumNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_CHKSM_RX_OK_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_RX_UNABLE_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_RX_ERR_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_TX_OK_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_TX_UNABLE_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_STAT_TX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX}, + {OID_SKGE_STAT_TX_OCTETS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET}, + {OID_SKGE_STAT_TX_BROADCAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST}, + {OID_SKGE_STAT_TX_MULTICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST}, + {OID_SKGE_STAT_TX_UNICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST}, + {OID_SKGE_STAT_TX_LONGFRAMES, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES}, + {OID_SKGE_STAT_TX_BURST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST}, + {OID_SKGE_STAT_TX_PFLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC}, + {OID_SKGE_STAT_TX_FLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC}, + {OID_SKGE_STAT_TX_SINGLE_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL}, + {OID_SKGE_STAT_TX_MULTI_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL}, + {OID_SKGE_STAT_TX_EXCESS_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL}, + {OID_SKGE_STAT_TX_LATE_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL}, + {OID_SKGE_STAT_TX_DEFFERAL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL}, + {OID_SKGE_STAT_TX_EXCESS_DEF, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF}, + {OID_SKGE_STAT_TX_UNDERRUN, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN}, + {OID_SKGE_STAT_TX_CARRIER, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER}, +/* {OID_SKGE_STAT_TX_UTIL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization), + SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ + {OID_SKGE_STAT_TX_64, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64}, + {OID_SKGE_STAT_TX_127, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127}, + {OID_SKGE_STAT_TX_255, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255}, + {OID_SKGE_STAT_TX_511, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511}, + {OID_SKGE_STAT_TX_1023, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023}, + {OID_SKGE_STAT_TX_MAX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX}, + {OID_SKGE_STAT_TX_SYNC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC}, + {OID_SKGE_STAT_TX_SYNC_OCTETS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET}, + {OID_SKGE_STAT_RX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX}, + {OID_SKGE_STAT_RX_OCTETS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET}, + {OID_SKGE_STAT_RX_BROADCAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST}, + {OID_SKGE_STAT_RX_MULTICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST}, + {OID_SKGE_STAT_RX_UNICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST}, + {OID_SKGE_STAT_RX_LONGFRAMES, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES}, + {OID_SKGE_STAT_RX_PFLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC}, + {OID_SKGE_STAT_RX_FLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC}, + {OID_SKGE_STAT_RX_PFLOWC_ERR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR}, + {OID_SKGE_STAT_RX_FLOWC_UNKWN, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN}, + {OID_SKGE_STAT_RX_BURST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST}, + {OID_SKGE_STAT_RX_MISSED, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED}, + {OID_SKGE_STAT_RX_FRAMING, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING}, + {OID_SKGE_STAT_RX_OVERFLOW, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW}, + {OID_SKGE_STAT_RX_JABBER, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER}, + {OID_SKGE_STAT_RX_CARRIER, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER}, + {OID_SKGE_STAT_RX_IR_LENGTH, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH}, + {OID_SKGE_STAT_RX_SYMBOL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL}, + {OID_SKGE_STAT_RX_SHORTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS}, + {OID_SKGE_STAT_RX_RUNT, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT}, + {OID_SKGE_STAT_RX_CEXT, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT}, + {OID_SKGE_STAT_RX_TOO_LONG, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG}, + {OID_SKGE_STAT_RX_FCS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS}, +/* {OID_SKGE_STAT_RX_UTIL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization), + SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ + {OID_SKGE_STAT_RX_64, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64}, + {OID_SKGE_STAT_RX_127, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127}, + {OID_SKGE_STAT_RX_255, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255}, + {OID_SKGE_STAT_RX_511, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511}, + {OID_SKGE_STAT_RX_1023, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023}, + {OID_SKGE_STAT_RX_MAX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX}, + {OID_SKGE_PHYS_CUR_ADDR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr), + SK_PNMI_RW, Addr, 0}, + {OID_SKGE_PHYS_FAC_ADDR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr), + SK_PNMI_RO, Addr, 0}, + {OID_SKGE_PMD, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_CONNECTOR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_LINK_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_LINK_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_LINK_MODE_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_LINK_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_FLOWCTRL_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_FLOWCTRL_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_FLOWCTRL_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_OPERATION_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_OPERATION_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_PHY_OPERATION_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_SPEED_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_SPEED_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_SPEED_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_TRAP, + 1, + 0, + SK_PNMI_MAI_OFF(Trap), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TRAP_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(TrapNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RLMT_MODE, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtMode), + SK_PNMI_RW, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtPortNumber), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_ACTIVE, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtPortActive), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_PREFERRED, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtPortPreferred), + SK_PNMI_RW, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeCts), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_TIME, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeTime), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_ESTIM, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeEstimate), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_THRES, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeThreshold), + SK_PNMI_RW, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_INDEX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_TX_HELLO_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_RX_HELLO_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_TX_SP_REQ_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_RX_SP_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_MONITOR_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtMonitorNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RLMT_MONITOR_INDEX, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_ADDR, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_ERRS, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_TIMESTAMP, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_ADMIN, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin), + SK_PNMI_RW, Monitor, 0}, + {OID_SKGE_MTU, + 1, + 0, + SK_PNMI_MAI_OFF(MtuSize), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_VCT_GET, + 0, + 0, + 0, + SK_PNMI_RO, Vct, 0}, + {OID_SKGE_VCT_SET, + 0, + 0, + 0, + SK_PNMI_WO, Vct, 0}, + {OID_SKGE_VCT_STATUS, + 0, + 0, + 0, + SK_PNMI_RO, Vct, 0}, +}; + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skgepnmi.c linux.21pre4-ac6/drivers/net/sk98lin/skgepnmi.c --- linux.21pre4/drivers/net/sk98lin/skgepnmi.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skgepnmi.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skgepnmi.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.87 $ - * Date: $Date: 2001/04/06 13:35:09 $ + * Version: $Revision: 1.102 $ + * Date: $Date: 2002/12/16 14:03:24 $ * Purpose: Private Network Management Interface * ****************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,78 @@ * History: * * $Log: skgepnmi.c,v $ + * Revision 1.102 2002/12/16 14:03:24 tschilli + * VCT code in Vct() changed. + * + * Revision 1.101 2002/12/16 09:04:10 tschilli + * Code for VCT handling added. + * + * Revision 1.100 2002/09/26 14:28:13 tschilli + * For XMAC the values in the SK_PNMI_PORT Port struct are copied to + * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call. + * These values are used when GetPhysStatVal() is called. With this + * mechanism you get the best results when software corrections for + * counters are needed. Example: RX_LONGFRAMES. + * + * Revision 1.99 2002/09/17 12:31:19 tschilli + * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR: + * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed. + * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to + * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement(). + * + * Revision 1.98 2002/09/10 09:00:03 rwahl + * Adapted boolean definitions according sktypes. + * + * Revision 1.97 2002/09/05 15:07:03 rwahl + * Editorial changes. + * + * Revision 1.96 2002/09/05 11:04:14 rwahl + * - Rx/Tx packets statistics of virtual port were zero on link down (#10750) + * - For GMAC the overflow IRQ for Rx longframe counter was not counted. + * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS, + * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR. + * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal(). + * - Editorial changes. + * + * Revision 1.95 2002/09/04 08:53:37 rwahl + * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751) + * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset. + * - Fixed compiler warning for debug msg arg types. + * + * Revision 1.94 2002/08/09 15:42:14 rwahl + * - Fixed StatAddr table for GMAC. + * - VirtualConf(): returned indeterminated status for speed oids if no + * active port. + * + * Revision 1.93 2002/08/09 11:04:59 rwahl + * Added handler for link speed caps. + * + * Revision 1.92 2002/08/09 09:43:03 rwahl + * - Added handler for NDIS OID_PNP_xxx ids. + * + * Revision 1.91 2002/07/17 19:53:03 rwahl + * - Added StatOvrflwBit table for XMAC & GMAC. + * - Extended StatAddr table for GMAC. Added check of number of counters + * in enumeration and size of StatAddr table on init level. + * - Added use of GIFunc table. + * - ChipSet is not static anymore, + * - Extended SIRQ event handler for both mac types. + * - Fixed rx short counter bug (#10620) + * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS. + * - Extendet GetPhysStatVal() for GMAC. + * - Editorial changes. + * + * Revision 1.90 2002/05/22 08:56:25 rwahl + * - Moved OID table to separate source file. + * - Fix: TX_DEFFERAL counter incremented in full-duplex mode. + * - Use string definitions for error msgs. + * + * Revision 1.89 2001/09/18 10:01:30 mkunz + * some OID's fixed for dualnetmode + * + * Revision 1.88 2001/08/02 07:58:08 rwahl + * - Fixed NetIndex to csum module at ResetCounter(). + * * Revision 1.87 2001/04/06 13:35:09 mkunz * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's * @@ -37,7 +109,6 @@ * * Revision 1.84 2001/03/06 09:04:55 mkunz * Made some changes in instance calculation - * C ^VS: * * Revision 1.83 2001/02/15 09:15:32 mkunz * Necessary changes for dual net mode added @@ -362,13 +433,12 @@ static const char SysKonnectFileId[] = - "@(#) $Id: skgepnmi.c,v 1.87 2001/04/06 13:35:09 mkunz Exp $" + "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $" " (C) SysKonnect."; #include "h/skdrv1st.h" #include "h/sktypes.h" #include "h/xmac_ii.h" - #include "h/skdebug.h" #include "h/skqueue.h" #include "h/skgepnmi.h" @@ -379,7 +449,16 @@ #include "h/skgeinit.h" #include "h/skdrv2nd.h" #include "h/skgepnm2.h" +#ifdef SK_POWER_MGMT +#include "h/skgepmgt.h" +#endif +/* defines *******************************************************************/ +#ifndef DEBUG +#define PNMI_STATIC static +#else /* DEBUG */ +#define PNMI_STATIC +#endif /* DEBUG */ /* * Public Function prototypes @@ -403,1037 +482,259 @@ /* * Private Function prototypes */ -static int Addr(SK_AC *pAC, SK_IOC IoC, int action, - SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int + +PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int PhysPortIndex); -static SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int +PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int PhysPortIndex); -static void CopyMac(char *pDst, SK_MAC_ADDR *pMac); -static void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); -static int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, +PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac); +PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); +PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int PhysPortIndex, unsigned int StatIndex); -static SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, +PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, unsigned int StatIndex, SK_U32 NetIndex); -static char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); -static void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, +PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); +PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, unsigned int *pEntries); -static int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, +PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, unsigned int KeyArrLen, unsigned int *pKeyNo); -static int LookupId(SK_U32 Id); -static int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, +PNMI_STATIC int LookupId(SK_U32 Id); +PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, unsigned int LastMac); -static int Monitor(SK_AC *pAC, SK_IOC IoC, int action, - SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int* pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, +PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, unsigned int *pLen, SK_U32 NetIndex); -static int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, +PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -static void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); -static void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, +PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); +PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, unsigned int PortIndex); -static void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, +PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, unsigned int SensorIndex); -static void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); -static void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); -static int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); -static int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -static int SirqUpdate(SK_AC *pAC, SK_IOC IoC); -static void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); -static int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); - - -/****************************************************************************** - * - * Global variables - */ +PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); +PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); +PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); +PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); +PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); +PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, + unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32); /* * Table to correlate OID with handler function and index to * hardware register stored in StatAddress if applicable. */ -static const SK_PNMI_TAB_ENTRY IdTable[] = { - {OID_GEN_XMIT_OK, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX}, - {OID_GEN_RCV_OK, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX}, - {OID_GEN_XMIT_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_RCV_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_RCV_NO_BUFFER, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_DIRECTED_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST}, - {OID_GEN_MULTICAST_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST}, - {OID_GEN_BROADCAST_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST}, - {OID_GEN_DIRECTED_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST}, - {OID_GEN_MULTICAST_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST}, - {OID_GEN_BROADCAST_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST}, - {OID_GEN_RCV_CRC_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS}, - {OID_GEN_TRANSMIT_QUEUE_LENGTH, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_802_3_PERMANENT_ADDRESS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, 0}, - {OID_802_3_CURRENT_ADDRESS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, 0}, - {OID_802_3_RCV_ERROR_ALIGNMENT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING}, - {OID_802_3_XMIT_ONE_COLLISION, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL}, - {OID_802_3_XMIT_MORE_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL}, - {OID_802_3_XMIT_DEFERRED, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL}, - {OID_802_3_XMIT_MAX_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL}, - {OID_802_3_RCV_OVERRUN, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW}, - {OID_802_3_XMIT_UNDERRUN, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN}, - {OID_802_3_XMIT_TIMES_CRS_LOST, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER}, - {OID_802_3_XMIT_LATE_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL}, - {OID_SKGE_MDB_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(MgmtDBVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SUPPORTED_LIST, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_SKGE_ALL_DATA, - 0, - 0, - 0, - SK_PNMI_RW, OidStruct, 0}, - {OID_SKGE_VPD_FREE_BYTES, - 1, - 0, - SK_PNMI_MAI_OFF(VpdFreeBytes), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ENTRIES_LIST, - 1, - 0, - SK_PNMI_MAI_OFF(VpdEntriesList), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ENTRIES_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(VpdEntriesNumber), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_KEY, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_VALUE, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ACCESS, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ACTION, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction), - SK_PNMI_RW, Vpd, 0}, - {OID_SKGE_PORT_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(PortNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DEVICE_TYPE, - 1, - 0, - SK_PNMI_MAI_OFF(DeviceType), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_DESCR, - 1, - 0, - SK_PNMI_MAI_OFF(DriverDescr), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(DriverVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_HW_DESCR, - 1, - 0, - SK_PNMI_MAI_OFF(HwDescr), - SK_PNMI_RO, General, 0}, - {OID_SKGE_HW_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(HwVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHIPSET, - 1, - 0, - SK_PNMI_MAI_OFF(Chipset), - SK_PNMI_RO, General, 0}, - {OID_SKGE_ACTION, - 1, - 0, - SK_PNMI_MAI_OFF(Action), - SK_PNMI_RW, Perform, 0}, - {OID_SKGE_RESULT, - 1, - 0, - SK_PNMI_MAI_OFF(TestResult), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_TYPE, - 1, - 0, - SK_PNMI_MAI_OFF(BusType), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_SPEED, - 1, - 0, - SK_PNMI_MAI_OFF(BusSpeed), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_WIDTH, - 1, - 0, - SK_PNMI_MAI_OFF(BusWidth), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_SW_QUEUE_LEN, - 1, - 0, - SK_PNMI_MAI_OFF(TxSwQueueLen), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_SW_QUEUE_MAX, - 1, - 0, - SK_PNMI_MAI_OFF(TxSwQueueMax), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_RETRY, - 1, - 0, - SK_PNMI_MAI_OFF(TxRetryCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_INTR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxIntrCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_INTR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxIntrCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_NO_BUF_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxNoBufCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_NO_BUF_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxNoBufCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_USED_DESCR_NO, - 1, - 0, - SK_PNMI_MAI_OFF(TxUsedDescrNo), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_DELIVERED_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxDeliveredCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_OCTETS_DELIV_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxOctetsDeliveredCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_HW_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxHwErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_HW_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxHwErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_IN_ERRORS_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(InErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_OUT_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(OutErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_ERR_RECOVERY_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(ErrRecoveryCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SYSUPTIME, - 1, - 0, - SK_PNMI_MAI_OFF(SysUpTime), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SENSOR_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(SensorNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SENSOR_INDEX, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_DESCR, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_TYPE, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_VALUE, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_THRES_LOW, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_THRES_UPP, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_THRES_LOW, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_THRES_UPP, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_STATUS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_CTS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_CTS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_TIME, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_TIME, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_CHKSM_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(ChecksumNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHKSM_RX_OK_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_RX_UNABLE_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_RX_ERR_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_TX_OK_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_TX_UNABLE_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_STAT_TX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX}, - {OID_SKGE_STAT_TX_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET}, - {OID_SKGE_STAT_TX_BROADCAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST}, - {OID_SKGE_STAT_TX_MULTICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST}, - {OID_SKGE_STAT_TX_UNICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST}, - {OID_SKGE_STAT_TX_LONGFRAMES, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES}, - {OID_SKGE_STAT_TX_BURST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST}, - {OID_SKGE_STAT_TX_PFLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC}, - {OID_SKGE_STAT_TX_FLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC}, - {OID_SKGE_STAT_TX_SINGLE_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL}, - {OID_SKGE_STAT_TX_MULTI_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL}, - {OID_SKGE_STAT_TX_EXCESS_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL}, - {OID_SKGE_STAT_TX_LATE_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL}, - {OID_SKGE_STAT_TX_DEFFERAL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL}, - {OID_SKGE_STAT_TX_EXCESS_DEF, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF}, - {OID_SKGE_STAT_TX_UNDERRUN, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN}, - {OID_SKGE_STAT_TX_CARRIER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER}, -/* {OID_SKGE_STAT_TX_UTIL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization), - SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ - {OID_SKGE_STAT_TX_64, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64}, - {OID_SKGE_STAT_TX_127, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127}, - {OID_SKGE_STAT_TX_255, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255}, - {OID_SKGE_STAT_TX_511, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511}, - {OID_SKGE_STAT_TX_1023, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023}, - {OID_SKGE_STAT_TX_MAX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX}, - {OID_SKGE_STAT_TX_SYNC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC}, - {OID_SKGE_STAT_TX_SYNC_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET}, - {OID_SKGE_STAT_RX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX}, - {OID_SKGE_STAT_RX_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET}, - {OID_SKGE_STAT_RX_BROADCAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST}, - {OID_SKGE_STAT_RX_MULTICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST}, - {OID_SKGE_STAT_RX_UNICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST}, - {OID_SKGE_STAT_RX_LONGFRAMES, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES}, - {OID_SKGE_STAT_RX_PFLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC}, - {OID_SKGE_STAT_RX_FLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC}, - {OID_SKGE_STAT_RX_PFLOWC_ERR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR}, - {OID_SKGE_STAT_RX_FLOWC_UNKWN, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN}, - {OID_SKGE_STAT_RX_BURST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST}, - {OID_SKGE_STAT_RX_MISSED, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED}, - {OID_SKGE_STAT_RX_FRAMING, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING}, - {OID_SKGE_STAT_RX_OVERFLOW, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW}, - {OID_SKGE_STAT_RX_JABBER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER}, - {OID_SKGE_STAT_RX_CARRIER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER}, - {OID_SKGE_STAT_RX_IR_LENGTH, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH}, - {OID_SKGE_STAT_RX_SYMBOL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL}, - {OID_SKGE_STAT_RX_SHORTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS}, - {OID_SKGE_STAT_RX_RUNT, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT}, - {OID_SKGE_STAT_RX_CEXT, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT}, - {OID_SKGE_STAT_RX_TOO_LONG, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG}, - {OID_SKGE_STAT_RX_FCS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS}, -/* {OID_SKGE_STAT_RX_UTIL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization), - SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ - {OID_SKGE_STAT_RX_64, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64}, - {OID_SKGE_STAT_RX_127, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127}, - {OID_SKGE_STAT_RX_255, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255}, - {OID_SKGE_STAT_RX_511, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511}, - {OID_SKGE_STAT_RX_1023, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023}, - {OID_SKGE_STAT_RX_MAX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX}, - {OID_SKGE_PHYS_CUR_ADDR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr), - SK_PNMI_RW, Addr, 0}, - {OID_SKGE_PHYS_FAC_ADDR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr), - SK_PNMI_RO, Addr, 0}, - {OID_SKGE_PMD, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_CONNECTOR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_LINK_MODE_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_TRAP, - 1, - 0, - SK_PNMI_MAI_OFF(Trap), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TRAP_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(TrapNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RLMT_MODE, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtMode), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortNumber), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_ACTIVE, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortActive), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_PREFERRED, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortPreferred), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeCts), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_TIME, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeTime), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_ESTIM, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeEstimate), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_THRES, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeThreshold), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_INDEX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_TX_HELLO_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_RX_HELLO_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_TX_SP_REQ_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_RX_SP_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_MONITOR_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtMonitorNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RLMT_MONITOR_INDEX, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ADDR, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ERRS, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_TIMESTAMP, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ADMIN, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin), - SK_PNMI_RW, Monitor, 0}, - {OID_SKGE_MTU, - 1, - 0, - SK_PNMI_MAI_OFF(MtuSize), - SK_PNMI_RW, MacPrivateConf, 0}, +#include "skgemib.c" + +/* global variables **********************************************************/ + +/* + * Overflow status register bit table and corresponding counter + * dependent on MAC type - the number relates to the size of overflow + * mask returned by the pFnMacOverflow function + */ +PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = { +/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST}, +/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST}, +/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC}, +/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST}, +/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW}, +/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH}, +/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64}, +/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127}, +/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255}, +/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511}, +/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023}, +/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX}, +/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES}, +/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED}, +/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL}, +/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL}, +/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL}, +/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL}, +/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL}, +/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN}, +/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED}, +/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED}, +/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED}, +/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED}, +/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED}, +/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED}, +/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST}, +/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST}, +/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC}, +/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST}, +/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS}, +/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED}, +/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW}, +/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH}, +/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW}, +/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH}, +/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE}, +/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT}, +/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64}, +/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127}, +/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255}, +/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511}, +/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023}, +/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX}, +/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES}, +/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG}, +/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER}, +/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED}, +/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW}, +/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED}, +/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED}, +/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED}, +/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED}, +/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED}, +/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED}, +/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED}, +/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED}, +/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED} }; /* * Table for hardware register saving on resets and port switches */ -static const SK_PNMI_STATADDR StatAddress[SK_PNMI_MAX_IDX] = { - /* 0 */ {TRUE, XM_TXF_OK}, - /* 1 */ {TRUE, 0}, - /* 2 */ {FALSE, 0}, - /* 3 */ {TRUE, XM_TXF_BC_OK}, - /* 4 */ {TRUE, XM_TXF_MC_OK}, - /* 5 */ {TRUE, XM_TXF_UC_OK}, - /* 6 */ {TRUE, XM_TXF_LONG}, - /* 7 */ {TRUE, XM_TXE_BURST}, - /* 8 */ {TRUE, XM_TXF_MPAUSE}, - /* 9 */ {TRUE, XM_TXF_MCTRL}, - /* 10 */ {TRUE, XM_TXF_SNG_COL}, - /* 11 */ {TRUE, XM_TXF_MUL_COL}, - /* 12 */ {TRUE, XM_TXF_ABO_COL}, - /* 13 */ {TRUE, XM_TXF_LAT_COL}, - /* 14 */ {TRUE, XM_TXF_DEF}, - /* 15 */ {TRUE, XM_TXF_EX_DEF}, - /* 16 */ {TRUE, XM_TXE_FIFO_UR}, - /* 17 */ {TRUE, XM_TXE_CS_ERR}, - /* 18 */ {FALSE, 0}, - /* 19 */ {FALSE, 0}, - /* 20 */ {TRUE, XM_TXF_64B}, - /* 21 */ {TRUE, XM_TXF_127B}, - /* 22 */ {TRUE, XM_TXF_255B}, - /* 23 */ {TRUE, XM_TXF_511B}, - /* 24 */ {TRUE, XM_TXF_1023B}, - /* 25 */ {TRUE, XM_TXF_MAX_SZ}, - /* 26 */ {FALSE, 0}, - /* 27 */ {FALSE, 0}, - /* 28 */ {FALSE, 0}, - /* 29 */ {FALSE, 0}, - /* 30 */ {FALSE, 0}, - /* 31 */ {FALSE, 0}, - /* 32 */ {TRUE, XM_RXF_OK}, - /* 33 */ {TRUE, 0}, - /* 34 */ {FALSE, 0}, - /* 35 */ {TRUE, XM_RXF_BC_OK}, - /* 36 */ {TRUE, XM_RXF_MC_OK}, - /* 37 */ {TRUE, XM_RXF_UC_OK}, - /* 38 */ {TRUE, XM_RXF_MPAUSE}, - /* 39 */ {TRUE, XM_RXF_MCTRL}, - /* 40 */ {TRUE, XM_RXF_INV_MP}, - /* 41 */ {TRUE, XM_RXF_INV_MOC}, - /* 42 */ {TRUE, XM_RXE_BURST}, - /* 43 */ {TRUE, XM_RXE_FMISS}, - /* 44 */ {TRUE, XM_RXF_FRA_ERR}, - /* 45 */ {TRUE, XM_RXE_FIFO_OV}, - /* 46 */ {TRUE, XM_RXF_JAB_PKT}, - /* 47 */ {TRUE, XM_RXE_CAR_ERR}, - /* 48 */ {TRUE, XM_RXF_LEN_ERR}, - /* 49 */ {TRUE, XM_RXE_SYM_ERR}, - /* 50 */ {TRUE, XM_RXE_SHT_ERR}, - /* 51 */ {TRUE, XM_RXE_RUNT}, - /* 52 */ {TRUE, XM_RXF_LNG_ERR}, - /* 53 */ {TRUE, XM_RXF_FCS_ERR}, - /* 54 */ {FALSE, 0}, - /* 55 */ {TRUE, XM_RXF_CEX_ERR}, - /* 56 */ {FALSE, 0}, - /* 57 */ {FALSE, 0}, - /* 58 */ {TRUE, XM_RXF_64B}, - /* 59 */ {TRUE, XM_RXF_127B}, - /* 60 */ {TRUE, XM_RXF_255B}, - /* 61 */ {TRUE, XM_RXF_511B}, - /* 62 */ {TRUE, XM_RXF_1023B}, - /* 63 */ {TRUE, XM_RXF_MAX_SZ}, - /* 64 */ {FALSE, 0}, - /* 65 */ {FALSE, 0}, - /* 66 */ {TRUE, 0} +PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = { + /* SK_PNMI_HTX */ + {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_OCTETHIGH */ + {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}}, + /* SK_PNMI_HTX_OCTETLOW */ + {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}}, + /* SK_PNMI_HTX_BROADCAST */ + {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}}, + /* SK_PNMI_HTX_MULTICAST */ + {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}}, + /* SK_PNMI_HTX_UNICAST */ + {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}}, + /* SK_PNMI_HTX_BURST */ + {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_PMACC */ + {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}}, + /* SK_PNMI_HTX_MACC */ + {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_COL */ + {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}}, + /* SK_PNMI_HTX_SINGLE_COL */ + {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}}, + /* SK_PNMI_HTX_MULTI_COL */ + {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}}, + /* SK_PNMI_HTX_EXCESS_COL */ + {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}}, + /* SK_PNMI_HTX_LATE_COL */ + {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}}, + /* SK_PNMI_HTX_DEFFERAL */ + {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_EXCESS_DEF */ + {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_UNDERRUN */ + {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}}, + /* SK_PNMI_HTX_CARRIER */ + {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_UTILUNDER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_UTILOVER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_64 */ + {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}}, + /* SK_PNMI_HTX_127 */ + {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}}, + /* SK_PNMI_HTX_255 */ + {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}}, + /* SK_PNMI_HTX_511 */ + {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}}, + /* SK_PNMI_HTX_1023 */ + {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}}, + /* SK_PNMI_HTX_MAX */ + {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}}, + /* SK_PNMI_HTX_LONGFRAMES */ + {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}}, + /* SK_PNMI_HTX_SYNC */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_SYNC_OCTET */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_RESERVED */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX */ + {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_OCTETHIGH */ + {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}}, + /* SK_PNMI_HRX_OCTETLOW */ + {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}}, + /* SK_PNMI_HRX_BADOCTETHIGH */ + {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}}, + /* SK_PNMI_HRX_BADOCTETLOW */ + {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}}, + /* SK_PNMI_HRX_BROADCAST */ + {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}}, + /* SK_PNMI_HRX_MULTICAST */ + {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}}, + /* SK_PNMI_HRX_UNICAST */ + {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}}, + /* SK_PNMI_HRX_PMACC */ + {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}}, + /* SK_PNMI_HRX_MACC */ + {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_PMACC_ERR */ + {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_MACC_UNKWN */ + {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_BURST */ + {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_MISSED */ + {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_FRAMING */ + {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_UNDERSIZE */ + {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}}, + /* SK_PNMI_HRX_OVERFLOW */ + {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}}, + /* SK_PNMI_HRX_JABBER */ + {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}}, + /* SK_PNMI_HRX_CARRIER */ + {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_IRLENGTH */ + {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_SYMBOL */ + {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_SHORTS */ + {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_RUNT */ + {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}}, + /* SK_PNMI_HRX_TOO_LONG */ + {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}}, + /* SK_PNMI_HRX_FCS */ + {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}}, + /* SK_PNMI_HRX_CEXT */ + {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_UTILUNDER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_UTILOVER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_64 */ + {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}}, + /* SK_PNMI_HRX_127 */ + {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}}, + /* SK_PNMI_HRX_255 */ + {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}}, + /* SK_PNMI_HRX_511 */ + {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}}, + /* SK_PNMI_HRX_1023 */ + {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}}, + /* SK_PNMI_HRX_MAX */ + {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}}, + /* SK_PNMI_HRX_LONGFRAMES */ + {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}}, + /* SK_PNMI_HRX_RESERVED */ + {{0, SK_FALSE}, {0, SK_FALSE}} }; @@ -1457,7 +758,6 @@ * Returns: * Always 0 */ - int SkPnmiInit( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -1468,6 +768,8 @@ SK_U16 Val16; /* Multiple purpose 16 bit variable */ SK_U8 Val8; /* Mulitple purpose 8 bit variable */ SK_EVPARA EventParam; /* Event struct for timer event */ + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctBackupData; SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, @@ -1485,6 +787,33 @@ pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE; pAC->Pnmi.DualNetActiveFlag = SK_FALSE; } + +#ifdef SK_PNMI_CHECK + if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, + ("CounterOffset struct size (%d) differs from" + "SK_PNMI_MAX_IDX (%d)\n", + SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); + BRK; + } + + if (SK_PNMI_MAX_IDX != + (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, + ("StatAddr table size (%d) differs from " + "SK_PNMI_MAX_IDX (%d)\n", + (sizeof(StatAddr) / + (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), + SK_PNMI_MAX_IDX)); + BRK; + } +#endif /* SK_PNMI_CHECK */ break; case SK_INIT_IO: @@ -1495,12 +824,17 @@ for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { - Val16 = XM_SC_CLR_RXC | XM_SC_CLR_TXC; - XM_OUT16(IoC, PortIndex, XM_STAT_CMD, Val16); - /* Clear two times according to Errata #3 */ - XM_OUT16(IoC, PortIndex, XM_STAT_CMD, Val16); + pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex); } - + + /* Initialize DSP variables for Vct() to 0xff => Never written! */ + for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { + pPrt = &pAC->GIni.GP[PortIndex]; + pPrt->PCableLen =0xff; + pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex]; + pVctBackupData->PCableLen = 0xff; + } + /* * Get pci bus speed */ @@ -1526,6 +860,22 @@ } /* + * Get chipset + */ + switch (pAC->GIni.GIChipId) { + case CHIP_ID_GENESIS: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC; + break; + + case CHIP_ID_YUKON: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON; + break; + + default: + break; + } + + /* * Get PMD and DeviceType */ SK_IN8(IoC, B2_PMD_TYP, &Val8); @@ -1608,14 +958,14 @@ default: pAC->Pnmi.Connector = 1; break; - } + } break; - + case SK_INIT_RUN: /* * Start timer for RLMT change counter */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, EventParam); @@ -1647,7 +997,6 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - int SkPnmiGetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -1690,7 +1039,6 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - int SkPnmiPreSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -1734,7 +1082,6 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - int SkPnmiSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -1771,7 +1118,6 @@ * the data. * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist */ - int SkPnmiGetStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -1861,8 +1207,7 @@ /* Retrieve values */ SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE); - for (TableIndex = 0; TableIndex < sizeof(IdTable)/sizeof(IdTable[0]); - TableIndex ++) { + for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { InstanceNo = IdTable[TableIndex].InstanceNo; for (InstanceCnt = 1; InstanceCnt <= InstanceNo; @@ -1951,7 +1296,6 @@ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid * value range. */ - int SkPnmiPreSetStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -1990,7 +1334,6 @@ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid * value range. */ - int SkPnmiSetStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -2056,7 +1399,6 @@ * Returns: * Always 0 */ - int SkPnmiEvent( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ @@ -2064,14 +1406,15 @@ SK_EVPARA Param) /* Event dependent parameter */ { unsigned int PhysPortIndex; - unsigned int MaxNetNumber; - int CounterIndex; - int Ret; + unsigned int MaxNetNumber; + int CounterIndex; + int Ret; SK_U16 MacStatus; SK_U64 OverflowStatus; SK_U64 Mask; - SK_U32 MacCntEvent; + int MacType; SK_U64 Value; + SK_U32 Val32; SK_U16 Register; SK_EVPARA EventParam; SK_U64 NewestValue; @@ -2079,6 +1422,11 @@ SK_U64 Delta; SK_PNMI_ESTIMATE *pEst; SK_U32 NetIndex; + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctBackupData; + SK_U32 RetCode; + int i; + SK_U32 CableLength; #ifdef DEBUG @@ -2086,11 +1434,13 @@ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n", - (unsigned long)Event, (unsigned long)Param.Para64)); + (unsigned int)Event, (unsigned int)Param.Para64)); } #endif SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); + MacType = pAC->GIni.GIMacType; + switch (Event) { case SK_PNMI_EVT_SIRQ_OVERFLOW: @@ -2100,7 +1450,8 @@ if (PhysPortIndex >= SK_MAX_MACS) { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter wrong, PhysPortIndex=0x%x\n", + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter" + " wrong, PhysPortIndex=0x%x\n", PhysPortIndex)); return (0); } @@ -2108,28 +1459,14 @@ OverflowStatus = 0; /* - * Check which source caused an overflow interrupt. The - * interrupt source is a self-clearing register. We only - * need to check the interrupt source once. Another check - * will be done by the SIRQ module to be sure that no - * interrupt get lost during process time. + * Check which source caused an overflow interrupt. */ - if ((MacStatus & XM_IS_RXC_OV) == XM_IS_RXC_OV) { - - XM_IN32(IoC, PhysPortIndex, XM_RX_CNT_EV, - &MacCntEvent); - OverflowStatus |= (SK_U64)MacCntEvent << 32; - } - if ((MacStatus & XM_IS_TXC_OV) == XM_IS_TXC_OV) { - - XM_IN32(IoC, PhysPortIndex, XM_TX_CNT_EV, - &MacCntEvent); - OverflowStatus |= (SK_U64)MacCntEvent; - } - if (OverflowStatus == 0) { + if ((pAC->GIni.GIFunc.pFnMacOverflow( + pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) || + (OverflowStatus == 0)) { SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); + return (0); } /* @@ -2145,7 +1482,7 @@ continue; } - switch (CounterIndex) { + switch (StatOvrflwBit[CounterIndex][MacType]) { case SK_PNMI_HTX_UTILUNDER: case SK_PNMI_HTX_UTILOVER: @@ -2167,23 +1504,24 @@ case SK_PNMI_HTX_OCTETHIGH: case SK_PNMI_HTX_OCTETLOW: - case SK_PNMI_HTX_RESERVED26: - case SK_PNMI_HTX_RESERVED27: - case SK_PNMI_HTX_RESERVED28: - case SK_PNMI_HTX_RESERVED29: - case SK_PNMI_HTX_RESERVED30: - case SK_PNMI_HTX_RESERVED31: + case SK_PNMI_HTX_RESERVED: case SK_PNMI_HRX_OCTETHIGH: case SK_PNMI_HRX_OCTETLOW: case SK_PNMI_HRX_IRLENGTH: - case SK_PNMI_HRX_RESERVED22: + case SK_PNMI_HRX_RESERVED: /* * the following counters aren't be handled (id > 63) */ case SK_PNMI_HTX_SYNC: case SK_PNMI_HTX_SYNC_OCTET: + break; + case SK_PNMI_HRX_LONGFRAMES: + if (MacType == SK_MAC_GMAC) { + pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[CounterIndex] ++; + } break; default: @@ -2333,7 +1671,7 @@ (void)SK_DRIVER_SENDEVENT(pAC, IoC); } - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, EventParam); @@ -2396,10 +1734,10 @@ */ pAC->Pnmi.MacUpdatedFlag ++; - for (CounterIndex = 0; CounterIndex < SK_PNMI_SCNT_NOT; + for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; CounterIndex ++) { - if (!StatAddress[CounterIndex].GetOffset) { + if (!StatAddr[CounterIndex][MacType].GetOffset) { continue; } @@ -2415,12 +1753,13 @@ break; case SK_PNMI_EVT_RLMT_PORT_UP: + PhysPortIndex = (unsigned int)Param.Para32[0]; #ifdef DEBUG - if ((unsigned int)Param.Para32[0] >= SK_MAX_MACS) { + if (PhysPortIndex >= SK_MAX_MACS) { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter wrong, PhysPortIndex=%d\n", - (unsigned int)Param.Para32[0])); + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter" + " wrong, PhysPortIndex=%d\n", PhysPortIndex)); return (0); } @@ -2429,18 +1768,35 @@ * Store a trap message in the trap buffer and generate an event for * user space applications with the SK_DRIVER_SENDEVENT macro. */ - QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, - (unsigned int)Param.Para32[0]); + QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex); (void)SK_DRIVER_SENDEVENT(pAC, IoC); + + /* Bugfix for XMAC errata (#10620)*/ + if (pAC->GIni.GIMacType == SK_MAC_XMAC){ + + /* Add incremental difference to offset (#10620)*/ + (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, + XM_RXE_SHT_ERR, &Val32); + + Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); + pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] += + Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark; + } + + /* Tell VctStatus() that a link was up meanwhile. */ + pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK; break; - case SK_PNMI_EVT_RLMT_PORT_DOWN: + case SK_PNMI_EVT_RLMT_PORT_DOWN: + PhysPortIndex = (unsigned int)Param.Para32[0]; + #ifdef DEBUG - if ((unsigned int)Param.Para32[0] >= SK_MAX_MACS) { + if (PhysPortIndex >= SK_MAX_MACS) { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter wrong, PhysPortIndex=%d\n", - (unsigned int)Param.Para32[0])); + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter" + " wrong, PhysPortIndex=%d\n", PhysPortIndex)); return (0); } @@ -2449,14 +1805,24 @@ * Store a trap message in the trap buffer and generate an event for * user space applications with the SK_DRIVER_SENDEVENT macro. */ - QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, - (unsigned int)Param.Para32[0]); + QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); (void)SK_DRIVER_SENDEVENT(pAC, IoC); + + /* Bugfix #10620 - get zero level for incremental difference */ + if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) { + + (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, + XM_RXE_SHT_ERR, &Val32); + pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = + (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); + } break; case SK_PNMI_EVT_RLMT_ACTIVE_DOWN: PhysPortIndex = (unsigned int)Param.Para32[0]; NetIndex = (SK_U32)Param.Para32[1]; + #ifdef DEBUG if (PhysPortIndex >= SK_MAX_MACS) { @@ -2512,7 +1878,7 @@ for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; CounterIndex ++) { - if (!StatAddress[CounterIndex].GetOffset) { + if (!StatAddr[CounterIndex][MacType].GetOffset) { continue; } @@ -2533,6 +1899,7 @@ case SK_PNMI_EVT_RLMT_ACTIVE_UP: PhysPortIndex = (unsigned int)Param.Para32[0]; NetIndex = (SK_U32)Param.Para32[1]; + #ifdef DEBUG if (PhysPortIndex >= SK_MAX_MACS) { @@ -2599,7 +1966,7 @@ for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; CounterIndex ++) { - if (!StatAddress[CounterIndex].GetOffset) { + if (!StatAddr[CounterIndex][MacType].GetOffset) { continue; } @@ -2644,7 +2011,7 @@ return (SK_PNMI_ERR_UNKNOWN_NET); } - if((unsigned int)Param.Para32[0] == 1){ /* single net mode */ + if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */ pAC->Pnmi.DualNetActiveFlag = SK_FALSE; } else { /* dual net mode */ @@ -2652,6 +2019,49 @@ } break; + case SK_PNMI_EVT_VCT_RESET: + PhysPortIndex = Param.Para32[0]; + pPrt = &pAC->GIni.GP[PhysPortIndex]; + pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; + + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); + if (RetCode == 2) { + /* + * VCT test is still running. + * Start VCT timer counter again. + */ + SK_MEMSET((char *) &Param, 0, sizeof(Param)); + Param.Para32[0] = PhysPortIndex; + Param.Para32[1] = -1; + SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, + 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); + break; + } + pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; + pAC->Pnmi.VctStatus[PhysPortIndex] |= + (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); + + /* Copy results for later use to PNMI struct. */ + for (i = 0; i < 4; i++) { + if (pPrt->PMdiPairLen[i] > 35) { + CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); + } + else { + CableLength = 0; + } + pVctBackupData->PMdiPairLen[i] = CableLength; + pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; + } + + Param.Para32[0] = PhysPortIndex; + Param.Para32[1] = -1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); + SkEventDispatcher(pAC, IoC); + } + + break; + default: break; } @@ -2682,8 +2092,7 @@ * calling functions. * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist */ - -static int PnmiVar( +PNMI_STATIC int PnmiVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -2738,8 +2147,7 @@ * SK_PNMI_ERR_XXX. The codes are described in the calling functions. * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist */ - -static int PnmiStruct( +PNMI_STATIC int PnmiStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Set action to be performed */ @@ -2802,10 +2210,10 @@ pAC->Pnmi.SirqUpdatedFlag ++; /* Preset/Set values */ - for (TableIndex = 0; TableIndex < sizeof(IdTable)/sizeof(IdTable[0]); - TableIndex ++) { + for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { - if (IdTable[TableIndex].Access != SK_PNMI_RW) { + if ((IdTable[TableIndex].Access != SK_PNMI_RW) && + (IdTable[TableIndex].Access != SK_PNMI_WO)) { continue; } @@ -2906,14 +2314,12 @@ * Returns: * The table index or -1 if not found. */ - -static int LookupId( +PNMI_STATIC int LookupId( SK_U32 Id) /* Object identifier to be searched */ { int i; - int Len = sizeof(IdTable)/sizeof(IdTable[0]); - for (i=0; iGIni.GIMacsFound; LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ LogPortMax--; } @@ -3384,17 +2786,43 @@ case OID_SKGE_STAT_RX_UTIL: return (SK_PNMI_ERR_GENERAL); */ - /* - * Frames longer than IEEE 802.3 frame max size are counted - * by XMAC in frame_too_long counter even reception of long - * frames was enabled and the frame was correct. - * So correct the value by subtracting RxLongFrame counter. - */ - case OID_SKGE_STAT_RX_TOO_LONG: - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex) - - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_LONGFRAMES, NetIndex); + case OID_SKGE_STAT_RX: + case OID_SKGE_STAT_TX: + switch (pAC->GIni.GIMacType) { + case SK_MAC_XMAC: + StatVal = GetStatVal(pAC, IoC, LogPortIndex, + IdTable[TableIndex].Param, NetIndex); + break; + + case SK_MAC_GMAC: + if (Id == OID_SKGE_STAT_TX) { + + StatVal = + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_BROADCAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_MULTICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_UNICAST, NetIndex); + } + else { + StatVal = + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_BROADCAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_MULTICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_UNICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_UNDERSIZE, NetIndex); + } + break; + + default: + StatVal = 0; + break; + } + SK_PNMI_STORE_U64(pBuf + Offset, StatVal); break; @@ -3438,8 +2866,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int Addr( +PNMI_STATIC int Addr( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -3458,8 +2885,6 @@ unsigned int Limit; unsigned int Offset = 0; - - /* * Calculate instance if wished. MAC index 0 is the virtual * MAC. @@ -3467,7 +2892,7 @@ PhysPortMax = pAC->GIni.GIMacsFound; LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ LogPortMax--; } @@ -3647,8 +3072,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int CsumStat( +PNMI_STATIC int CsumStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -3766,8 +3190,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int SensorStat( +PNMI_STATIC int SensorStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -3976,8 +3399,8 @@ break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR013, - SK_PNMI_ERR013MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("SensorStat: Unknown OID should be handled before")); return (SK_PNMI_ERR_GENERAL); } @@ -4014,8 +3437,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int Vpd( +PNMI_STATIC int Vpd( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -4490,8 +3912,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int General( +PNMI_STATIC int General( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -4515,7 +3936,7 @@ SK_U64 Val64TxHwErrs = 0; SK_BOOL Is64BitReq = SK_FALSE; char Buf[256]; - + int MacType; /* * Check instance. We only handle single instance variables @@ -4534,7 +3955,9 @@ *pLen = 0; return (SK_PNMI_ERR_READ_ONLY); } - + + MacType = pAC->GIni.GIMacType; + /* * Check length for the various supported OIDs */ @@ -4669,8 +4092,7 @@ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex)- - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_LONGFRAMES, NetIndex)+ + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex); break; @@ -4682,8 +4104,7 @@ GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+ GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+ - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex)+ - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex); + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex); break; } } @@ -4694,7 +4115,7 @@ switch (Id) { case OID_SKGE_SUPPORTED_LIST: - Len = sizeof(IdTable)/sizeof(IdTable[0]) * sizeof(SK_U32); + Len = ID_TABLE_SIZE * sizeof(SK_U32); if (*pLen < Len) { *pLen = Len; @@ -4833,7 +4254,7 @@ break; case OID_SKGE_CHIPSET: - Val16 = SK_PNMI_CHIPSET; + Val16 = pAC->Pnmi.Chipset; SK_PNMI_STORE_U16(pBuf, Val16); *pLen = sizeof(SK_U16); break; @@ -4895,141 +4316,281 @@ break; case OID_SKGE_TX_SW_QUEUE_LEN: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen + + pAC->Pnmi.BufPort[1].TxSwQueueLen; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + - pAC->Pnmi.Port[1].TxSwQueueLen; - } + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + + pAC->Pnmi.Port[1].TxSwQueueLen; + } + } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_TX_SW_QUEUE_MAX: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax + + pAC->Pnmi.BufPort[1].TxSwQueueMax; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + - pAC->Pnmi.Port[1].TxSwQueueMax; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + + pAC->Pnmi.Port[1].TxSwQueueMax; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_TX_RETRY: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxRetryCts + + pAC->Pnmi.BufPort[1].TxRetryCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].TxRetryCts + - pAC->Pnmi.Port[1].TxRetryCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].TxRetryCts + + pAC->Pnmi.Port[1].TxRetryCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_RX_INTR_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxIntrCts + + pAC->Pnmi.BufPort[1].RxIntrCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].RxIntrCts + - pAC->Pnmi.Port[1].RxIntrCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].RxIntrCts + + pAC->Pnmi.Port[1].RxIntrCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_TX_INTR_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxIntrCts + + pAC->Pnmi.BufPort[1].TxIntrCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].TxIntrCts + - pAC->Pnmi.Port[1].TxIntrCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].TxIntrCts + + pAC->Pnmi.Port[1].TxIntrCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_RX_NO_BUF_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts + + pAC->Pnmi.BufPort[1].RxNoBufCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].RxNoBufCts + - pAC->Pnmi.Port[1].RxNoBufCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].RxNoBufCts + + pAC->Pnmi.Port[1].RxNoBufCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_TX_NO_BUF_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts + + pAC->Pnmi.BufPort[1].TxNoBufCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].TxNoBufCts + - pAC->Pnmi.Port[1].TxNoBufCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].TxNoBufCts + + pAC->Pnmi.Port[1].TxNoBufCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_TX_USED_DESCR_NO: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo + + pAC->Pnmi.BufPort[1].TxUsedDescrNo; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + - pAC->Pnmi.Port[1].TxUsedDescrNo; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + + pAC->Pnmi.Port[1].TxUsedDescrNo; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_RX_DELIVERED_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts + + pAC->Pnmi.BufPort[1].RxDeliveredCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + - pAC->Pnmi.Port[1].RxDeliveredCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + + pAC->Pnmi.Port[1].RxDeliveredCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_RX_OCTETS_DELIV_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts + + pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + - pAC->Pnmi.Port[1].RxOctetsDeliveredCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + + pAC->Pnmi.Port[1].RxOctetsDeliveredCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); @@ -5046,44 +4607,88 @@ break; case OID_SKGE_IN_ERRORS_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + /* Single net mode */ + else { + Val64 = Val64RxHwErrs + + pAC->Pnmi.BufPort[0].RxNoBufCts + + pAC->Pnmi.BufPort[1].RxNoBufCts; + } } - /* Single net mode */ else { - Val64 = Val64RxHwErrs + - pAC->Pnmi.Port[0].RxNoBufCts + - pAC->Pnmi.Port[1].RxNoBufCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } + /* Single net mode */ + else { + Val64 = Val64RxHwErrs + + pAC->Pnmi.Port[0].RxNoBufCts + + pAC->Pnmi.Port[1].RxNoBufCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_OUT_ERROR_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } + /* Single net mode */ + else { + Val64 = Val64TxHwErrs + + pAC->Pnmi.BufPort[0].TxNoBufCts + + pAC->Pnmi.BufPort[1].TxNoBufCts; + } } - /* Single net mode */ else { - Val64 = Val64TxHwErrs + - pAC->Pnmi.Port[0].TxNoBufCts + - pAC->Pnmi.Port[1].TxNoBufCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } + /* Single net mode */ + else { + Val64 = Val64TxHwErrs + + pAC->Pnmi.Port[0].TxNoBufCts + + pAC->Pnmi.Port[1].TxNoBufCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); break; case OID_SKGE_ERR_RECOVERY_CTS: - /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ - Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts + + pAC->Pnmi.BufPort[1].ErrRecoveryCts; + } } - /* Single net mode */ else { - Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + - pAC->Pnmi.Port[1].ErrRecoveryCts; + /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; + } + /* Single net mode */ + else { + Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + + pAC->Pnmi.Port[1].ErrRecoveryCts; + } } SK_PNMI_STORE_U64(pBuf, Val64); *pLen = sizeof(SK_U64); @@ -5103,7 +4708,13 @@ break; case OID_GEN_RCV_ERROR: - Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + else { + Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } /* * by default 32bit values are evaluated @@ -5120,7 +4731,13 @@ break; case OID_GEN_XMIT_ERROR: - Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } + else { + Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } /* * by default 32bit values are evaluated @@ -5137,7 +4754,13 @@ break; case OID_GEN_RCV_NO_BUFFER: - Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + else { + Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } /* * by default 32bit values are evaluated @@ -5200,8 +4823,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int Rlmt( +PNMI_STATIC int Rlmt( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -5359,8 +4981,8 @@ break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR036, - SK_PNMI_ERR036MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("Rlmt: Unknown OID should be handled before")); pAC->Pnmi.RlmtUpdatedFlag --; *pLen = 0; @@ -5506,8 +5128,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int RlmtStat( +PNMI_STATIC int RlmtStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -5543,7 +5164,7 @@ PhysPortIndex = Instance - 1; /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { PhysPortIndex = NetIndex; } @@ -5556,7 +5177,7 @@ Limit = PhysPortMax; /* Dual net mode */ - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { PhysPortIndex = NetIndex; Limit = PhysPortIndex + 1; } @@ -5674,8 +5295,8 @@ break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, - SK_PNMI_ERR040MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("RlmtStat: Unknown OID should be errored before")); pAC->Pnmi.RlmtUpdatedFlag --; *pLen = 0; @@ -5709,8 +5330,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int MacPrivateConf( +PNMI_STATIC int MacPrivateConf( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -5740,7 +5360,7 @@ PhysPortMax = pAC->GIni.GIMacsFound; LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ LogPortMax--; } @@ -5783,6 +5403,9 @@ case OID_SKGE_PHY_OPERATION_CAP: case OID_SKGE_PHY_OPERATION_MODE: case OID_SKGE_PHY_OPERATION_STATUS: + case OID_SKGE_SPEED_CAP: + case OID_SKGE_SPEED_MODE: + case OID_SKGE_SPEED_STATUS: if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { *pLen = (Limit - LogPortIndex) * @@ -5836,188 +5459,327 @@ break; case OID_SKGE_LINK_CAP: - if (LogPortIndex == 0) { + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PLinkCap; + } + Offset += sizeof(char); } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkCap; + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap; + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_LINK_MODE: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + Offset); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkModeConf; + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PLinkModeConf; + } + Offset += sizeof(char); + } + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf; + Offset += sizeof(char); } - - Offset += sizeof(char); break; case OID_SKGE_LINK_MODE_STATUS: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = + CalculateLinkModeStatus(pAC, + IoC, PhysPortIndex); + } + Offset += sizeof(char); } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *(pBuf + Offset) = - CalculateLinkModeStatus(pAC, - IoC, PhysPortIndex); + else { /* DualNetMode */ + *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex); + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_LINK_STATUS: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = + CalculateLinkStatus(pAC, + IoC, PhysPortIndex); + } + Offset += sizeof(char); } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); + else { /* DualNetMode */ - *(pBuf + Offset) = - CalculateLinkStatus(pAC, - IoC, PhysPortIndex); + *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex); + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_FLOWCTRL_CAP: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PFlowCtrlCap; + } + Offset += sizeof(char); } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PFlowCtrlCap; + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap; + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_FLOWCTRL_MODE: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PFlowCtrlMode; + } + Offset += sizeof(char); } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); + else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PFlowCtrlMode; + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode; + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_FLOWCTRL_STATUS: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PFlowCtrlStatus; + } + Offset += sizeof(char); } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); + else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PFlowCtrlStatus; + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_PHY_OPERATION_CAP: - if (LogPortIndex == 0) { - - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PMSCap; + } + Offset += sizeof(char); } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PMSCap; + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap; + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_PHY_OPERATION_MODE: - if (LogPortIndex == 0) { + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PMSMode; + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PMSMode; + } + Offset += sizeof(char); + } + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode; + Offset += sizeof(char); } - Offset += sizeof(char); break; case OID_SKGE_PHY_OPERATION_STATUS: - if (LogPortIndex == 0) { + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PMSStatus; + } + Offset += sizeof(char); } else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus; + Offset += sizeof(char); + } + break; + + case OID_SKGE_SPEED_CAP: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + + Offset); + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PLinkSpeedCap; + } + Offset += sizeof(char); + } + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap; + Offset += sizeof(char); + } + break; + + case OID_SKGE_SPEED_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PLinkSpeed; + } + Offset += sizeof(char); + } + else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PMSStatus; + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed; + Offset += sizeof(char); } - Offset += sizeof(char); break; + case OID_SKGE_SPEED_STATUS: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + + /* Get value for virtual port */ + VirtualConf(pAC, IoC, Id, pBuf + Offset); + } + else { + /* Get value for physical port */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *(pBuf + Offset) = pAC->GIni.GP[ + PhysPortIndex].PLinkSpeedUsed; + } + Offset += sizeof(char); + } + else { /* DualNetMode */ + + *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; + Offset += sizeof(char); + } + break; + case OID_SKGE_MTU: Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); SK_PNMI_STORE_U32(pBuf + Offset, Val32); @@ -6025,8 +5787,8 @@ break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR042, - SK_PNMI_ERR042MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("MacPrivateConf: Unknown OID should be handled before")); pAC->Pnmi.SirqUpdatedFlag --; return (SK_PNMI_ERR_GENERAL); @@ -6047,6 +5809,7 @@ case OID_SKGE_LINK_MODE: case OID_SKGE_FLOWCTRL_MODE: case OID_SKGE_PHY_OPERATION_MODE: + case OID_SKGE_SPEED_MODE: if (*pLen < Limit - LogPortIndex) { *pLen = Limit - LogPortIndex; @@ -6284,8 +6047,8 @@ EventParam) > 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR052, - SK_PNMI_ERR052MSG); + SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); *pLen = 0; return (SK_PNMI_ERR_GENERAL); @@ -6304,8 +6067,8 @@ SK_HWEV_SET_ROLE, EventParam) > 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR052, - SK_PNMI_ERR052MSG); + SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); *pLen = 0; return (SK_PNMI_ERR_GENERAL); @@ -6315,6 +6078,82 @@ Offset += sizeof(char); break; + case OID_SKGE_SPEED_MODE: + /* Check the value range */ + Val8 = *(pBuf + Offset); + if (Val8 == 0) { + + Offset += sizeof(char); + break; + } + if (Val8 < (SK_LSPEED_AUTO) || + (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) || + (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* The preset ends here */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (LogPortIndex == 0) { + + /* + * The virtual port consists of all currently + * active ports. Find them and send an event + * with the new flow control mode to SIRQ. + */ + for (PhysPortIndex = 0; + PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + continue; + } + + EventParam.Para32[0] = PhysPortIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_SPEED, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { + /* + * Send an event with the new flow control + * mode to the SIRQ module. + */ + EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_SPEED, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + Offset += sizeof(char); + break; + case OID_SKGE_MTU : /* Check the value range */ Val32 = *(SK_U32*)(pBuf + Offset); @@ -6341,8 +6180,8 @@ break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045, - SK_PNMI_ERR045MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("MacPrivateConf: Unknown OID should be handled before set")); *pLen = 0; return (SK_PNMI_ERR_GENERAL); @@ -6373,8 +6212,7 @@ * exist (e.g. port instance 3 on a two port * adapter. */ - -static int Monitor( +PNMI_STATIC int Monitor( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Action, /* Get/PreSet/Set action */ @@ -6489,8 +6327,7 @@ * Returns: * Nothing */ - -static void VirtualConf( +PNMI_STATIC void VirtualConf( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -6534,8 +6371,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PLinkModeConf; + *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; continue; } @@ -6553,8 +6389,7 @@ case OID_SKGE_LINK_MODE_STATUS: /* Get the link mode of the physical port */ - Val8 = CalculateLinkModeStatus(pAC, IoC, - PhysPortIndex); + Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); /* Check if it is the first active port */ if (*pBuf == 0) { @@ -6602,8 +6437,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PFlowCtrlCap; + *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; continue; } @@ -6618,8 +6452,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PFlowCtrlMode; + *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; continue; } @@ -6628,8 +6461,7 @@ * control mode than the first one, we return a value * that indicates that the mode is indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex]. - PFlowCtrlMode) { + if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) { *pBuf = SK_FLOW_MODE_INDETERMINATED; } @@ -6639,8 +6471,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PFlowCtrlStatus; + *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; continue; } @@ -6650,18 +6481,17 @@ * value that indicates that the status is * indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex]. - PFlowCtrlStatus) { + if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) { *pBuf = SK_FLOW_STAT_INDETERMINATED; } break; + case OID_SKGE_PHY_OPERATION_CAP: /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PMSCap; + *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap; continue; } @@ -6676,8 +6506,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PMSMode; + *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode; continue; } @@ -6686,8 +6515,7 @@ * slave mode than the first one, we return a value * that indicates that the mode is indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex]. - PMSMode) { + if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) { *pBuf = SK_MS_MODE_INDETERMINATED; } @@ -6697,8 +6525,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex]. - PMSStatus; + *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus; continue; } @@ -6708,12 +6535,50 @@ * value that indicates that the status is * indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex]. - PMSStatus) { + if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) { *pBuf = SK_MS_STAT_INDETERMINATED; } break; + + case OID_SKGE_SPEED_MODE: + /* Check if it is the first active port */ + if (*pBuf == 0) { + + *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; + continue; + } + + /* + * If we find an active port with a different flow + * control mode than the first one, we return a value + * that indicates that the mode is indeterminated. + */ + if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) { + + *pBuf = SK_LSPEED_INDETERMINATED; + } + break; + + case OID_SKGE_SPEED_STATUS: + /* Check if it is the first active port */ + if (*pBuf == 0) { + + *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; + continue; + } + + /* + * If we find an active port with a different flow + * control status than the first one, we return a + * value that indicates that the status is + * indeterminated. + */ + if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) { + + *pBuf = SK_LSPEED_STAT_INDETERMINATED; + } + break; } } @@ -6760,6 +6625,17 @@ case OID_SKGE_PHY_OPERATION_STATUS: *pBuf = SK_MS_STAT_INDETERMINATED; break; + case OID_SKGE_SPEED_CAP: + *pBuf = SK_LSPEED_CAP_INDETERMINATED; + break; + + case OID_SKGE_SPEED_MODE: + *pBuf = SK_LSPEED_INDETERMINATED; + break; + + case OID_SKGE_SPEED_STATUS: + *pBuf = SK_LSPEED_STAT_INDETERMINATED; + break; } } } @@ -6779,8 +6655,7 @@ * Returns: * Link status of physical port */ - -static SK_U8 CalculateLinkStatus( +PNMI_STATIC SK_U8 CalculateLinkStatus( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ unsigned int PhysPortIndex) /* Physical port index */ @@ -6820,8 +6695,7 @@ * Returns: * The link mode status */ - -static SK_U8 CalculateLinkModeStatus( +PNMI_STATIC SK_U8 CalculateLinkModeStatus( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ unsigned int PhysPortIndex) /* Physical port index */ @@ -6869,8 +6743,7 @@ * SK_PNMI_ERR_OK Task successfully performed. * SK_PNMI_ERR_GENERAL Something went wrong. */ - -static int GetVpdKeyArr( +PNMI_STATIC int GetVpdKeyArr( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ char *pKeyArr, /* Ptr KeyArray */ @@ -6966,8 +6839,7 @@ * SK_PNMI_ERR_OK Task successfully performed. * SK_PNMI_ERR_GENERAL Something went wrong. */ - -static int SirqUpdate( +PNMI_STATIC int SirqUpdate( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC) /* IO context handle */ { @@ -7006,8 +6878,7 @@ * SK_PNMI_ERR_OK Task successfully performed. * SK_PNMI_ERR_GENERAL Something went wrong. */ - -static int RlmtUpdate( +PNMI_STATIC int RlmtUpdate( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ @@ -7042,24 +6913,20 @@ * * Description: * The XMAC holds its statistic internally. To obtain the current - * values we must send a command so that the statistic data will - * be written to a predefined memory area on the adapter. + * values we send a command so that the statistic data will + * be written to apredefined memory area on the adapter. * * Returns: * SK_PNMI_ERR_OK Task successfully performed. * SK_PNMI_ERR_GENERAL Something went wrong. */ - -static int MacUpdate( +PNMI_STATIC int MacUpdate( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ unsigned int FirstMac, /* Index of the first Mac to be updated */ unsigned int LastMac) /* Index of the last Mac to be updated */ { unsigned int MacIndex; - SK_U16 StatReg; - unsigned int WaitIndex; - /* * Were the statistics already updated during the @@ -7070,31 +6937,21 @@ return (SK_PNMI_ERR_OK); } - /* Send an update command to all XMACs specified */ + /* Send an update command to all MACs specified */ for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { - StatReg = XM_SC_SNP_TXC | XM_SC_SNP_RXC; - XM_OUT16(IoC, MacIndex, XM_STAT_CMD, StatReg); - /* - * It is an auto-clearing register. If the command bits - * went to zero again, the statistics are transfered. - * Normally the command should be executed immediately. - * But just to be sure we execute a loop. + * 2002-09-13 pweber: Freeze the current sw counters. + * (That should be done as close as + * possible to the update of the + * hw counters) */ - for (WaitIndex = 0; WaitIndex < 10; WaitIndex ++) { - - XM_IN16(IoC, MacIndex, XM_STAT_CMD, &StatReg); - if ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) == - 0) { - - break; - } + if (pAC->GIni.GIMacType == SK_MAC_XMAC) { + pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; } - if (WaitIndex == 10 ) { - - SK_ERR_LOG(pAC, SK_ERRCL_HW, SK_PNMI_ERR050, - SK_PNMI_ERR050MSG); + + /* 2002-09-13 pweber: Update the hw counter */ + if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { return (SK_PNMI_ERR_GENERAL); } @@ -7119,8 +6976,7 @@ * Returns: * Requested statistic value */ - -static SK_U64 GetStatVal( +PNMI_STATIC SK_U64 GetStatVal( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ unsigned int LogPortIndex, /* Index of the logical Port to be processed */ @@ -7129,16 +6985,15 @@ { unsigned int PhysPortIndex; unsigned int PhysPortMax; - SK_U64 Val = 0; + SK_U64 Val = 0; - if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ PhysPortIndex = NetIndex; Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } /* end of dual net mode */ - - else { /* single net mode */ + } + else { /* Single Net mode */ if (LogPortIndex == 0) { @@ -7163,7 +7018,7 @@ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); } - } /* end of single net mode */ + } return (Val); } @@ -7183,52 +7038,261 @@ * Returns: * Counter value */ - -static SK_U64 GetPhysStatVal( +PNMI_STATIC SK_U64 GetPhysStatVal( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ unsigned int PhysPortIndex, /* Index of the logical Port to be processed */ unsigned int StatIndex) /* Index to statistic value */ { - SK_U64 Val = 0; - SK_U32 LowVal; - SK_U32 HighVal; - + SK_U64 Val = 0; + SK_U32 LowVal = 0; + SK_U32 HighVal = 0; + SK_U16 Word; + int MacType; + + SK_PNMI_PORT *pPnmiPrt; + SK_GEMACFUNC *pFnMac; + + MacType = pAC->GIni.GIMacType; + + /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + if (pAC->GIni.GIMacType == SK_MAC_XMAC) { + pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; + } + else { + pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex]; + } + + pFnMac = &pAC->GIni.GIFunc; switch (StatIndex) { - - case SK_PNMI_HTX_OCTET: - XM_IN32(IoC, PhysPortIndex, XM_TXO_OK_LO, &LowVal); - XM_IN32(IoC, PhysPortIndex, XM_TXO_OK_HI, &HighVal); + case SK_PNMI_HTX: + case SK_PNMI_HRX: + /* Not supported by GMAC */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; break; + case SK_PNMI_HTX_OCTET: case SK_PNMI_HRX_OCTET: - XM_IN32(IoC, PhysPortIndex, XM_RXO_OK_LO, &LowVal); - XM_IN32(IoC, PhysPortIndex, XM_RXO_OK_HI, &HighVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &HighVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex + 1][MacType].Reg, + &LowVal); break; - case SK_PNMI_HTX_OCTETLOW: - case SK_PNMI_HRX_OCTETLOW: - return (Val); + case SK_PNMI_HTX_BURST: + case SK_PNMI_HTX_EXCESS_DEF: + case SK_PNMI_HTX_CARRIER: + /* Not supported by GMAC */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } - case SK_PNMI_HTX_SYNC: - LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex].StatSyncCts; - HighVal = (SK_U32) - (pAC->Pnmi.Port[PhysPortIndex].StatSyncCts >> 32); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; break; - case SK_PNMI_HTX_SYNC_OCTET: - LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex]. - StatSyncOctetsCts; - HighVal = (SK_U32) - (pAC->Pnmi.Port[PhysPortIndex].StatSyncOctetsCts >> - 32); + case SK_PNMI_HTX_MACC: + /* GMAC only supports PAUSE MAC control frames */ + if (MacType == SK_MAC_GMAC) { + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC); + + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HTX_COL: + case SK_PNMI_HRX_UNDERSIZE: + /* Not supported by XMAC */ + if (MacType == SK_MAC_XMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + + + case SK_PNMI_HTX_DEFFERAL: + /* Not supported by GMAC */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } + + /* + * XMAC counts frames with deferred transmission + * even in full-duplex mode. + * + * In full-duplex mode the counter remains constant! + */ + if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || + (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) { + + LowVal = 0; + HighVal = 0; + } + else { + /* Otherwise get contents of hardware register. */ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + } + break; + + case SK_PNMI_HRX_BADOCTET: + /* Not supported by XMAC */ + if (MacType == SK_MAC_XMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &HighVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex + 1][MacType].Reg, + &LowVal); break; + case SK_PNMI_HTX_OCTETLOW: + case SK_PNMI_HRX_OCTETLOW: + case SK_PNMI_HRX_BADOCTETLOW: + return (Val); + case SK_PNMI_HRX_LONGFRAMES: - LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts; - HighVal = (SK_U32) - (pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts >> 32); + /* For XMAC the SW counter is managed by PNMI */ + if (MacType == SK_MAC_XMAC) { + return (pPnmiPrt->StatRxLongFrameCts); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HRX_TOO_LONG: + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + + switch (MacType) { + case SK_MAC_GMAC: + /* For GMAC the SW counter is additionally managed by PNMI */ + Val += pPnmiPrt->StatRxFrameTooLongCts; + break; + + case SK_MAC_XMAC: + /* + * Frames longer than IEEE 802.3 frame max size are counted + * by XMAC in frame_too_long counter even reception of long + * frames was enabled and the frame was correct. + * So correct the value by subtracting RxLongFrame counter. + */ + Val -= pPnmiPrt->StatRxLongFrameCts; + break; + + default: + break; + } + + LowVal = (SK_U32)Val; + HighVal = (SK_U32)(Val >> 32); + break; + + case SK_PNMI_HRX_SHORTS: + /* Not supported by GMAC */ + if (MacType == SK_MAC_GMAC) { + /* GM_RXE_FRAG?? */ + return (Val); + } + + /* + * XMAC counts short frame errors even if link down (#10620) + * + * If link-down the counter remains constant + */ + if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { + + /* Otherwise get incremental difference */ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + Val -= pPnmiPrt->RxShortZeroMark; + + LowVal = (SK_U32)Val; + HighVal = (SK_U32)(Val >> 32); + } + break; + + case SK_PNMI_HRX_MACC: + case SK_PNMI_HRX_MACC_UNKWN: + case SK_PNMI_HRX_BURST: + case SK_PNMI_HRX_MISSED: + case SK_PNMI_HRX_FRAMING: + case SK_PNMI_HRX_CARRIER: + case SK_PNMI_HRX_IRLENGTH: + case SK_PNMI_HRX_SYMBOL: + case SK_PNMI_HRX_CEXT: + /* Not supported by GMAC */ + if (MacType == SK_MAC_GMAC) { + /* GM_RXE_FRAG?? */ + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HRX_PMACC_ERR: + /* For GMAC the SW counter is managed by PNMI */ + if (MacType == SK_MAC_GMAC) { + return (pPnmiPrt->StatRxPMaccErr); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + /* SW counter managed by PNMI */ + case SK_PNMI_HTX_SYNC: + LowVal = (SK_U32)pPnmiPrt->StatSyncCts; + HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32); + break; + + /* SW counter managed by PNMI */ + case SK_PNMI_HTX_SYNC_OCTET: + LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts; + HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32); break; case SK_PNMI_HRX_FCS: @@ -7240,30 +7304,33 @@ /* do not read while not initialized (PHY_READ hangs!)*/ if (pAC->GIni.GP[PhysPortIndex].PState) { PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex], - PhysPortIndex, PHY_BCOM_RE_CTR, - &LowVal); - } - else { - LowVal = 0; + PhysPortIndex, PHY_BCOM_RE_CTR, + &Word); + + LowVal = Word; } - HighVal = pAC->Pnmi.Port[PhysPortIndex].CounterHigh[StatIndex]; + HighVal = pPnmiPrt->CounterHigh[StatIndex]; } else { - XM_IN32(IoC, PhysPortIndex, - StatAddress[StatIndex].Param, &LowVal); - HighVal = pAC->Pnmi.Port[PhysPortIndex].CounterHigh[StatIndex]; + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; } + break; + default: - XM_IN32(IoC, PhysPortIndex, StatAddress[StatIndex].Param, - &LowVal); - HighVal = pAC->Pnmi.Port[PhysPortIndex].CounterHigh[StatIndex]; + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; break; } Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); /* Correct value because of possible XMAC reset. XMAC Errata #2 */ - Val += pAC->Pnmi.Port[PhysPortIndex].CounterOffset[StatIndex]; + Val += pPnmiPrt->CounterOffset[StatIndex]; return (Val); } @@ -7279,8 +7346,7 @@ * Returns: * Nothing */ - -static void ResetCounter( +PNMI_STATIC void ResetCounter( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 NetIndex) @@ -7305,7 +7371,8 @@ /* Notify CSUM module */ #ifdef SK_USE_CSUM - EventParam.Para64 = (SK_U64)(-1); + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, EventParam); #endif @@ -7314,11 +7381,7 @@ for (PhysPortIndex = 0; PhysPortIndex < (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { - XM_OUT16(IoC, PhysPortIndex, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); - /* Clear two times according to Errata #3 */ - XM_OUT16(IoC, PhysPortIndex, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); + (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex); SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh, 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh)); @@ -7333,6 +7396,12 @@ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[ PhysPortIndex].StatRxLongFrameCts)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].StatRxFrameTooLongCts)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].StatRxPMaccErr)); } /* @@ -7373,8 +7442,7 @@ * Returns: * A pointer to the trap entry */ - -static char* GetTrapEntry( +PNMI_STATIC char* GetTrapEntry( SK_AC *pAC, /* Pointer to adapter context */ SK_U32 TrapId, /* SNMP ID of the trap */ unsigned int Size) /* Space needed for trap entry */ @@ -7399,11 +7467,11 @@ if (Beg >= Size) { NeededSpace = Size; - Wrap = FALSE; + Wrap = SK_FALSE; } else { NeededSpace = Beg + Size; - Wrap = TRUE; + Wrap = SK_TRUE; } /* @@ -7479,8 +7547,7 @@ * Returns: * Nothing */ - -static void CopyTrapQueue( +PNMI_STATIC void CopyTrapQueue( SK_AC *pAC, /* Pointer to adapter context */ char *pDstBuf) /* Buffer to which the queued traps will be copied */ { @@ -7523,8 +7590,7 @@ * Returns: * Nothing */ - -static void GetTrapQueueLen( +PNMI_STATIC void GetTrapQueueLen( SK_AC *pAC, /* Pointer to adapter context */ unsigned int *pLen, /* Length in Bytes of all queued traps */ unsigned int *pEntries) /* Returns number of trapes stored in queue */ @@ -7566,8 +7632,7 @@ * Returns: * Nothing */ - -static void QueueSimpleTrap( +PNMI_STATIC void QueueSimpleTrap( SK_AC *pAC, /* Pointer to adapter context */ SK_U32 TrapId) /* Type of sensor trap */ { @@ -7585,8 +7650,7 @@ * Returns: * Nothing */ - -static void QueueSensorTrap( +PNMI_STATIC void QueueSensorTrap( SK_AC *pAC, /* Pointer to adapter context */ SK_U32 TrapId, /* Type of sensor trap */ unsigned int SensorIndex) /* Index of sensor which caused the trap */ @@ -7641,8 +7705,7 @@ * Returns: * Nothing */ - -static void QueueRlmtNewMacTrap( +PNMI_STATIC void QueueRlmtNewMacTrap( SK_AC *pAC, /* Pointer to adapter context */ unsigned int ActiveMac) /* Index (0..n) of the currently active port */ { @@ -7669,8 +7732,7 @@ * Returns: * Nothing */ - -static void QueueRlmtPortTrap( +PNMI_STATIC void QueueRlmtPortTrap( SK_AC *pAC, /* Pointer to adapter context */ SK_U32 TrapId, /* Type of RLMT port trap */ unsigned int PortIndex) /* Index of the port, which changed its state */ @@ -7697,8 +7759,7 @@ * Returns: * Nothing */ - -static void CopyMac( +PNMI_STATIC void CopyMac( char *pDst, /* Pointer to destination buffer */ SK_MAC_ADDR *pMac) /* Pointer of Source */ { @@ -7710,3 +7771,536 @@ *(pDst + i) = pMac->a[i]; } } + + +#ifdef SK_POWER_MGMT +/***************************************************************************** + * + * PowerManagement - OID handler function of PowerManagement OIDs + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ + +PNMI_STATIC int PowerManagement( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* Get/PreSet/Set action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer to which to mgmt data will be retrieved */ +unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +{ + + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + + /* + * Check instance. We only handle single instance variables + */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* + * Perform action + */ + if (Action == SK_PNMI_GET) { + + /* + * Check length + */ + switch (Id) { + + case OID_PNP_CAPABILITIES: + if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { + + *pLen = sizeof(SK_PNP_CAPABILITIES); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_PNP_QUERY_POWER: + case OID_PNP_ENABLE_WAKE_UP: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_PNP_SET_POWER: + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, + SK_PNMI_ERR040MSG); + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Get value + */ + switch (Id) { + + case OID_PNP_CAPABILITIES: + RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen); + break; + + case OID_PNP_QUERY_POWER: + /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests + the miniport to indicate whether it can transition its NIC + to the low-power state. + A miniport driver must always return NDIS_STATUS_SUCCESS + to a query of OID_PNP_QUERY_POWER. */ + RetCode = SK_PNMI_ERR_OK; + break; + + /* NDIS handles these OIDs as write-only. + * So in case of get action the buffer with written length = 0 + * is returned + */ + case OID_PNP_SET_POWER: + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + *pLen = 0; + RetCode = SK_PNMI_ERR_OK; + break; + + case OID_PNP_ENABLE_WAKE_UP: + RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen); + break; + + default: + RetCode = SK_PNMI_ERR_GENERAL; + break; + } + + return (RetCode); + } + + /* + * From here SET or PRESET action. Check if the passed + * buffer length is plausible. + */ + switch (Id) { + case OID_PNP_SET_POWER: + case OID_PNP_ENABLE_WAKE_UP: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + if (*pLen != sizeof(SK_U32)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + break; + + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* + * Perform preset or set + */ + + /* POWER module does not support PRESET action */ + if (Action == SK_PNMI_PRESET) { + return (SK_PNMI_ERR_OK); + } + + switch (Id) { + case OID_PNP_SET_POWER: + RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen); + break; + + case OID_PNP_ADD_WAKE_UP_PATTERN: + RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen); + break; + + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen); + break; + + case OID_PNP_ENABLE_WAKE_UP: + RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen); + break; + + default: + RetCode = SK_PNMI_ERR_GENERAL; + } + + return (RetCode); +} +#endif /* SK_POWER_MGMT */ + + +/***************************************************************************** + * + * Vct - OID handler function of OIDs + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was performed successfully. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter). + * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed. + * + */ + +PNMI_STATIC int Vct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* Get/PreSet/Set action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer to which the mgmt data will be copied */ +unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctBackupData; + SK_U32 LogPortMax; + SK_U32 PhysPortMax; + SK_U32 PhysPortIndex; + SK_U32 Limit; + SK_U32 Offset; + + SK_BOOL Link; + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + int i; + SK_EVPARA Para; + SK_U32 CableLength; + + /* + * Calculate the port indexes from the instance. + */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + /* Dual net mode? */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + LogPortMax--; + } + + if ((Instance != (SK_U32) (-1))) { + /* Check instance range. */ + if ((Instance < 2) || (Instance > LogPortMax)) { + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + } + else { + PhysPortIndex = Instance - 2; + } + Limit = PhysPortIndex + 1; + } + else { /* + * Instance == (SK_U32) (-1), get all Instances of that OID. + * + * Not implemented yet. May be used in future releases. + */ + PhysPortIndex = 0; + Limit = PhysPortMax; + } + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + if (pPrt->PHWLinkUp) { + Link = SK_TRUE; + } + else { + Link = SK_FALSE; + } + + /* + * Check MAC type. + */ + if (pPrt->PhyType != SK_PHY_MARV_COPPER) { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Initialize backup data pointer. */ + pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; + + /* + * Check action type. + */ + if (Action == SK_PNMI_GET) { + /* + * Check length. + */ + switch (Id) { + + case OID_SKGE_VCT_GET: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_VCT_STATUS: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Get value. + */ + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex++) { + switch (Id) { + + case OID_SKGE_VCT_GET: + if ((Link == SK_FALSE) && + (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); + if (RetCode == 0) { + pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; + pAC->Pnmi.VctStatus[PhysPortIndex] |= + (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); + + /* Copy results for later use to PNMI struct. */ + for (i = 0; i < 4; i++) { + if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { + if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) { + pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; + } + } + if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) { + CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); + } + else { + CableLength = 0; + } + pVctBackupData->PMdiPairLen[i] = CableLength; + pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; + } + + Para.Para32[0] = PhysPortIndex; + Para.Para32[1] = -1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); + SkEventDispatcher(pAC, IoC); + } + else { + ; /* VCT test is running. */ + } + } + + /* Get all results. */ + CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); + Offset += sizeof(SK_U8); + *(pBuf + Offset) = pPrt->PCableLen; + Offset += sizeof(SK_U8); + for (i = 0; i < 4; i++) { + SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]); + Offset += sizeof(SK_U32); + } + for (i = 0; i < 4; i++) { + *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i]; + Offset += sizeof(SK_U8); + } + + RetCode = SK_PNMI_ERR_OK; + break; + + case OID_SKGE_VCT_STATUS: + CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); + Offset += sizeof(SK_U8); + RetCode = SK_PNMI_ERR_OK; + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } /* for */ + *pLen = Offset; + return (RetCode); + + } /* if SK_PNMI_GET */ + + /* + * From here SET or PRESET action. Check if the passed + * buffer length is plausible. + */ + + /* + * Check length. + */ + switch (Id) { + case OID_SKGE_VCT_SET: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Perform preset or set. + */ + + /* VCT does not support PRESET action. */ + if (Action == SK_PNMI_PRESET) { + return (SK_PNMI_ERR_OK); + } + + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex++) { + switch (Id) { + case OID_SKGE_VCT_SET: /* Start VCT test. */ + if (Link == SK_FALSE) { + SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST); + + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE); + if (RetCode == 0) { /* RetCode: 0 => Start! */ + pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING; + pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA; + pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK; + + /* + * Start VCT timer counter. + */ + SK_MEMSET((char *) &Para, 0, sizeof(Para)); + Para.Para32[0] = PhysPortIndex; + Para.Para32[1] = -1; + SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, + 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } + else { /* RetCode: 2 => Running! */ + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } + } + else { /* RetCode: 4 => Link! */ + RetCode = 4; + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } + Offset += sizeof(SK_U32); + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } /* for */ + *pLen = Offset; + return (RetCode); + +} /* Vct */ + + +PNMI_STATIC void CheckVctStatus( +SK_AC *pAC, +SK_IOC IoC, +char *pBuf, +SK_U32 Offset, +SK_U32 PhysPortIndex) +{ + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctData; + SK_U32 RetCode; + SK_U8 LinkSpeedUsed; + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + + pVctData = (SK_PNMI_VCT *) (pBuf + Offset); + pVctData->VctStatus = SK_PNMI_VCT_NONE; + + if (!pPrt->PHWLinkUp) { + + /* Was a VCT test ever made before? */ + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { + if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) { + pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; + } + else { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; + } + } + + /* Check VCT test status. */ + RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE); + if (RetCode == 2) { /* VCT test is running. */ + pVctData->VctStatus |= SK_PNMI_VCT_RUNNING; + } + else { /* VCT data was copied to pAC here. Check PENDING state. */ + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; + } + } + + if (pPrt->PCableLen != 0xff) { /* Old DSP value. */ + pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA; + } + } + else { + + /* Was a VCT test ever made before? */ + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { + pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA; + pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; + } + + /* DSP only valid in 100/1000 modes. */ + LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; + if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; + } + } + +} /* CheckVctStatus */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skgesirq.c linux.21pre4-ac6/drivers/net/sk98lin/skgesirq.c --- linux.21pre4/drivers/net/sk98lin/skgesirq.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skgesirq.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skgesirq.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.65 $ - * Date: $Date: 2001/02/23 13:41:51 $ + * Version: $Revision: 1.81 $ + * Date: $Date: 2002/12/05 10:49:51 $ * Purpose: Special IRQ module * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2000 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,89 @@ * History: * * $Log: skgesirq.c,v $ + * Revision 1.81 2002/12/05 10:49:51 rschmidt + * Fixed missing Link Down Event for fiber (Bug Id #10768) + * Added reading of cable length when link is up + * Removed testing of unused error bits in PHY ISR + * Editorial changes. + * + * Revision 1.80 2002/11/12 17:15:21 rschmidt + * Replaced SkPnmiGetVar() by ...MacStatistic() in SkMacParity(). + * Editorial changes. + * + * Revision 1.79 2002/10/14 15:14:51 rschmidt + * Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in + * SkMacParity() depending on GIChipRev (HW-Bug #8). + * Added error messages for GPHY Auto-Negotiation Error and + * FIFO Overflow/Underrun in SkPhyIsrGmac(). + * Editorial changes. + * + * Revision 1.78 2002/10/10 15:54:29 mkarl + * changes for PLinkSpeedUsed + * + * Revision 1.77 2002/09/12 08:58:51 rwahl + * Retrieve counters needed for XMAC errata workarounds directly because + * PNMI returns corrected counter values (e.g. #10620). + * + * Revision 1.76 2002/08/16 15:21:54 rschmidt + * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. + * Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros. + * Editorial changes. + * + * Revision 1.75 2002/08/12 13:50:47 rschmidt + * Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in + * SkMacParity() by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE (HW-Bug #8). + * Added clearing of IS_IRQ_TIST_OV and IS_IRQ_SENSOR in SkGeHwErr(). + * Corrected handling of Link Up and Auto-Negotiation Over for GPHY. + * in SkGePortCheckUpGmac(). + * Editorial changes. + * + * Revision 1.74 2002/08/08 16:17:04 rschmidt + * Added PhyType check for SK_HWEV_SET_ROLE event (copper only) + * Changed Link Up check reading PHY Specific Status (YUKON) + * Editorial changes + * + * Revision 1.73 2002/07/15 18:36:53 rwahl + * Editorial changes. + * + * Revision 1.72 2002/07/15 15:46:26 rschmidt + * Added new event: SK_HWEV_SET_SPEED + * Editorial changes + * + * Revision 1.71 2002/06/10 09:34:19 rschmidt + * Editorial changes + * + * Revision 1.70 2002/06/05 08:29:18 rschmidt + * SkXmRxTxEnable() replaced by SkMacRxTxEnable(). + * Editorial changes. + * + * Revision 1.69 2002/04/25 13:03:49 rschmidt + * Changes for handling YUKON. + * Use of #ifdef OTHER_PHY to eliminate code for unused Phy types. + * Replaced all XMAC-access macros by functions: SkMacRxTxDisable(), + * SkMacIrqDisable(). + * Added handling for GMAC FIFO in SkMacParity(). + * Replaced all SkXm...() functions with SkMac...() to handle also + * YUKON's GMAC. + * Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced + * by functions SkXmPhyRead(), SkXmPhyWrite(). + * Disabling all PHY interrupts moved to SkMacIrqDisable(). + * Added handling for GPHY IRQ in SkGeSirqIsr(). + * Removed status parameter from MAC IRQ handler SkMacIrq(). + * Added SkGePortCheckUpGmac(), SkPhyIsrGmac() for GMAC. + * Editorial changes + * + * Revision 1.68 2002/02/26 15:24:53 rwahl + * Fix: no link with manual configuration (#10673). The previous fix for + * #10639 was removed. So for RLMT mode = CLS the RLMT may switch to + * misconfigured port. It should not occur for the other RLMT modes. + * + * Revision 1.67 2001/11/20 09:19:58 rwahl + * Reworked bugfix #10639 (no dependency to RLMT mode). + * + * Revision 1.66 2001/10/26 07:52:53 afischer + * Port switching bug in `check local link` mode + * * Revision 1.65 2001/02/23 13:41:51 gklug * fix: PHYS2INST should be used correctly for Dual Net operation * chg: do no longer work with older PNMI @@ -254,49 +337,53 @@ * * In the ISR of the driver the bits for frame transmission complete and * for receive complete are checked and handled by the driver itself. - * The bits of the slow path mask are checked after this and then the - * entry into the so-called "slow path" is prepared. It is an implemetors + * The bits of the slow path mask are checked after that and then the + * entry into the so-called "slow path" is prepared. It is an implementors * decision whether this is executed directly or just scheduled by - * disabling the mask. In the interrupt service routine events may be + * disabling the mask. In the interrupt service routine some events may be * generated, so it would be a good idea to call the EventDispatcher * right after this ISR. * - * The Interrupt service register of the adapter is NOT read by this - * module. SO if the drivers implemetor needs a while loop around the - * slow data paths Interrupt bits, he needs to call the SkGeIsr() for + * The Interrupt source register of the adapter is NOT read by this module. + * SO if the drivers implementor needs a while loop around the + * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for * each loop entered. * - * However, the XMAC Interrupt status registers are read in a while loop. + * However, the MAC Interrupt status registers are read in a while loop. * */ - + static const char SysKonnectFileId[] = - "$Id: skgesirq.c,v 1.65 2001/02/23 13:41:51 gklug Exp $" ; + "$Id: skgesirq.c,v 1.81 2002/12/05 10:49:51 rschmidt Exp $" ; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skgepnmi.h" /* PNMI Definitions */ #include "h/skrlmt.h" /* RLMT Definitions */ -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ +#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */ /* local function prototypes */ static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int); static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int); +static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int); +static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16); +static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16); +#ifdef OTHER_PHY static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int); static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int); -static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16); static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16); +#endif /* OTHER_PHY */ /* - * Define an array of RX counter which are checked - * in AutoSense mode to check whether a link is not able to autonegotiate. + * array of Rx counter from XMAC which are checked + * in AutoSense mode to check whether a link is not able to auto-negotiate. */ -static const SK_U32 SkGeRxOids[]= { - OID_SKGE_STAT_RX_64, - OID_SKGE_STAT_RX_127, - OID_SKGE_STAT_RX_255, - OID_SKGE_STAT_RX_511, - OID_SKGE_STAT_RX_1023, - OID_SKGE_STAT_RX_MAX, +static const SK_U16 SkGeRxRegs[]= { + XM_RXF_64B, + XM_RXF_127B, + XM_RXF_255B, + XM_RXF_511B, + XM_RXF_1023B, + XM_RXF_MAX_SZ } ; #ifdef __C2MAN__ @@ -310,7 +397,7 @@ {} #endif -/* Define return codes of SkGePortCheckUp and CheckShort. */ +/* Define return codes of SkGePortCheckUp and CheckShort */ #define SK_HW_PS_NONE 0 /* No action needed */ #define SK_HW_PS_RESTART 1 /* Restart needed */ #define SK_HW_PS_LINK 2 /* Link Up actions needed */ @@ -320,17 +407,17 @@ * SkHWInitDefSense() - Default Autosensing mode initialization * * Description: - * This function handles the Hardware link down signal + * This function sets the PLinkMode for HWInit * * Note: * */ -void SkHWInitDefSense( +static void SkHWInitDefSense( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ +int Port) /* Port Index (MAC_1 + n) */ { - SK_GEPORT *pPrt; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ pPrt = &pAC->GIni.GP[Port]; @@ -343,8 +430,7 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("AutoSensing: First mode %d on Port %d\n", - (int)SK_LMODE_AUTOFULL, - Port)); + (int)SK_LMODE_AUTOFULL, Port)); pPrt->PLinkMode = SK_LMODE_AUTOFULL; @@ -362,12 +448,12 @@ * Note: * */ -SK_U8 SkHWSenseGetNext( +SK_U8 SkHWSenseGetNext( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ +int Port) /* Port Index (MAC_1 + n) */ { - SK_GEPORT *pPrt; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ pPrt = &pAC->GIni.GP[Port]; @@ -375,16 +461,16 @@ if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) { /* Leave all as configured */ - return (pPrt->PLinkModeConf); + return(pPrt->PLinkModeConf); } if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) { /* Return next mode AUTOBOTH */ - return (SK_LMODE_AUTOBOTH); + return(SK_LMODE_AUTOBOTH); } /* Return default autofull */ - return (SK_LMODE_AUTOFULL); + return(SK_LMODE_AUTOFULL); } /* SkHWSenseGetNext */ @@ -398,13 +484,13 @@ * Note: * */ -void SkHWSenseSetNext( +void SkHWSenseSetNext( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ +int Port, /* Port Index (MAC_1 + n) */ SK_U8 NewMode) /* New Mode to be written in sense mode */ { - SK_GEPORT *pPrt; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ pPrt = &pAC->GIni.GP[Port]; @@ -415,7 +501,9 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("AutoSensing: next mode %d on Port %d\n", (int)NewMode, Port)); + ("AutoSensing: next mode %d on Port %d\n", + (int)NewMode, Port)); + pPrt->PLinkMode = NewMode; return; @@ -432,73 +520,47 @@ * Note: * */ -void SkHWLinkDown( +void SkHWLinkDown( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { - SK_GEPORT *pPrt; - SK_U16 Word; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ pPrt = &pAC->GIni.GP[Port]; - /* Disable all XMAC interrupts. */ - XM_OUT16(IoC, Port, XM_IMSK, 0xffff); + /* Disable all MAC interrupts */ + SkMacIrqDisable(pAC, IoC, Port); - /* Disable Receiver and Transmitter. */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); + /* Disable Receiver and Transmitter */ + SkMacRxTxDisable(pAC, IoC, Port); - /* Disable all PHY interrupts. */ - switch (pPrt->PhyType) { - case SK_PHY_BCOM: - /* Make sure that PHY is initialized. */ - if (pAC->GIni.GP[Port].PState) { - /* NOT allowed if BCOM is in RESET state */ - /* Workaround BCOM Errata (#10523) all BCom. */ - /* Disable Power Management if link is down. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &Word); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, - Word | PHY_B_AC_DIS_PM); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 0xffff); - } - break; - case SK_PHY_LONE: - PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 0x0); - break; - case SK_PHY_NAT: - /* todo: National - PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, 0xffff); */ - break; - } - - /* Init default sense mode. */ + /* Init default sense mode */ SkHWInitDefSense(pAC, IoC, Port); if (!pPrt->PHWLinkUp) { return; - } + } - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link down Port %d\n", Port)); - /* Set Link to DOWN. */ + /* Set Link to DOWN */ pPrt->PHWLinkUp = SK_FALSE; /* Reset Port stati */ pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED; - /* - * Reinit Phy especially when the AutoSense default is set now. - */ - SkXmInitPhy(pAC, IoC, Port, SK_FALSE); + /* Re-init Phy especially when the AutoSense default is set now */ + SkMacInitPhy(pAC, IoC, Port, SK_FALSE); - /* GP0: used for workaround of Rev. C Errata 2. */ + /* GP0: used for workaround of Rev. C Errata 2 */ - /* Do NOT signal to RLMT. */ + /* Do NOT signal to RLMT */ - /* Do NOT start the timer here. */ + /* Do NOT start the timer here */ } /* SkHWLinkDown */ @@ -512,19 +574,19 @@ * Note: * */ -void SkHWLinkUp( +void SkHWLinkUp( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ +int Port) /* Port Index (MAC_1 + n) */ { - SK_GEPORT *pPrt; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ pPrt = &pAC->GIni.GP[Port]; if (pPrt->PHWLinkUp) { /* We do NOT need to proceed on active link */ return; - } + } pPrt->PHWLinkUp = SK_TRUE; pPrt->PAutoNegFail = SK_FALSE; @@ -533,11 +595,14 @@ if (pPrt->PLinkMode != SK_LMODE_AUTOHALF && pPrt->PLinkMode != SK_LMODE_AUTOFULL && pPrt->PLinkMode != SK_LMODE_AUTOBOTH) { - /* Link is up and no Autonegotiation should be done */ + /* Link is up and no Auto-negotiation should be done */ /* Configure Port */ + + /* link speed should be the configured one */ + pPrt->PLinkSpeedUsed = pPrt->PLinkSpeed; - /* Set Link Mode */ + /* Set Link Mode Status */ if (pPrt->PLinkMode == SK_LMODE_FULL) { pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL; } @@ -545,11 +610,11 @@ pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF; } - /* No flow control without autonegotiation */ + /* No flow control without auto-negotiation */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - /* RX/TX enable */ - SkXmRxTxEnable(pAC, IoC, Port); + /* enable Rx/Tx */ + SkMacRxTxEnable(pAC, IoC, Port); } } /* SkHWLinkUp */ @@ -559,29 +624,33 @@ * SkMacParity - does everything to handle MAC parity errors correctly * */ -static void SkMacParity( +static void SkMacParity( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* Port Index of the port failed */ +int Port) /* Port Index of the port failed */ { SK_EVPARA Para; SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U64 TxMax; /* TxMax Counter */ - unsigned Len; + SK_U32 TxMax; /* TxMax Counter */ pPrt = &pAC->GIni.GP[Port]; - /* Clear IRQ */ - SK_OUT16(IoC, MR_ADDR(Port,TX_MFF_CTRL1), MFF_CLR_PERR); + /* Clear IRQ Tx Parity Error */ + if (pAC->GIni.GIGenesis) { + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR); + } + else { + /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), + (SK_U8)((pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); + } if (pPrt->PCheckPar) { if (Port == MAC_1) { - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E016, - SKERR_SIRQ_E016MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG); } else { - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E017, - SKERR_SIRQ_E017MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG); } Para.Para64 = Port; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); @@ -592,11 +661,16 @@ } /* Check whether frames with a size of 1k were sent */ - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_MAX, (char *)&TxMax, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); - + if (pAC->GIni.GIGenesis) { + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, Port); + + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax); + } + else { + (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax); + } + if (TxMax > 0) { /* From now on check the parity */ pPrt->PCheckPar = SK_TRUE; @@ -612,7 +686,7 @@ * * Notes: */ -static void SkGeHwErr( +static void SkGeHwErr( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ SK_U32 HwStatus) /* Interrupt status word */ @@ -620,17 +694,19 @@ SK_EVPARA Para; SK_U16 Word; - if ((HwStatus & IS_IRQ_MST_ERR) || (HwStatus & IS_IRQ_STAT)) { - if (HwStatus & IS_IRQ_STAT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG); + if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) { + /* PCI Errors occured */ + if ((HwStatus & IS_IRQ_STAT) != 0) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG); } else { - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG); } /* Reset all bits in the PCI STATUS register */ - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); @@ -638,68 +714,82 @@ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); } - if (HwStatus & IS_NO_STAT_M1) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_1,RX_MFF_CTRL1), MFF_CLR_INSTAT); - } - - if (HwStatus & IS_NO_STAT_M2) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INSTAT); - } - - if (HwStatus & IS_NO_TIST_M1) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_1,RX_MFF_CTRL1), MFF_CLR_INTIST); + if (pAC->GIni.GIGenesis) { + if ((HwStatus & IS_NO_STAT_M1) != 0) { + /* Ignore it */ + /* This situation is also indicated in the descriptor */ + SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT); + } + + if ((HwStatus & IS_NO_STAT_M2) != 0) { + /* Ignore it */ + /* This situation is also indicated in the descriptor */ + SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT); + } + + if ((HwStatus & IS_NO_TIST_M1) != 0) { + /* Ignore it */ + /* This situation is also indicated in the descriptor */ + SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST); + } + + if ((HwStatus & IS_NO_TIST_M2) != 0) { + /* Ignore it */ + /* This situation is also indicated in the descriptor */ + SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST); + } } + else { /* YUKON */ + /* This is necessary only for Rx timing measurements */ + if ((HwStatus & IS_IRQ_TIST_OV) != 0) { + /* Clear Time Stamp Timer IRQ */ + SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ); + } - if (HwStatus & IS_NO_TIST_M2) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INTIST); + if ((HwStatus & IS_IRQ_SENSOR) != 0) { + /* Clear I2C IRQ */ + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); + } } - if (HwStatus & IS_RAM_RD_PAR) { + if ((HwStatus & IS_RAM_RD_PAR) != 0) { SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR); - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG); Para.Para64 = 0; SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); } - if (HwStatus & IS_RAM_WR_PAR) { + if ((HwStatus & IS_RAM_WR_PAR) != 0) { SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR); - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG); Para.Para64 = 0; SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); } - if (HwStatus & IS_M1_PAR_ERR) { + if ((HwStatus & IS_M1_PAR_ERR) != 0) { SkMacParity(pAC, IoC, MAC_1); } - if (HwStatus & IS_M2_PAR_ERR) { + if ((HwStatus & IS_M2_PAR_ERR) != 0) { SkMacParity(pAC, IoC, MAC_2); } - if (HwStatus & IS_R1_PAR_ERR) { + if ((HwStatus & IS_R1_PAR_ERR) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P); - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); Para.Para64 = MAC_1; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); Para.Para32[0] = MAC_1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - if (HwStatus & IS_R2_PAR_ERR) { + if ((HwStatus & IS_R2_PAR_ERR) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P); - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); Para.Para64 = MAC_2; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); Para.Para32[0] = MAC_2; @@ -716,126 +806,122 @@ * * Notes: */ -void SkGeSirqIsr( +void SkGeSirqIsr( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ SK_U32 Istatus) /* Interrupt status word */ { SK_EVPARA Para; - SK_U32 RegVal32; /* Read register Value */ - SK_U16 XmIsr; + SK_U32 RegVal32; /* Read register value */ + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + unsigned Len; + SK_U64 Octets; + SK_U16 PhyInt; + SK_U16 PhyIMsk; + int i; - if (Istatus & IS_HW_ERR) { + if ((Istatus & IS_HW_ERR) != 0) { + /* read the HW Error Interrupt source */ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); + SkGeHwErr(pAC, IoC, RegVal32); } /* * Packet Timeout interrupts */ - /* Check whether XMACs are correctly initialized */ - if ((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) && - !pAC->GIni.GP[MAC_1].PState) { - /* XMAC was not initialized but Packet timeout occured */ + /* Check whether MACs are correctly initialized */ + if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) && + pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) { + /* MAC 1 was not initialized but Packet timeout occured */ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004, SKERR_SIRQ_E004MSG); } - if ((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) && - !pAC->GIni.GP[MAC_2].PState) { - /* XMAC was not initialized but Packet timeout occured */ + if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) && + pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) { + /* MAC 2 was not initialized but Packet timeout occured */ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005, SKERR_SIRQ_E005MSG); } - if (Istatus & IS_PA_TO_RX1) { + if ((Istatus & IS_PA_TO_RX1) != 0) { /* Means network is filling us up */ SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002, SKERR_SIRQ_E002MSG); SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1); } - if (Istatus & IS_PA_TO_RX2) { + if ((Istatus & IS_PA_TO_RX2) != 0) { /* Means network is filling us up */ SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003, SKERR_SIRQ_E003MSG); SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2); } - if (Istatus & IS_PA_TO_TX1) { - unsigned int Len; - SK_U64 Octets; - SK_GEPORT *pPrt = &pAC->GIni.GP[0]; + if ((Istatus & IS_PA_TO_TX1) != 0) { + + pPrt = &pAC->GIni.GP[0]; /* May be a normal situation in a server with a slow network */ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1); /* - * workaround: if in half duplex mode, check for tx hangup. + * workaround: if in half duplex mode, check for Tx hangup. * Read number of TX'ed bytes, wait for 10 ms, then compare - * the number with current value. If nothing changed, we - * assume that tx is hanging and do a FIFO flush (see event - * routine). + * the number with current value. If nothing changed, we assume + * that Tx is hanging and do a FIFO flush (see event routine). */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && !pPrt->HalfDupTimerActive) { - /* + /* * many more pack. arb. timeouts may come in between, * we ignore those */ pPrt->HalfDupTimerActive = SK_TRUE; Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *) &Octets, + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0), pAC->Rlmt.Port[0].Net->NetNumber); + pPrt->LastOctets = Octets; + Para.Para32[0] = 0; - SkTimerStart(pAC, IoC, - &pPrt->HalfDupChkTimer, - SK_HALFDUP_CHK_TIME, - SKGE_HWAC, - SK_HWEV_HALFDUP_CHK, - Para); + SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, + SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); } } - if (Istatus & IS_PA_TO_TX2) { - unsigned int Len; - SK_U64 Octets; - SK_GEPORT *pPrt = &pAC->GIni.GP[1]; + if ((Istatus & IS_PA_TO_TX2) != 0) { + + pPrt = &pAC->GIni.GP[1]; /* May be a normal situation in a server with a slow network */ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2); - /* - * workaround: see above - */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && + /* workaround: see above */ + if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && !pPrt->HalfDupTimerActive) { pPrt->HalfDupTimerActive = SK_TRUE; Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *) &Octets, + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1), pAC->Rlmt.Port[1].Net->NetNumber); + pPrt->LastOctets = Octets; + Para.Para32[0] = 1; - SkTimerStart(pAC, IoC, - &pPrt->HalfDupChkTimer, - SK_HALFDUP_CHK_TIME, - SKGE_HWAC, - SK_HWEV_HALFDUP_CHK, - Para); + SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, + SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); } } - /* - * Check interrupts of the particular queues. - */ - if (Istatus & IS_R1_C) { + /* Check interrupts of the particular queues */ + if ((Istatus & IS_R1_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C); SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006, @@ -846,7 +932,7 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - if (Istatus & IS_R2_C) { + if ((Istatus & IS_R2_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C); SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007, @@ -857,7 +943,7 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - if (Istatus & IS_XS1_C) { + if ((Istatus & IS_XS1_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C); SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008, @@ -868,7 +954,7 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - if (Istatus & IS_XA1_C) { + if ((Istatus & IS_XA1_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C); SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009, @@ -879,7 +965,7 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - if (Istatus & IS_XS2_C) { + if ((Istatus & IS_XS2_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C); SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010, @@ -890,7 +976,7 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - if (Istatus & IS_XA2_C) { + if ((Istatus & IS_XA2_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C); SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011, @@ -901,58 +987,55 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - /* - * External reg interrupt. - */ - if (Istatus & IS_EXT_REG) { - SK_U16 PhyInt; - SK_U16 PhyIMsk; - int i; - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - /* Test IRQs from PHY. */ + /* External reg interrupt */ + if ((Istatus & IS_EXT_REG) != 0) { + /* Test IRQs from PHY */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + pPrt = &pAC->GIni.GP[i]; + + if (pPrt->PState == SK_PRT_RESET) { + continue; + } + switch (pPrt->PhyType) { + case SK_PHY_XMAC: break; + case SK_PHY_BCOM: - if (pPrt->PState) { - PHY_READ(IoC, pPrt, i, PHY_BCOM_INT_STAT, &PhyInt); - PHY_READ(IoC, pPrt, i, PHY_BCOM_INT_MASK, &PhyIMsk); + SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); + SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_MASK, &PhyIMsk); -#ifdef xDEBUG - if (PhyInt & PhyIMsk) { - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "SirqIsr - Stat: %x", - (void *)PhyInt, - (void *)NULL); - } -#endif /* DEBUG */ - - if (PhyInt & ~PhyIMsk) { - SK_DBG_MSG( - pAC, - SK_DBGMOD_HWM, - SK_DBGCAT_IRQ, - ("Port %d Bcom Int: %x Mask: %x\n", - i, PhyInt, PhyIMsk)); - SkPhyIsrBcom(pAC, IoC, i, PhyInt); - } + if ((PhyInt & ~PhyIMsk) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Port %d Bcom Int: 0x%04X Mask: 0x%04X\n", + i, PhyInt, PhyIMsk)); + SkPhyIsrBcom(pAC, IoC, i, PhyInt); + } + break; + + case SK_PHY_MARV_COPPER: + case SK_PHY_MARV_FIBER: + SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt); + SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_MASK, &PhyIMsk); + + if ((PhyInt & PhyIMsk) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Port %d Marv Int: 0x%04X Mask: 0x%04X\n", + i, PhyInt, PhyIMsk)); + SkPhyIsrGmac(pAC, IoC, i, PhyInt); } break; + +#ifdef OTHER_PHY case SK_PHY_LONE: - PHY_READ(IoC, pPrt, i, PHY_LONE_INT_STAT, &PhyInt); - PHY_READ(IoC, pPrt, i, PHY_LONE_INT_ENAB, &PhyIMsk); + SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); + SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_ENAB, &PhyIMsk); - if (PhyInt & PhyIMsk) { - SK_DBG_MSG( - pAC, - SK_DBGMOD_HWM, - SK_DBGCAT_IRQ, - ("Port %d Lone Int: %x Mask: %x\n", + if ((PhyInt & PhyIMsk) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Port %d Lone Int: %x Mask: %x\n", i, PhyInt, PhyIMsk)); SkPhyIsrLone(pAC, IoC, i, PhyInt); } @@ -960,18 +1043,17 @@ case SK_PHY_NAT: /* todo: National */ break; +#endif /* OTHER_PHY */ } } } - /* - * I2C Ready interrupt - */ - if (Istatus & IS_I2C_READY) { + /* I2C Ready interrupt */ + if ((Istatus & IS_I2C_READY) != 0) { SkI2cIsr(pAC, IoC); } - if (Istatus & IS_LNK_SYNC_M1) { + if ((Istatus & IS_LNK_SYNC_M1) != 0) { /* * We do NOT need the Link Sync interrupt, because it shows * us only a link going down. @@ -981,31 +1063,28 @@ } /* Check MAC after link sync counter */ - if (Istatus & IS_MAC1) { - XM_IN16(IoC, MAC_1, XM_ISRC, &XmIsr); - SkXmIrq(pAC, IoC, MAC_1, XmIsr); + if ((Istatus & IS_MAC1) != 0) { + /* IRQ from MAC 1 */ + SkMacIrq(pAC, IoC, MAC_1); } - if (Istatus & IS_LNK_SYNC_M2) { + if ((Istatus & IS_LNK_SYNC_M2) != 0) { /* * We do NOT need the Link Sync interrupt, because it shows * us only a link going down. */ /* clear interrupt */ - SK_OUT8(IoC, MR_ADDR(MAC_2,LNK_SYNC_CTRL), LED_CLR_IRQ); + SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ); } /* Check MAC after link sync counter */ - if (Istatus & IS_MAC2) { - XM_IN16(IoC, MAC_2, XM_ISRC, &XmIsr); - SkXmIrq(pAC, IoC, MAC_2, XmIsr); + if ((Istatus & IS_MAC2) != 0) { + /* IRQ from MAC 2 */ + SkMacIrq(pAC, IoC, MAC_2); } - /* - * Timer interrupt - * To be served last - */ - if (Istatus & IS_TIMINT) { + /* Timer interrupt (served last) */ + if ((Istatus & IS_TIMINT) != 0) { SkHwtIsr(pAC, IoC); } } /* SkGeSirqIsr */ @@ -1013,24 +1092,23 @@ /****************************************************************************** * - * SkGePortCheckShorts - Implementing of the Workaround Errata # 2 + * SkGePortCheckShorts - Implementing XMAC Workaround Errata # 2 * * return: * 0 o.k. nothing needed * 1 Restart needed on this port */ -int SkGePortCheckShorts( +static int SkGePortCheckShorts( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ { - SK_U64 Shorts; /* Short Event Counter */ - SK_U64 CheckShorts; /* Check value for Short Event Counter */ - SK_U64 RxCts; /* RX Counter (packets on network) */ - SK_U64 RxTmp; /* RX temp. Counter */ - SK_U64 FcsErrCts; /* FCS Error Counter */ + SK_U32 Shorts; /* Short Event Counter */ + SK_U32 CheckShorts; /* Check value for Short Event Counter */ + SK_U64 RxCts; /* Rx Counter (packets on network) */ + SK_U32 RxTmp; /* Rx temp. Counter */ + SK_U32 FcsErrCts; /* FCS Error Counter */ SK_GEPORT *pPrt; /* GIni Port struct pointer */ - unsigned Len; int Rtv; /* Return value */ int i; @@ -1039,48 +1117,35 @@ /* Default: no action */ Rtv = SK_HW_PS_NONE; - /* - * Extra precaution: check for short Event counter - */ - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *)&Shorts, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); + (void)SkXmUpdateStats(pAC, IoC, Port); + + /* Extra precaution: check for short Event counter */ + (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); /* - * Read RX counter (packets seen on the network and not neccesarily + * Read Rx counter (packets seen on the network and not necessarily * really received. */ - Len = sizeof(SK_U64); RxCts = 0; - for (i = 0; i < sizeof(SkGeRxOids)/sizeof(SK_U32); i++) { - SkPnmiGetVar(pAC, IoC, SkGeRxOids[i], (char *)&RxTmp, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); - RxCts += RxTmp; + for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { + (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); + RxCts += (SK_U64)RxTmp; } /* On default: check shorts against zero */ CheckShorts = 0; - /* - * Extra extra precaution on active links: - */ + /* Extra precaution on active links */ if (pPrt->PHWLinkUp) { - /* - * Reset Link Restart counter - */ + /* Reset Link Restart counter */ pPrt->PLinkResCt = 0; pPrt->PAutoNegTOCt = 0; /* If link is up check for 2 */ CheckShorts = 2; - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_FCS, - (char *)&FcsErrCts, &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); + (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts); if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN && @@ -1091,13 +1156,11 @@ * manual full/half duplex mode. */ if (RxCts == pPrt->PPrevRx) { - /* - * Nothing received - * restart link - */ + /* Nothing received, restart link */ pPrt->PPrevFcs = FcsErrCts; pPrt->PPrevShorts = Shorts; - return (SK_HW_PS_RESTART); + + return(SK_HW_PS_RESTART); } else { pPrt->PLipaAutoNeg = SK_LIPA_MANUAL; @@ -1118,7 +1181,7 @@ pPrt->PPrevFcs = FcsErrCts; pPrt->PPrevShorts = Shorts; - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } pPrt->PPrevFcs = FcsErrCts; @@ -1134,8 +1197,8 @@ pPrt->PPrevShorts = Shorts; pPrt->PPrevRx = RxCts; - return (Rtv); -} /* SkGePortCheckShorts*/ + return(Rtv); +} /* SkGePortCheckShorts */ /****************************************************************************** @@ -1147,22 +1210,27 @@ * 1 Restart needed on this port * 2 Link came up */ -int SkGePortCheckUp( +static int SkGePortCheckUp( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ { switch (pAC->GIni.GP[Port].PhyType) { case SK_PHY_XMAC: - return (SkGePortCheckUpXmac(pAC, IoC, Port)); + return(SkGePortCheckUpXmac(pAC, IoC, Port)); case SK_PHY_BCOM: - return (SkGePortCheckUpBcom(pAC, IoC, Port)); + return(SkGePortCheckUpBcom(pAC, IoC, Port)); + case SK_PHY_MARV_COPPER: + case SK_PHY_MARV_FIBER: + return(SkGePortCheckUpGmac(pAC, IoC, Port)); +#ifdef OTHER_PHY case SK_PHY_LONE: - return (SkGePortCheckUpLone(pAC, IoC, Port)); + return(SkGePortCheckUpLone(pAC, IoC, Port)); case SK_PHY_NAT: - return (SkGePortCheckUpNat(pAC, IoC, Port)); + return(SkGePortCheckUpNat(pAC, IoC, Port)); +#endif /* OTHER_PHY */ } - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } /* SkGePortCheckUp */ @@ -1175,14 +1243,13 @@ * 1 Restart needed on this port * 2 Link came up */ -static int SkGePortCheckUpXmac( +static int SkGePortCheckUpXmac( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ { - SK_U64 Shorts; /* Short Event Counter */ + SK_U32 Shorts; /* Short Event Counter */ SK_GEPORT *pPrt; /* GIni Port struct pointer */ - unsigned Len; int Done; SK_U32 GpReg; /* General Purpose register value */ SK_U16 Isrc; /* Interrupt source register */ @@ -1190,26 +1257,25 @@ SK_U16 LpAb; /* Link Partner Ability */ SK_U16 ResAb; /* Resolved Ability */ SK_U16 ExtStat; /* Extended Status Register */ - SK_BOOL AutoNeg; /* Is Autonegotiation used ? */ + SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ SK_U8 NextMode; /* Next AutoSensing Mode */ pPrt = &pAC->GIni.GP[Port]; if (pPrt->PHWLinkUp) { if (pPrt->PhyType != SK_PHY_XMAC) { - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } else { - return (SkGePortCheckShorts(pAC, IoC, Port)); + return(SkGePortCheckShorts(pAC, IoC, Port)); } } IsrcSum = pPrt->PIsave; pPrt->PIsave = 0; - /* Now wait for each port's link. */ - if (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL) { + /* Now wait for each port's link */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { AutoNeg = SK_FALSE; } else { @@ -1218,27 +1284,26 @@ if (pPrt->PLinkBroken) { /* Link was broken */ - XM_IN32(IoC,Port,XM_GP_PORT, &GpReg); + XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); if ((GpReg & XM_GP_INP_ASS) == 0) { /* The Link is in sync */ - XM_IN16(IoC,Port,XM_ISRC, &Isrc); + XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); if ((Isrc & XM_IS_INP_ASS) == 0) { - /* It has been in sync since last Time */ + /* It has been in sync since last time */ /* Restart the PORT */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link in sync Restart Port %d\n", Port)); - /* We now need to reinitialize the PrevShorts counter. */ - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *)&Shorts, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); + (void)SkXmUpdateStats(pAC, IoC, Port); + + /* We now need to reinitialize the PrevShorts counter */ + (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); pPrt->PPrevShorts = Shorts; - pAC->GIni.GP[Port].PLinkBroken = SK_FALSE; + pPrt->PLinkBroken = SK_FALSE; /* * Link Restart Workaround: @@ -1248,31 +1313,34 @@ * happening we check for a maximum number * of consecutive restart. If those happens, * we do NOT restart the active link and - * check whether the lionk is now o.k. + * check whether the link is now o.k. */ - pAC->GIni.GP[Port].PLinkResCt ++; + pPrt->PLinkResCt++; + pPrt->PAutoNegTimeOut = 0; - if (pAC->GIni.GP[Port].PLinkResCt < SK_MAX_LRESTART) { - return (SK_HW_PS_RESTART); + if (pPrt->PLinkResCt < SK_MAX_LRESTART) { + return(SK_HW_PS_RESTART); } - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + pPrt->PLinkResCt = 0; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); - pAC->GIni.GP[Port].PLinkResCt = 0; } else { - pPrt->PIsave = (SK_U16)(IsrcSum & (XM_IS_AND)); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + pPrt->PIsave = IsrcSum & XM_IS_AND; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); /* Do nothing more if link is broken */ - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } } else { /* Do nothing more if link is broken */ - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } } @@ -1280,69 +1348,67 @@ /* Link was not broken, check if it is */ XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; - if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) { + if ((Isrc & XM_IS_INP_ASS) != 0) { XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; - if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) { + if ((Isrc & XM_IS_INP_ASS) != 0) { XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; - if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) { + if ((Isrc & XM_IS_INP_ASS) != 0) { pPrt->PLinkBroken = SK_TRUE; - /* - * Re-Init Link partner Autoneg flag - */ + /* Re-Init Link partner Autoneg flag */ pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; - SK_DBG_MSG(pAC,SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link broken Port %d\n", Port)); - /* Cable removed-> reinit sense mode. */ - /* Init default sense mode. */ + /* Cable removed-> reinit sense mode */ SkHWInitDefSense(pAC, IoC, Port); - return (SK_HW_PS_RESTART); + return(SK_HW_PS_RESTART); } } } else { SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { - return (SK_HW_PS_RESTART); + return(SK_HW_PS_RESTART); } } } /* * here we usually can check whether the link is in sync and - * autonegotiation is done. + * auto-negotiation is done. */ XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); + if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { if ((GpReg & XM_GP_INP_ASS) == 0) { - /* Save Autonegotiation Done interrupt only if link is in sync. */ - pPrt->PIsave = (SK_U16)(IsrcSum & (XM_IS_AND)); + /* Save Auto-negotiation Done interrupt only if link is in sync */ + pPrt->PIsave = IsrcSum & XM_IS_AND; } -#ifdef DEBUG - if (pPrt->PIsave & (XM_IS_AND)) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, +#ifdef DEBUG + if ((pPrt->PIsave & XM_IS_AND) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg done rescheduled Port %d\n", Port)); } -#endif - return (SK_HW_PS_NONE); +#endif /* DEBUG */ + return(SK_HW_PS_NONE); } if (AutoNeg) { - if (IsrcSum & XM_IS_AND) { + if ((IsrcSum & XM_IS_AND) != 0) { SkHWLinkUp(pAC, IoC, Port); - Done = SkXmAutoNegDone(pAC,IoC,Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); if (Done != SK_AND_OK) { - /* Get PHY parameters, for debuging only */ - PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP, &LpAb); - PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI, &ResAb); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + /* Get PHY parameters, for debugging only */ + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb); + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n", Port, LpAb, ResAb)); @@ -1354,44 +1420,30 @@ SkHWSenseSetNext(pAC, IoC, Port, NextMode); } - return (SK_HW_PS_RESTART); - } - else { - /* - * Dummy Read extended status to prevent extra link down/ups - * (clear Page Received bit if set) - */ - PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_EXP, &ExtStat); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); - return (SK_HW_PS_LINK); + return(SK_HW_PS_RESTART); } - } - - /* - * AutoNeg not done, but HW link is up. Check for timeouts - */ - pPrt->PAutoNegTimeOut ++; - if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { /* - * Increase the Timeout counter. + * Dummy Read extended status to prevent extra link down/ups + * (clear Page Received bit if set) */ - pPrt->PAutoNegTOCt ++; + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg done Port %d\n", Port)); + return(SK_HW_PS_LINK); + } + + /* AutoNeg not done, but HW link is up. Check for timeouts */ + pPrt->PAutoNegTimeOut++; + if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { + /* Increase the Timeout counter */ + pPrt->PAutoNegTOCt++; - /* - * Timeout occured. - * What do we need now? - */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM, - SK_DBGCAT_IRQ, - ("AutoNeg timeout Port %d\n", - Port)); + /* Timeout occured */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("AutoNeg timeout Port %d\n", Port)); if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { - /* - * Timeout occured - * Set Link manually up. - */ + /* Set Link manually up */ SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Set manual full duplex Port %d\n", Port)); @@ -1403,10 +1455,10 @@ /* * This is rather complicated. * we need to check here whether the LIPA_AUTO - * we saw before is false alert. We saw at one + * we saw before is false alert. We saw at one * switch ( SR8800) that on boot time it sends - * just one autoneg packet and does no further - * autonegotiation. + * just one auto-neg packet and does no further + * auto-negotiation. * Solution: we restart the autosensing after * a few timeouts. */ @@ -1415,30 +1467,31 @@ SkHWInitDefSense(pAC, IoC, Port); } - /* - * Do the restart - */ - return (SK_HW_PS_RESTART); + /* Do the restart */ + return(SK_HW_PS_RESTART); } } else { - /* - * Link is up and we don't need more. - */ -#ifdef DEBUG + /* Link is up and we don't need more */ +#ifdef DEBUG if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("ERROR: Lipa auto detected on port %d\n", Port)); } -#endif - - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, +#endif /* DEBUG */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); - return (SK_HW_PS_LINK); + + /* + * Link sync (GP) and so assume a good connection. But if not received + * a bunch of frames received in a time slot (maybe broken tx cable) + * the port is restart. + */ + return(SK_HW_PS_LINK); } - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } /* SkGePortCheckUpXmac */ @@ -1451,7 +1504,7 @@ * 1 Restart needed on this port * 2 Link came up */ -static int SkGePortCheckUpBcom( +static int SkGePortCheckUpBcom( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ @@ -1465,20 +1518,22 @@ #ifdef DEBUG SK_U16 LpAb; SK_U16 ExtStat; -#endif /* DEBUG */ - SK_BOOL AutoNeg; /* Is Autonegotiation used ? */ +#endif /* DEBUG */ + SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ pPrt = &pAC->GIni.GP[Port]; /* Check for No HCD Link events (#10523) */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &Isrc); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc); #ifdef xDEBUG - if ((Isrc & ~0x1800) == 0x70) { + if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) == + (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { + SK_U32 Stat1, Stat2, Stat3; Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_INT_MASK, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, @@ -1487,14 +1542,14 @@ (void *)Stat1); Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_CTRL, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_STAT, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_ADV, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); Stat3 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_LP, &Stat3); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, @@ -1504,14 +1559,14 @@ (void *)Stat2); Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_EXP, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_EXT_STAT, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_CTRL, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); Stat3 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_STAT, &Stat3); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, @@ -1521,14 +1576,14 @@ (void *)Stat2); Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_STAT, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_CTRL, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); Stat3 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_STAT, &Stat3); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, @@ -1537,16 +1592,18 @@ (void *)Stat1, (void *)Stat2); } -#endif /* DEBUG */ +#endif /* DEBUG */ if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { /* * Workaround BCOM Errata: * enable and disable loopback mode if "NO HCD" occurs. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_CTRL, &Ctrl); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl | PHY_CT_LOOP); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl & ~PHY_CT_LOOP); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, + (SK_U16)(Ctrl | PHY_CT_LOOP)); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, + (SK_U16)(Ctrl & ~PHY_CT_LOOP)); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("No HCD Link event, Port %d\n", Port)); #ifdef xDEBUG @@ -1556,14 +1613,14 @@ "No HCD link event, port %d.", (void *)Port, (void *)NULL); -#endif /* DEBUG */ +#endif /* DEBUG */ } /* Not obsolete: link status bit is latched to 0 and autoclearing! */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); if (pPrt->PHWLinkUp) { - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } #ifdef xDEBUG @@ -1571,7 +1628,7 @@ SK_U32 Stat1, Stat2, Stat3; Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_INT_MASK, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, @@ -1580,14 +1637,14 @@ (void *)Stat1); Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_CTRL, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_STAT, &PhyStat); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); Stat1 = Stat1 << 16 | PhyStat; Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_ADV, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); Stat3 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_LP, &Stat3); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, @@ -1597,14 +1654,14 @@ (void *)Stat2); Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_EXP, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_EXT_STAT, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_CTRL, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); Stat3 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); Stat2 = Stat2 << 16 | ResAb; CMSMPrintString( pAC->pConfigTable, @@ -1614,14 +1671,14 @@ (void *)Stat2); Stat1 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_STAT, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_CTRL, &Stat2); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); Stat3 = 0; - PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_STAT, &Stat3); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, @@ -1630,9 +1687,9 @@ (void *)Stat1, (void *)Stat2); } -#endif /* DEBUG */ +#endif /* DEBUG */ - /* Now wait for each port's link. */ + /* Now wait for each port's link */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { AutoNeg = SK_FALSE; } @@ -1642,76 +1699,59 @@ /* * Here we usually can check whether the link is in sync and - * autonegotiation is done. + * auto-negotiation is done. */ -#if 0 -/* RA;:;: obsolete */ - XM_IN16(IoC, Port, XM_ISRC, &Isrc); -#endif /* 0 */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat); - -#ifdef xDEBUG - if ((PhyStat & PHY_ST_LSYNC) >> 2 != (ExtStat & PHY_B_PES_LS) >> 8) { - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "PhyStat != ExtStat: %x %x", - (void *)PhyStat, - (void *)ExtStat); - } -#endif /* DEBUG */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); - SkXmAutoNegLipaBcom(pAC, IoC, Port, PhyStat); + SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat)); + ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); - PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); - if (ResAb & PHY_B_1000S_MSF) { + if ((ResAb & PHY_B_1000S_MSF) != 0) { /* Error */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Master/Slave Fault port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; - return (SK_HW_PS_RESTART); + + return(SK_HW_PS_RESTART); } if ((PhyStat & PHY_ST_LSYNC) == 0) { - return (SK_HW_PS_NONE); - } - else if (ResAb & PHY_B_1000S_MSR) { - pPrt->PMSStatus = SK_MS_STAT_MASTER; - } - else { - pPrt->PMSStatus = SK_MS_STAT_SLAVE; + return(SK_HW_PS_NONE); } + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat)); + ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); if (AutoNeg) { - if (PhyStat & PHY_ST_AN_OVER) { + if ((PhyStat & PHY_ST_AN_OVER) != 0) { SkHWLinkUp(pAC, IoC, Port); - Done = SkXmAutoNegDone(pAC, IoC, Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); if (Done != SK_AND_OK) { #ifdef DEBUG - /* Get PHY parameters, for debugging only. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LpAb); - PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ExtStat); + /* Get PHY parameters, for debugging only */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", Port, LpAb, ExtStat)); -#endif /* DEBUG */ - return (SK_HW_PS_RESTART); +#endif /* DEBUG */ + return(SK_HW_PS_RESTART); } else { #ifdef xDEBUG - /* Dummy read ISR to prevent extra link downs/ups. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat); + /* Dummy read ISR to prevent extra link downs/ups */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); - if ((ExtStat & ~0x1800) != 0) { + if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, @@ -1719,30 +1759,28 @@ (void *)ExtStat, (void *)NULL); } -#endif /* DEBUG */ +#endif /* DEBUG */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg done Port %d\n", Port)); - return (SK_HW_PS_LINK); + return(SK_HW_PS_LINK); } - } + } } else { /* !AutoNeg */ - /* - * Link is up and we don't need more. - */ -#ifdef DEBUG + /* Link is up and we don't need more. */ +#ifdef DEBUG if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("ERROR: Lipa auto detected on port %d\n", Port)); } -#endif +#endif /* DEBUG */ #ifdef xDEBUG - /* Dummy read ISR to prevent extra link downs/ups. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat); + /* Dummy read ISR to prevent extra link downs/ups */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); - if ((ExtStat & ~0x1800) != 0) { + if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, @@ -1750,20 +1788,136 @@ (void *)ExtStat, (void *)NULL); } -#endif /* DEBUG */ +#endif /* DEBUG */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); - return (SK_HW_PS_LINK); + return(SK_HW_PS_LINK); } - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } /* SkGePortCheckUpBcom */ /****************************************************************************** * + * SkGePortCheckUpGmac - Check, if the link is up + * + * return: + * 0 o.k. nothing needed + * 1 Restart needed on this port + * 2 Link came up + */ +static int SkGePortCheckUpGmac( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO Context */ +int Port) /* Which port should be checked */ +{ + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + int Done; + SK_U16 Isrc; /* Interrupt source */ + SK_U16 PhyStat; /* Phy Status */ + SK_U16 PhySpecStat;/* Phy Specific Status */ + SK_U16 ResAb; /* Master/Slave resolution */ + SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ + + pPrt = &pAC->GIni.GP[Port]; + + /* Read PHY Interrupt Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc); + + if ((Isrc & PHY_M_IS_AN_COMPL) != 0) { + /* TBD */ + } + + if (pPrt->PHWLinkUp) { + return(SK_HW_PS_NONE); + } + + /* Now wait for each port's link */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + AutoNeg = SK_FALSE; + } + else { + AutoNeg = SK_TRUE; + } + + /* Read PHY Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); + + SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); + + if ((ResAb & PHY_B_1000S_MSF) != 0) { + /* Error */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Master/Slave Fault port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; + + return(SK_HW_PS_RESTART); + } + + /* Read PHY Specific Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat)); + + if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { + return(SK_HW_PS_NONE); + } + + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; + + pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); + + if (AutoNeg) { + /* Auto-Negotiation Over ? */ + if ((PhyStat & PHY_ST_AN_OVER) != 0) { + + SkHWLinkUp(pAC, IoC, Port); + + Done = SkMacAutoNegDone(pAC, IoC, Port); + + if (Done != SK_AND_OK) { + return(SK_HW_PS_RESTART); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg done Port %d\n", Port)); + return(SK_HW_PS_LINK); + } + } + else { /* !AutoNeg */ + /* Link is up and we don't need more */ +#ifdef DEBUG + if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("ERROR: Lipa auto detected on port %d\n", Port)); + } +#endif /* DEBUG */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Link sync, Port %d\n", Port)); + SkHWLinkUp(pAC, IoC, Port); + + return(SK_HW_PS_LINK); + } + + return(SK_HW_PS_NONE); +} /* SkGePortCheckUpGmac */ + + +#ifdef OTHER_PHY +/****************************************************************************** + * * SkGePortCheckUpLone - Check if the link is up * * return: @@ -1771,33 +1925,32 @@ * 1 Restart needed on this port * 2 Link came up */ -static int SkGePortCheckUpLone( +static int SkGePortCheckUpLone( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ - int Done; + int Done; SK_U16 Isrc; /* Interrupt source register */ SK_U16 LpAb; /* Link Partner Ability */ SK_U16 ExtStat; /* Extended Status Register */ SK_U16 PhyStat; /* Phy Status Register */ SK_U16 StatSum; - SK_BOOL AutoNeg; /* Is Autonegotiation used ? */ + SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ SK_U8 NextMode; /* Next AutoSensing Mode */ pPrt = &pAC->GIni.GP[Port]; if (pPrt->PHWLinkUp) { - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } StatSum = pPrt->PIsave; pPrt->PIsave = 0; /* Now wait for each ports link */ - if (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL) { + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { AutoNeg = SK_FALSE; } else { @@ -1806,39 +1959,33 @@ /* * here we usually can check whether the link is in sync and - * autonegotiation is done. + * auto-negotiation is done. */ - XM_IN16(IoC, Port, XM_ISRC, &Isrc); - PHY_READ(IoC, pPrt, Port, PHY_LONE_STAT, &PhyStat); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat); StatSum |= PhyStat; - SkXmAutoNegLipaLone(pAC, IoC, Port, PhyStat); - if ((PhyStat & PHY_ST_LSYNC) == 0){ - /* - * Save Autonegotiation Done bit - */ + SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); + + if ((PhyStat & PHY_ST_LSYNC) == 0) { + /* Save Auto-negotiation Done bit */ pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER); #ifdef DEBUG - if (pPrt->PIsave & PHY_ST_AN_OVER) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg done rescheduled Port %d\n", Port)); } -#endif - return (SK_HW_PS_NONE); +#endif /* DEBUG */ + return(SK_HW_PS_NONE); } if (AutoNeg) { - if (StatSum & PHY_ST_AN_OVER) { + if ((StatSum & PHY_ST_AN_OVER) != 0) { SkHWLinkUp(pAC, IoC, Port); - Done = SkXmAutoNegDone(pAC,IoC,Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); if (Done != SK_AND_OK) { - /* Get PHY parameters, for debuging only */ - PHY_READ(IoC, pPrt, Port, - PHY_LONE_AUNE_LP, - &LpAb); - PHY_READ(IoC, pPrt, Port, - PHY_LONE_1000T_STAT, - &ExtStat); + /* Get PHY parameters, for debugging only */ + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", Port, LpAb, ExtStat)); @@ -1851,7 +1998,7 @@ SkHWSenseSetNext(pAC, IoC, Port, NextMode); } - return (SK_HW_PS_RESTART); + return(SK_HW_PS_RESTART); } else { @@ -1859,71 +2006,54 @@ * Dummy Read interrupt status to prevent * extra link down/ups */ - PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT, &ExtStat); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg done Port %d\n", Port)); - return (SK_HW_PS_LINK); + return(SK_HW_PS_LINK); } - } + } - /* - * AutoNeg not done, but HW link is up. Check for timeouts - */ - pPrt->PAutoNegTimeOut ++; + /* AutoNeg not done, but HW link is up. Check for timeouts */ + pPrt->PAutoNegTimeOut++; if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { - /* - * Timeout occured. - * What do we need now? - */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM, - SK_DBGCAT_IRQ, - ("AutoNeg timeout Port %d\n", - Port)); + /* Timeout occured */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("AutoNeg timeout Port %d\n", Port)); if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { - /* - * Timeout occured - * Set Link manually up. - */ - SkHWSenseSetNext(pAC, IoC, Port, - SK_LMODE_FULL); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM, - SK_DBGCAT_IRQ, - ("Set manual full duplex Port %d\n", - Port)); + /* Set Link manually up */ + SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Set manual full duplex Port %d\n", Port)); } - /* - * Do the restart - */ - return (SK_HW_PS_RESTART); + /* Do the restart */ + return(SK_HW_PS_RESTART); } } else { - /* - * Link is up and we don't need more. - */ -#ifdef DEBUG + /* Link is up and we don't need more */ +#ifdef DEBUG if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("ERROR: Lipa auto detected on port %d\n", Port)); } -#endif +#endif /* DEBUG */ /* * Dummy Read interrupt status to prevent * extra link down/ups */ - PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT, &ExtStat); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); - return (SK_HW_PS_LINK); + return(SK_HW_PS_LINK); } - return (SK_HW_PS_NONE); -} /* SkGePortCheckUpLone*/ + return(SK_HW_PS_NONE); +} /* SkGePortCheckUpLone */ /****************************************************************************** @@ -1935,14 +2065,15 @@ * 1 Restart needed on this port * 2 Link came up */ -static int SkGePortCheckUpNat( +static int SkGePortCheckUpNat( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ { /* todo: National */ - return (SK_HW_PS_NONE); + return(SK_HW_PS_NONE); } /* SkGePortCheckUpNat */ +#endif /* OTHER_PHY */ /****************************************************************************** @@ -1968,7 +2099,7 @@ SK_U8 Val8; Port = Para.Para32[0]; - pPrt = & pAC->GIni.GP[Port]; + pPrt = &pAC->GIni.GP[Port]; switch (Event) { case SK_HWEV_WATIM: @@ -2010,9 +2141,9 @@ } /* Todo: still needed for non-XMAC PHYs??? */ - /* Start workaround Errata #2 timer. */ - SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer, - Time, SKGE_HWAC, SK_HWEV_WATIM, Para); + /* Start workaround Errata #2 timer */ + SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Time, + SKGE_HWAC, SK_HWEV_WATIM, Para); break; case SK_HWEV_PORT_START: @@ -2035,7 +2166,7 @@ break; case SK_HWEV_PORT_STOP: - if (pAC->GIni.GP[Port].PHWLinkUp) { + if (pPrt->PHWLinkUp) { /* * Signal directly to RLMT to ensure correct * sequence of SWITCH and RESET event. @@ -2087,6 +2218,10 @@ break; case SK_HWEV_SET_ROLE: + /* not possible for fiber */ + if (!pAC->GIni.GICopperType) { + break; + } Val8 = (SK_U8)Para.Para32[1]; if (pPrt->PMSMode != Val8) { /* Set New link mode */ @@ -2098,30 +2233,48 @@ } break; + case SK_HWEV_SET_SPEED: + if (pPrt->PhyType != SK_PHY_MARV_COPPER) { + break; + } + Val8 = (SK_U8)Para.Para32[1]; + if (pPrt->PLinkSpeed != Val8) { + /* Set New Speed parameter */ + pPrt->PLinkSpeed = Val8; + + /* Restart Port */ + SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); + SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); + } + break; + case SK_HWEV_HALFDUP_CHK: /* - * half duplex hangup workaround. See packet arbiter timeout - * interrupt for description + * half duplex hangup workaround. + * See packet arbiter timeout interrupt for description */ pPrt->HalfDupTimerActive = SK_FALSE; - if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { + Len = sizeof(SK_U64); SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), pAC->Rlmt.Port[Port].Net->NetNumber); + if (pPrt->LastOctets == Octets) { - /* TX hanging, do a FIFO flush restarts it. */ - SkXmFlushTxFifo(pAC, IoC, Port); + /* Tx hanging, a FIFO flush restarts it */ + SkMacFlushTxFifo(pAC, IoC, Port); } } break; + default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); break; } - return (0); + return(0); } /* SkGeSirqEvent */ @@ -2144,25 +2297,13 @@ pPrt = &pAC->GIni.GP[Port]; - if (IStatus & PHY_B_IS_PSE) { - /* Incorrectable pair swap error. */ + if ((IStatus & PHY_B_IS_PSE) != 0) { + /* Incorrectable pair swap error */ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022, SKERR_SIRQ_E022MSG); } - if (IStatus & PHY_B_IS_MDXI_SC) { - /* not used */ - } - - if (IStatus & PHY_B_IS_HCT) { - /* not used */ - } - - if (IStatus & PHY_B_IS_LCT) { - /* not used */ - } - - if (IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) { + if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) { Para.Para32[0] = (SK_U32)Port; SkHWLinkDown(pAC, IoC, Port); @@ -2171,47 +2312,58 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pPrt->PWaTimer, - SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para); + SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, + SKGE_HWAC, SK_HWEV_WATIM, Para); } - if (IStatus & PHY_B_IS_NO_HDCL) { - } +} /* SkPhyIsrBcom */ - if (IStatus & PHY_B_IS_NO_HDC) { - /* not used */ - } - if (IStatus & PHY_B_IS_NEG_USHDC) { - /* not used */ - } +/****************************************************************************** + * + * SkPhyIsrGmac - PHY interrupt service routine + * + * Description: handle all interrupts from Marvell PHY + * + * Returns: N/A + */ +static void SkPhyIsrGmac( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* Io Context */ +int Port, /* Port Num = PHY Num */ +SK_U16 IStatus) /* Interrupt Status */ +{ + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + SK_EVPARA Para; - if (IStatus & PHY_B_IS_SCR_S_ER) { - /* not used */ - } + pPrt = &pAC->GIni.GP[Port]; - if (IStatus & PHY_B_IS_RRS_CHANGE) { - /* not used */ - } + if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) { + Para.Para32[0] = (SK_U32)Port; - if (IStatus & PHY_B_IS_LRS_CHANGE) { - /* not used */ - } + SkHWLinkDown(pAC, IoC, Port); - if (IStatus & PHY_B_IS_DUP_CHANGE) { - /* not used */ + /* Signal to RLMT */ + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } - - if (IStatus & PHY_B_IS_LSP_CHANGE) { - /* not used */ + + if ((IStatus & PHY_M_IS_AN_ERROR) != 0) { + /* Auto-Negotiation Error */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); } - - if (IStatus & PHY_B_IS_CRC_ER) { - /* not used */ + + if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) { + /* TBD */ } -} /* SkPhyIsrBcom */ + + if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) { + /* FIFO Overflow/Underrun Error */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG); + } +} /* SkPhyIsrGmac */ +#ifdef OTHER_PHY /****************************************************************************** * * SkPhyIsrLone - PHY interrupt service routine @@ -2228,49 +2380,15 @@ { SK_EVPARA Para; - if (IStatus & PHY_L_IS_CROSS) { - /* not used */ - } - - if (IStatus & PHY_L_IS_POL) { - /* not used */ - } - - if (IStatus & PHY_L_IS_SS) { - /* not used */ - } - - if (IStatus & PHY_L_IS_CFULL) { - /* not used */ - } - - if (IStatus & PHY_L_IS_AN_C) { - /* not used */ - } - - if (IStatus & PHY_L_IS_SPEED) { - /* not used */ - } - - if (IStatus & PHY_L_IS_CFULL) { - /* not used */ - } - if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) { SkHWLinkDown(pAC, IoC, Port); /* Signal to RLMT */ Para.Para32[0] = (SK_U32)Port; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - - /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer, - SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para); } - if (IStatus & PHY_L_IS_MDINT) { - /* not used */ - } } /* SkPhyIsrLone */ +#endif /* OTHER_PHY */ /* End of File */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/ski2c.c linux.21pre4-ac6/drivers/net/sk98lin/ski2c.c --- linux.21pre4/drivers/net/sk98lin/ski2c.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/ski2c.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: ski2c.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.47 $ - * Date: $Date: 2001/04/05 11:38:09 $ + * Version: $Revision: 1.56 $ + * Date: $Date: 2002/12/19 14:20:41 $ * Purpose: Functions to access Voltage and Temperature Sensor - * (taken from Monalisa (taken from Concentrator)) * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -27,6 +26,43 @@ * History: * * $Log: ski2c.c,v $ + * Revision 1.56 2002/12/19 14:20:41 rschmidt + * Added debugging code in SkI2cWait(). + * Replaced all I2C-write operations with function SkI2cWrite(). + * Fixed compiler warning because of uninitialized 'Time' in SkI2cEvent(). + * Editorial changes. + * + * Revision 1.55 2002/10/15 07:23:55 rschmidt + * Added setting of the GIYukon32Bit bool variable to distinguish + * 32-bit adapters. + * Editorial changes (TWSI). + * + * Revision 1.54 2002/08/13 09:05:06 rschmidt + * Added new thresholds if VAUX is not available (GIVauxAvail). + * Merged defines for PHY PLL 3V3 voltage (A and B). + * Editorial changes. + * + * Revision 1.53 2002/08/08 11:04:53 rwahl + * Added missing comment for revision 1.51 + * + * Revision 1.52 2002/08/08 10:09:02 jschmalz + * Sensor init state caused wrong error log entry + * + * Revision 1.51 2002/08/06 09:43:03 jschmalz + * Extensions and changes for Yukon + * + * Revision 1.50 2002/08/02 12:09:22 rschmidt + * Added support for YUKON sensors. + * Editorial changes. + * + * Revision 1.49 2002/07/30 11:07:52 rschmidt + * Replaced MaxSens init by update for Copper in SkI2cInit1(), + * because it was already initialized in SkI2cInit0(). + * Editorial changes. + * + * Revision 1.48 2001/08/16 12:44:33 afischer + * LM80 sensor init values corrected + * * Revision 1.47 2001/04/05 11:38:09 rassmann * Set SenState to idle in SkI2cWaitIrq(). * Changed error message in SkI2cWaitIrq(). @@ -178,7 +214,7 @@ * Revision 1.2 1998/08/11 07:27:15 gklug * add: functions of the interface * adapt rest of source to C coding Conventions - * rmv: unneccessary code taken from Mona Lisa + * rmv: unnecessary code taken from Mona Lisa * * Revision 1.1 1998/06/19 14:28:43 malthoff * Created. Sources taken from ML Projekt. @@ -192,7 +228,7 @@ * I2C Protocol */ static const char SysKonnectFileId[] = - "$Id: ski2c.c,v 1.47 2001/04/05 11:38:09 rassmann Exp $"; + "$Id: ski2c.c,v 1.56 2002/12/19 14:20:41 rschmidt Exp $"; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" @@ -280,21 +316,21 @@ #ifndef I2C_SLOW_TIMING #define T_CLK_LOW 1300L /* clock low time in ns */ #define T_CLK_HIGH 600L /* clock high time in ns */ -#define T_DATA_IN_SETUP 100L /* data in Set-UP Time */ +#define T_DATA_IN_SETUP 100L /* data in Set-up Time */ #define T_START_HOLD 600L /* start condition hold time */ #define T_START_SETUP 600L /* start condition Set-up time */ #define T_STOP_SETUP 600L /* stop condition Set-up time */ -#define T_BUS_IDLE 1300L /* time the bus must free after tx */ +#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ #define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ #else /* I2C_SLOW_TIMING */ /* I2C Standard Mode Timing */ #define T_CLK_LOW 4700L /* clock low time in ns */ #define T_CLK_HIGH 4000L /* clock high time in ns */ -#define T_DATA_IN_SETUP 250L /* data in Set-UP Time */ +#define T_DATA_IN_SETUP 250L /* data in Set-up Time */ #define T_START_HOLD 4000L /* start condition hold time */ -#define T_START_SETUP 4700L /* start condition Set_up time */ +#define T_START_SETUP 4700L /* start condition Set-up time */ #define T_STOP_SETUP 4000L /* stop condition Set-up time */ -#define T_BUS_IDLE 4700L /* time the bus must free after tx */ +#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ #endif /* !I2C_SLOW_TIMING */ #define NS2BCLK(x) (((x)*125)/10000) @@ -312,9 +348,9 @@ #define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA) #define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA) #define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR) -#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR|I2C_DATA) +#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA) #define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK) -#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK|I2C_DATA_DIR) +#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR) #define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK) #define NS2CLKT(x) ((x*125L)/10000) @@ -331,7 +367,8 @@ I2C_DATA_OUT(IoC); if (Bit) { I2C_DATA_HIGH(IoC); - } else { + } + else { I2C_DATA_LOW(IoC); } SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP)); @@ -428,11 +465,8 @@ SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); SK_I2C_GET_SW(IoC, &I2cSwCtrl); - if (I2cSwCtrl & I2C_DATA) { - Bit = 1; - } else { - Bit = 0; - } + + Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0; I2C_CLK_LOW(IoC); SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)); @@ -444,16 +478,16 @@ /* * Receive an ACK. * - * returns 0 If acknoledged + * returns 0 If acknowledged * 1 in case of an error */ int SkI2cRcvAck( -SK_IOC IoC) /* I/O Context */ +SK_IOC IoC) /* I/O Context */ { /* * Received bit must be zero. */ - return (SkI2cRcvBit(IoC) != 0); + return(SkI2cRcvBit(IoC) != 0); } /* SkI2cRcvAck */ @@ -461,7 +495,7 @@ * Send an NACK. */ void SkI2cSndNAck( -SK_IOC IoC) /* I/O Context */ +SK_IOC IoC) /* I/O Context */ { /* * Received bit must be zero. @@ -487,18 +521,19 @@ /* * Send one byte to the I2C device and wait for ACK. * - * Return acknoleged status. + * Return acknowleged status. */ int SkI2cSndByte( SK_IOC IoC, /* I/O Context */ -int Byte) /* byte to send */ +int Byte) /* byte to send */ { int i; for (i = 0; i < 8; i++) { if (Byte & (1<<(7-i))) { SkI2cSndBit(IoC, 1); - } else { + } + else { SkI2cSndBit(IoC, 0); } } @@ -514,7 +549,7 @@ */ int SkI2cRcvByte( SK_IOC IoC, /* I/O Context */ -int Last) /* Last Byte Flag */ +int Last) /* Last Byte Flag */ { int i; int Byte = 0; @@ -526,7 +561,8 @@ if (Last) { SkI2cSndNAck(IoC); - } else { + } + else { SkI2cSndAck(IoC); } @@ -537,7 +573,7 @@ /* * Start dialog and send device address * - * Return 0 if acknoleged, 1 in case of an error + * Return 0 if acknowleged, 1 in case of an error */ int SkI2cSndDev( SK_IOC IoC, /* I/O Context */ @@ -545,7 +581,7 @@ int Rw) /* Read / Write Flag */ { SkI2cStart(IoC); - Rw = ~Rw; + Rw = ~Rw; Rw &= I2C_WRITE; return(SkI2cSndByte(IoC, (Addr<<1) | Rw)); } /* SkI2cSndDev */ @@ -567,18 +603,33 @@ int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ { SK_U64 StartTime; + SK_U64 CurrentTime; SK_U32 I2cCtrl; StartTime = SkOsGetTime(pAC); + do { - if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { + CurrentTime = SkOsGetTime(pAC); + + if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) { + SK_I2C_STOP(IoC); #ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); #endif /* !SK_DIAG */ return(1); } + SK_I2C_GET_CTL(IoC, &I2cCtrl); + +#ifdef xYUKON_DBG + printf("StartTime=%lu, CurrentTime=%lu\n", + StartTime, CurrentTime); + if (kbhit()) { + return(1); + } +#endif /* YUKON_DBG */ + } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31); return(0); @@ -591,7 +642,7 @@ * Returns * Nothing */ -void SkI2cWaitIrq( +void SkI2cWaitIrq( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC) /* I/O Context */ { @@ -621,8 +672,6 @@ return; } /* SkI2cWaitIrq */ -#ifdef SK_DIAG - /* * writes a single byte or 4 bytes into the I2C device * @@ -635,14 +684,17 @@ SK_U32 I2cData, /* I2C Data to write */ int I2cDev, /* I2C Device Address */ int I2cReg, /* I2C Device Register Address */ -int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */ +int I2cBurst) /* I2C Burst Flag */ { SK_OUT32(IoC, B2_I2C_DATA, I2cData); SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst); + return(SkI2cWait(pAC, IoC, I2C_WRITE)); } /* SkI2cWrite*/ +#ifdef SK_DIAG + /* * reads a single byte or 4 bytes from the I2C device * @@ -653,15 +705,17 @@ SK_IOC IoC, /* I/O Context */ int I2cDev, /* I2C Device Address */ int I2cReg, /* I2C Device Register Address */ -int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */ +int I2cBurst) /* I2C Burst Flag */ { SK_U32 Data; SK_OUT32(IoC, B2_I2C_DATA, 0); SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst); - if (SkI2cWait(pAC, IoC, I2C_READ)) { - w_print("I2C Transfer Timeout!\n"); + + if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { + w_print("%s\n", SKERR_I2C_E002MSG); } + SK_IN32(IoC, B2_I2C_DATA, &Data); return(Data); } /* SkI2cRead */ @@ -684,13 +738,17 @@ SK_IOC IoC, /* I/O Context */ SK_SENSOR *pSen) /* Sensor to be read */ { - return((*pSen->SenRead)(pAC, IoC, pSen)); + if (pSen->SenRead != NULL) { + return((*pSen->SenRead)(pAC, IoC, pSen)); + } + else + return(0); /* no success */ } /* SkI2cReadSensor*/ /* * Do the Init state 0 initialization */ -static int SkI2cInit0( +static int SkI2cInit0( SK_AC *pAC) /* Adapter Context */ { int i; @@ -698,109 +756,33 @@ /* Begin with first sensor */ pAC->I2c.CurrSens = 0; - /* Set to mimimum sensor number */ - pAC->I2c.MaxSens = SK_MIN_SENSORS; + /* Begin with timeout control for state machine */ + pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; + + /* Set sensor number to zero */ + pAC->I2c.MaxSens = 0; #ifndef SK_DIAG /* Initialize Number of Dummy Reads */ pAC->I2c.DummyReads = SK_MAX_SENSORS; #endif - for (i = 0; i < SK_MAX_SENSORS; i ++) { - switch (i) { - case 0: - pAC->I2c.SenTable[i].SenDesc = "Temperature"; - pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH0; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW0; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH0; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW0; - pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - case 1: - pAC->I2c.SenTable[i].SenDesc = "Voltage PCI"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH1; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW1; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH1; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW1; - pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - case 2: - pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH2; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW2; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH2; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW2; - pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN; - pAC->I2c.SenTable[i].SenInit = SK_FALSE; - break; - case 3: - pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH3; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW3; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH3; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW3; - pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - case 4: - pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH4; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW4; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH4; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW4; - pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - case 5: - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH5; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW5; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH5; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW5; - pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - case 6: - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH6; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW6; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH6; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW6; - pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - case 7: - pAC->I2c.SenTable[i].SenDesc = "Speed Fan"; - pAC->I2c.SenTable[i].SenType = SK_SEN_FAN; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_WARNHIGH; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_WARNLOW; - pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; - pAC->I2c.SenTable[i].SenInit = SK_TRUE; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, - SKERR_I2C_E001, SKERR_I2C_E001MSG); - break; - } - + for (i = 0; i < SK_MAX_SENSORS; i++) { + pAC->I2c.SenTable[i].SenDesc = "unknown"; + pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN; + pAC->I2c.SenTable[i].SenThreErrHigh = 0; + pAC->I2c.SenTable[i].SenThreErrLow = 0; + pAC->I2c.SenTable[i].SenThreWarnHigh = 0; + pAC->I2c.SenTable[i].SenThreWarnLow = 0; + pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; + pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE; pAC->I2c.SenTable[i].SenValue = 0; - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; + pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT; pAC->I2c.SenTable[i].SenErrCts = 0; pAC->I2c.SenTable[i].SenBegErrTS = 0; pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; - pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor; - pAC->I2c.SenTable[i].SenDev = LM80_ADDR; + pAC->I2c.SenTable[i].SenRead = NULL; + pAC->I2c.SenTable[i].SenDev = 0; } /* Now we are "INIT data"ed */ @@ -829,68 +811,211 @@ * - all 0s * */ -static int SkI2cInit1( +static int SkI2cInit1( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC) /* I/O Context */ { + int i; + SK_U8 I2cSwCtrl; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + if (pAC->I2c.InitLevel != SK_INIT_DATA) { /* ReInit not needed in I2C module */ return(0); } - SK_OUT32(IoC, B2_I2C_DATA, 0); - SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_CFG, 0); - (void)SkI2cWait(pAC, IoC, I2C_WRITE); - - SK_OUT32(IoC, B2_I2C_DATA, 0xff); - SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_IMSK_1, 0); - (void)SkI2cWait(pAC, IoC, I2C_WRITE); - - SK_OUT32(IoC, B2_I2C_DATA, 0xff); - SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_IMSK_2, 0); - (void)SkI2cWait(pAC, IoC, I2C_WRITE); - - SK_OUT32(IoC, B2_I2C_DATA, 0x0); - SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_FAN_CTRL, 0); - (void)SkI2cWait(pAC, IoC, I2C_WRITE); - - SK_OUT32(IoC, B2_I2C_DATA, 0); - SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_TEMP_CTRL, 0); - (void)SkI2cWait(pAC, IoC, I2C_WRITE); + /* Set the Direction of I2C-Data Pin to IN */ + SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA); + /* Check for 32-Bit Yukon with Low at I2C-Data Pin */ + SK_I2C_GET_SW(IoC, &I2cSwCtrl); - SK_OUT32(IoC, B2_I2C_DATA, LM80_CFG_START); - SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_CFG, 0); - (void)SkI2cWait(pAC, IoC, I2C_WRITE); + if ((I2cSwCtrl & I2C_DATA) == 0) { + /* this is a 32-Bit board */ + pAC->GIni.GIYukon32Bit = SK_TRUE; + return(0); + } + + /* Check for 64 Bit Yukon without sensors */ + if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) { + return(0); + } + (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0); + + (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0); + + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0); + + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0); + + (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0); + /* - * MaxSens has to be initialized here, because PhyType is not - * set when performing Init Level 1 + * MaxSens has to be updated here, because PhyType is not + * set when performing Init Level 0 */ - switch (pAC->GIni.GP[0].PhyType) { - case SK_PHY_XMAC: - pAC->I2c.MaxSens = 5; - break; + pAC->I2c.MaxSens = 5; + + pPrt = &pAC->GIni.GP[0]; + + switch (pPrt->PhyType) { case SK_PHY_BCOM: - pAC->I2c.SenTable[4].SenDesc = "Voltage PHY A PLL"; if (pAC->GIni.GIMacsFound == 1) { - pAC->I2c.MaxSens = 6; - } + pAC->I2c.MaxSens += 1; + } else { - pAC->I2c.MaxSens = 8; + pAC->I2c.MaxSens += 3; } break; - case SK_PHY_LONE: - pAC->I2c.MaxSens = 5; + case SK_PHY_MARV_COPPER: + pAC->I2c.MaxSens += 3; break; } + for (i = 0; i < pAC->I2c.MaxSens; i++) { + switch (i) { + case 0: + pAC->I2c.SenTable[i].SenDesc = "Temperature"; + pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN; + break; + case 1: + pAC->I2c.SenTable[i].SenDesc = "Voltage PCI"; + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN; + break; + case 2: + pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO"; + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN; + pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO; + break; + case 3: + pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC"; + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN; + break; + case 4: + if (pPrt->PhyType == SK_PHY_BCOM) { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } + else if (pPrt->PhyType == SK_PHY_MARV_COPPER) { + pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; + if (pAC->GIni.GIVauxAvail) { + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR; + } + } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; + break; + case 5: + if (pPrt->PhyType == SK_PHY_MARV_COPPER) { + pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; + } + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN; + break; + case 6: + if (pPrt->PhyType == SK_PHY_MARV_COPPER) { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3"; + } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; + } + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN; + break; + case 7: + if (pPrt->PhyType == SK_PHY_MARV_COPPER) { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; + } + else { + pAC->I2c.SenTable[i].SenDesc = "Speed Fan"; + pAC->I2c.SenTable[i].SenType = SK_SEN_FAN; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; + } + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, + SKERR_I2C_E001, SKERR_I2C_E001MSG); + break; + } + + pAC->I2c.SenTable[i].SenValue = 0; + pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; + pAC->I2c.SenTable[i].SenErrCts = 0; + pAC->I2c.SenTable[i].SenBegErrTS = 0; + pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; + pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor; + pAC->I2c.SenTable[i].SenDev = LM80_ADDR; + } + #ifndef SK_DIAG pAC->I2c.DummyReads = pAC->I2c.MaxSens; - - /* Clear the interrupt source */ - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); #endif /* !SK_DIAG */ + /* Clear I2C IRQ */ + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); + /* Now we are I/O initialized */ pAC->I2c.InitLevel = SK_INIT_IO; return(0); @@ -900,7 +1025,7 @@ /* * Init level 2: Start first sensor read. */ -static int SkI2cInit2( +static int SkI2cInit2( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC) /* I/O Context */ { @@ -977,13 +1102,13 @@ * * Starts the timer if necessary. */ -void SkI2cIsr( +void SkI2cIsr( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC) /* I/O Context */ { SK_EVPARA Para; - /* Clear the interrupt source */ + /* Clear I2C IRQ */ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); Para.Para64 = 0; @@ -994,7 +1119,7 @@ /* * Check this sensors Value against the threshold and send events. */ -static void SkI2cCheckSensor( +static void SkI2cCheckSensor( SK_AC *pAC, /* Adapter Context */ SK_SENSOR *pSen) { @@ -1008,7 +1133,7 @@ /* Check Dummy Reads first */ if (pAC->I2c.DummyReads > 0) { - pAC->I2c.DummyReads --; + pAC->I2c.DummyReads--; return; } @@ -1016,7 +1141,7 @@ CurrTime = SkOsGetTime(pAC); /* Set para to the most useful setting: The current sensor. */ - ParaLocal.Para64 = (SK_U64) pAC->I2c.CurrSens; + ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; /* Check the Value against the thresholds. First: Error Thresholds */ TooHigh = (pSen->SenValue > pSen->SenThreErrHigh); @@ -1053,9 +1178,9 @@ */ DoErrLog = SK_FALSE; } - } else { - /* We came from a different state */ - /* -> Set Begin Time Stamp */ + } + else { + /* We came from a different state -> Set Begin Time Stamp */ pSen->SenBegErrTS = CurrTime; pSen->SenErrFlag = SK_SEN_ERR_ERR; } @@ -1063,7 +1188,7 @@ if (DoTrapSend) { /* Set current Time */ pSen->SenLastErrTrapTS = CurrTime; - pSen->SenErrCts ++; + pSen->SenErrCts++; /* Queue PNMI Event */ SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? @@ -1095,7 +1220,6 @@ TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh); TooLow = (pSen->SenValue < pSen->SenThreWarnLow); - if (!IsError && (TooHigh || TooLow)) { /* Error condition is satisfied */ DoTrapSend = SK_TRUE; @@ -1123,9 +1247,9 @@ */ DoErrLog = SK_FALSE; } - } else { - /* We came from a different state */ - /* -> Set Begin Time Stamp */ + } + else { + /* We came from a different state -> Set Begin Time Stamp */ pSen->SenBegWarnTS = CurrTime; pSen->SenErrFlag = SK_SEN_ERR_WARN; } @@ -1133,7 +1257,7 @@ if (DoTrapSend) { /* Set current Time */ pSen->SenLastWarnTrapTS = CurrTime; - pSen->SenWarnCts ++; + pSen->SenWarnCts++; /* Queue PNMI Event */ SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? @@ -1168,6 +1292,43 @@ /* End of check against the thresholds */ + /* Bug fix AF: 16.Aug.2001: Correct the init base + * of LM80 sensor. + */ + if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { + + pSen->SenInit = SK_SEN_DYN_INIT_NONE; + + if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { + /* 5V PCI-IO Voltage */ + pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; + } + else { + /* 3.3V PCI-IO Voltage */ + pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; + pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; + } + } + +#if 0 + /* Dynamic thresholds also for VAUX of LM80 sensor */ + if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { + + pSen->SenInit = SK_SEN_DYN_INIT_NONE; + + /* 3.3V VAUX Voltage */ + if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { + pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; + } + /* 0V VAUX Voltage */ + else { + pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; + pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; + } + } + /* * Check initialization state: * The VIO Thresholds need adaption @@ -1175,20 +1336,21 @@ if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && pSen->SenValue > SK_SEN_WARNLOW2C && pSen->SenValue < SK_SEN_WARNHIGH2) { - pSen->SenThreErrLow = SK_SEN_ERRLOW2C; - pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; + pSen->SenThreErrLow = SK_SEN_ERRLOW2C; + pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; pSen->SenInit = SK_TRUE; } if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && pSen->SenValue > SK_SEN_WARNLOW2 && pSen->SenValue < SK_SEN_WARNHIGH2C) { - pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; - pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; + pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; + pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; pSen->SenInit = SK_TRUE; } +#endif - if (!pSen->SenInit) { + if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); } } /* SkI2cCheckSensor*/ @@ -1210,9 +1372,13 @@ SK_EVPARA ParaLocal; int i; + /* New case: no sensors */ + if (pAC->I2c.MaxSens == 0) { + return(0); + } + switch (Event) { case SK_I2CEV_IRQ: - case SK_I2CEV_TIM: pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); @@ -1220,23 +1386,92 @@ /* Check sensor against defined thresholds */ SkI2cCheckSensor (pAC, pSen); - /* Increment Current and set appropriate Timeout */ - Time = SK_I2C_TIM_SHORT; + /* Increment Current sensor and set appropriate Timeout */ + pAC->I2c.CurrSens++; + if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { + pAC->I2c.CurrSens = 0; + Time = SK_I2C_TIM_LONG; + } + else { + Time = SK_I2C_TIM_SHORT; + } + + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; - pAC->I2c.CurrSens ++; + pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + else { + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + break; + case SK_I2CEV_TIM: + if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { + + ParaLocal.Para64 = (SK_U64)0; + SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); + + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); + + if (ReadComplete) { + /* Check sensor against defined thresholds */ + SkI2cCheckSensor (pAC, pSen); + + /* Increment Current sensor and set appropriate Timeout */ + pAC->I2c.CurrSens++; + if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { + pAC->I2c.CurrSens = 0; + Time = SK_I2C_TIM_LONG; + } + else { + Time = SK_I2C_TIM_SHORT; + } + + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + } + else { + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + pSen->SenErrFlag = SK_SEN_ERR_FAULTY; + SK_I2C_STOP(IoC); + + /* Increment Current sensor and set appropriate Timeout */ + pAC->I2c.CurrSens++; if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { pAC->I2c.CurrSens = 0; Time = SK_I2C_TIM_LONG; } + else { + Time = SK_I2C_TIM_SHORT; + } /* Start Timer */ - ParaLocal.Para64 = (SK_U64) 0; + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); } break; case SK_I2CEV_CLEAR: - for (i = 0; i < SK_MAX_SENSORS; i ++) { + for (i = 0; i < SK_MAX_SENSORS; i++) { pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; pAC->I2c.SenTable[i].SenErrCts = 0; pAC->I2c.SenTable[i].SenWarnCts = 0; @@ -1255,4 +1490,4 @@ return(0); } /* SkI2cEvent*/ -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/sklm80.c linux.21pre4-ac6/drivers/net/sk98lin/sklm80.c --- linux.21pre4/drivers/net/sk98lin/sklm80.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/sklm80.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: sklm80.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.17 $ - * Date: $Date: 1999/11/22 13:35:51 $ + * Version: $Revision: 1.20 $ + * Date: $Date: 2002/08/13 09:16:27 $ * Purpose: Funktions to access Voltage and Temperature Sensor (LM80) * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -27,6 +26,16 @@ * History: * * $Log: sklm80.c,v $ + * Revision 1.20 2002/08/13 09:16:27 rschmidt + * Changed return value for SkLm80ReadSensor() back to 'int' + * Editorial changes + * + * Revision 1.19 2002/08/06 09:43:31 jschmalz + * Extensions and changes for Yukon + * + * Revision 1.18 2002/08/02 12:26:57 rschmidt + * Editorial changes + * * Revision 1.17 1999/11/22 13:35:51 cgoos * Changed license header to GPL. * @@ -93,7 +102,7 @@ LM80 functions */ static const char SysKonnectFileId[] = - "$Id: sklm80.c,v 1.17 1999/11/22 13:35:51 cgoos Exp $" ; + "$Id: sklm80.c,v 1.20 2002/08/13 09:16:27 rschmidt Exp $" ; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" @@ -107,15 +116,15 @@ #ifdef SK_DIAG /* - * read the regeister 'reg' from the device 'device' + * read the register 'Reg' from the device 'Dev' * * return read error -1 * success the read value */ int SkLm80RcvReg( SK_IOC IoC, /* Adapter Context */ -int Dev, /* I2C device address */ -int Reg) /* register to read */ +int Dev, /* I2C device address */ +int Reg) /* register to read */ { int Val = 0; int TempExt; @@ -134,9 +143,9 @@ return(-1); } - switch(Reg) { + switch (Reg) { case LM80_TEMP_IN: - Val = (int)SkI2cRcvByte(IoC, 1) ; + Val = (int)SkI2cRcvByte(IoC, 1); /* First: correct the value: it might be negative */ if ((Val & 0x80) != 0) { @@ -145,7 +154,9 @@ } Val = Val * SK_LM80_TEMP_LSB; SkI2cStop(IoC); - TempExt = (int) SkLm80RcvReg(IoC,LM80_ADDR,LM80_TEMP_CTRL); + + TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL); + if (Val > 0) { Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); } @@ -158,10 +169,11 @@ case LM80_VT1_IN: case LM80_VT2_IN: case LM80_VT3_IN: - Val = (int) SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; + Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; break; + default: - Val = (int) SkI2cRcvByte(IoC, 1); + Val = (int)SkI2cRcvByte(IoC, 1); break; } @@ -173,30 +185,32 @@ /* * read a sensors value (LM80 specific) * - * This function reads a sensors value from the I2c sensor chip LM80. The - * sensor is defined by its index into the sensors database in the struct + * This function reads a sensors value from the I2C sensor chip LM80. + * The sensor is defined by its index into the sensors database in the struct * pAC points to. * * Returns 1 if the read is completed - * 0 if the read must be continued (I2c Bus still allocated) + * 0 if the read must be continued (I2C Bus still allocated) */ -int SkLm80ReadSensor( +int SkLm80ReadSensor( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IoContext needed in level 1 and 2 */ +SK_IOC IoC, /* I/O Context needed in level 1 and 2 */ SK_SENSOR *pSen) /* Sensor to be read */ { SK_I32 Value; - switch(pSen->SenState) { + switch (pSen->SenState) { case SK_SEN_IDLE: /* Send address to ADDR register */ - SK_I2C_CTL(IoC,I2C_READ,pSen->SenDev,pSen->SenReg,0); + SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0); pSen->SenState = SK_SEN_VALUE ; - BREAK_OR_WAIT(pAC, IoC, I2C_READ) ; + BREAK_OR_WAIT(pAC, IoC, I2C_READ); + case SK_SEN_VALUE: /* Read value from data register */ - SK_IN32(IoC,B2_I2C_DATA, ((SK_U32 *)&Value)); + SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); + Value &= 0xff; /* only least significant byte is valid */ /* Do NOT check the Value against the thresholds */ @@ -228,10 +242,9 @@ Value = Value - 256; } - /* We have a temperature sensor and need to get the signed - * extension. For now we get the extension from the last - * reading, so in the normal case we won't see flickering - * temperatures. + /* We have a temperature sensor and need to get the signed extension. + * For now we get the extension from the last reading, so in the normal + * case we won't see flickering temperatures. */ pSen->SenValue = (Value * SK_LM80_TEMP_LSB) + (pSen->SenValue % SK_LM80_TEMP_LSB); @@ -240,32 +253,34 @@ SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0); pSen->SenState = SK_SEN_VALEXT ; - BREAK_OR_WAIT(pAC, IoC, I2C_READ) ; + BREAK_OR_WAIT(pAC, IoC, I2C_READ); + case SK_SEN_VALEXT: /* Read value from data register */ - SK_IN32(IoC,B2_I2C_DATA,((SK_U32 *)&Value)); + SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */ /* cut the LSB bit */ pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) * - SK_LM80_TEMP_LSB) ; + SK_LM80_TEMP_LSB); if (pSen->SenValue < 0) { /* Value negative: The bit value must be subtracted */ pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB); - } else { + } + else { /* Value positive: The bit value must be added */ pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB); } pSen->SenState = SK_SEN_IDLE ; return(1); + default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, - SKERR_I2C_E007MSG) ; + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG); return(1); } /* Not completed */ - return(0) ; + return(0); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skproc.c linux.21pre4-ac6/drivers/net/sk98lin/skproc.c --- linux.21pre4/drivers/net/sk98lin/skproc.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skproc.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skproc.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.2.2.2 $ - * Date: $Date: 2001/03/15 12:50:13 $ + * Version: $Revision: 1.3 $ + * Date: $Date: 2002/10/02 12:59:51 $ * Purpose: Funktions to display statictic data * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -28,6 +28,31 @@ * History: * * $Log: skproc.c,v $ + * Revision 1.3 2002/10/02 12:59:51 mlindner + * Add: Support for Yukon + * Add: Speed check and setup + * Add: Merge source for kernel 2.2.x and 2.4.x + * Add: Read sensor names directly from VPD + * Fix: Volt values + * + * Revision 1.2.2.7 2002/01/14 12:45:15 mlindner + * Fix: Editorial changes + * + * Revision 1.2.2.6 2001/12/06 15:26:07 mlindner + * Fix: Return value of proc_read + * + * Revision 1.2.2.5 2001/12/06 09:57:39 mlindner + * New ProcFs entries + * + * Revision 1.2.2.4 2001/09/05 12:16:02 mlindner + * Add: New ProcFs entries + * Fix: Counter Errors (Jumbo == to long errors) + * Fix: Kernel error compilation + * Fix: too short counters + * + * Revision 1.2.2.3 2001/06/25 07:26:26 mlindner + * Add: More error messages + * * Revision 1.2.2.2 2001/03/15 12:50:13 mlindner * fix: ProcFS owner protection * @@ -46,36 +71,24 @@ #include "h/skdrv1st.h" #include "h/skdrv2nd.h" -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -//#define SPECIAL 32 /* 0x */ -#define LARGE 64 - -extern void proc_fill_inode(struct inode *inode, int fill); -extern char * SkNumber(char * str, long long num, int base, int size, - int precision ,int type); -int proc_read(char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data); - -static const char SK_Root_Dir_entry[] = "sk98lin"; -extern struct net_device *sk98lin_root_dev; - - -struct proc_dir_entry pSkRootDir = { - 0, - sizeof(SK_Root_Dir_entry)-1, - (const char*)SK_Root_Dir_entry, - S_IFDIR | S_IRUGO, - 2, 0, 0, 0, NULL, - NULL -}; +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIALX 32 /* 0x */ +#define LARGE 64 + +extern SK_AC *pACList; +extern struct net_device *SkGeRootDev; + +extern char * SkNumber( + char * str, + long long num, + int base, + int size, + int precision, + int type); /***************************************************************************** @@ -100,13 +113,14 @@ int len = 0; int t; int i; - DEV_NET *pNet; - SK_AC *pAC; - char test_buf[100]; + DEV_NET *pNet; + SK_AC *pAC; + char test_buf[100]; + char sens_msg[50]; unsigned long Flags; unsigned int Size; - struct net_device *next; - struct net_device *SkgeProcDev = sk98lin_root_dev; + struct SK_NET_DEVICE *next; + struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; SK_PNMI_STRUCT_DATA *pPnmiStruct; SK_PNMI_STAT *pPnmiStat; @@ -122,7 +136,7 @@ for (t=pAC->GIni.GIMacsFound; t > 0; t--) { if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1) t--; - + spin_lock_irqsave(&pAC->SlowPathLock, Flags); Size = SK_PNMI_STRUCT_SIZE; SkPnmiGetStruct(pAC, pAC->IoBase, @@ -135,151 +149,214 @@ "\nDetailed statistic for device %s\n", pAC->dev[t-1]->name); len += sprintf(buffer + len, - "==================================\n"); + "=======================================\n"); /* Board statistics */ len += sprintf(buffer + len, "\nBoard statistics\n\n"); len += sprintf(buffer + len, - "Active Port %c\n", + "Active Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); len += sprintf(buffer + len, - "Preferred Port %c\n", + "Preferred Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); len += sprintf(buffer + len, - "Bus speed (Mhz) %d\n", + "Bus speed (MHz) %d\n", pPnmiStruct->BusSpeed); len += sprintf(buffer + len, - "Bus width (Bit) %d\n", + "Bus width (Bit) %d\n", pPnmiStruct->BusWidth); - - for (i=0; i < SK_MAX_SENSORS; i ++) { - if (strcmp(pAC->I2c.SenTable[i].SenDesc, - "Temperature") == 0 ) { + len += sprintf(buffer + len, + "Hardware revision v%d.%d\n", + (pAC->GIni.GIPciHwRev >> 4) & 0x0F, + pAC->GIni.GIPciHwRev & 0x0F); + + /* Print sensor informations */ + for (i=0; i < pAC->I2c.MaxSens; i ++) { + /* Check type */ + switch (pAC->I2c.SenTable[i].SenType) { + case 1: + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (C)"); len += sprintf(buffer + len, - "Temperature (C) %d.%d\n", + "%-25s %d.%02d\n", + sens_msg, pAC->I2c.SenTable[i].SenValue / 10, pAC->I2c.SenTable[i].SenValue % 10); + + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (F)"); len += sprintf(buffer + len, - "Temperature (F) %d.%d\n", + "%-25s %d.%02d\n", + sens_msg, ((((pAC->I2c.SenTable[i].SenValue) *10)*9)/5 + 3200)/100, ((((pAC->I2c.SenTable[i].SenValue) *10)*9)/5 + 3200) % 10); - } else if (strcmp(pAC->I2c.SenTable[i].SenDesc, - "Speed Fan") == 0 ) { - len += sprintf(buffer + len, - "Speed Fan %d\n", - pAC->I2c.SenTable[i].SenValue); - } else { + break; + case 2: + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (V)"); len += sprintf(buffer + len, - "%-20s %d.%d\n", - pAC->I2c.SenTable[i].SenDesc, + "%-25s %d.%03d\n", + sens_msg, pAC->I2c.SenTable[i].SenValue / 1000, pAC->I2c.SenTable[i].SenValue % 1000); + break; + case 3: + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (rpm)"); + len += sprintf(buffer + len, + "%-25s %d\n", + sens_msg, + pAC->I2c.SenTable[i].SenValue); + break; + default: + break; } } /*Receive statistics */ - len += sprintf(buffer + len, "\nReceive statistics\n\n"); len += sprintf(buffer + len, - "Received bytes %s\n", + "Received bytes %s\n", SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Received packets %s\n", + "Received packets %s\n", SkNumber(test_buf, pPnmiStat->StatRxOkCts, 10,0,-1,0)); +#if 0 + if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && + pAC->HWRevision < 12) { + pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - + pPnmiStat->StatRxShortsCts; + pPnmiStat->StatRxShortsCts = 0; + } +#endif + if (pNet->Mtu > 1500) + pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - + pPnmiStat->StatRxTooLongCts; + len += sprintf(buffer + len, - "Received errors %s\n", - SkNumber(test_buf, pPnmiStat->StatRxFcsCts, + "Receive errors %s\n", + SkNumber(test_buf, pPnmiStruct->InErrorsCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Received dropped %s\n", + "Receive drops %s\n", SkNumber(test_buf, pPnmiStruct->RxNoBufCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Received multicast %s\n", + "Received multicast %s\n", SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Received errors types\n"); + "Receive error types\n"); len += sprintf(buffer + len, - " length errors %s\n", + " length %s\n", SkNumber(test_buf, pPnmiStat->StatRxRuntCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " over errors %s\n", + " buffer overflow %s\n", SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " crc errors %s\n", + " bad crc %s\n", SkNumber(test_buf, pPnmiStat->StatRxFcsCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " frame errors %s\n", + " framing %s\n", SkNumber(test_buf, pPnmiStat->StatRxFramingCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " fifo errors %s\n", - SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " missed errors %s\n", + " missed frames %s\n", SkNumber(test_buf, pPnmiStat->StatRxMissedCts, 10, 0, -1, 0)); - + + if (pNet->Mtu > 1500) + pPnmiStat->StatRxTooLongCts = 0; + + len += sprintf(buffer + len, + " too long %s\n", + SkNumber(test_buf, pPnmiStat->StatRxTooLongCts, + 10, 0, -1, 0)); + len += sprintf(buffer + len, + " carrier extension %s\n", + SkNumber(test_buf, pPnmiStat->StatRxCextCts, + 10, 0, -1, 0)); + len += sprintf(buffer + len, + " too short %s\n", + SkNumber(test_buf, pPnmiStat->StatRxShortsCts, + 10, 0, -1, 0)); + len += sprintf(buffer + len, + " symbol %s\n", + SkNumber(test_buf, pPnmiStat->StatRxSymbolCts, + 10, 0, -1, 0)); + len += sprintf(buffer + len, + " LLC MAC size %s\n", + SkNumber(test_buf, pPnmiStat->StatRxIRLengthCts, + 10, 0, -1, 0)); + len += sprintf(buffer + len, + " carrier event %s\n", + SkNumber(test_buf, pPnmiStat->StatRxCarrierCts, + 10, 0, -1, 0)); + len += sprintf(buffer + len, + " jabber %s\n", + SkNumber(test_buf, pPnmiStat->StatRxJabberCts, + 10, 0, -1, 0)); + + /*Transmit statistics */ len += sprintf(buffer + len, "\nTransmit statistics\n\n"); len += sprintf(buffer + len, - "Transmit bytes %s\n", + "Transmited bytes %s\n", SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Transmit packets %s\n", + "Transmited packets %s\n", SkNumber(test_buf, pPnmiStat->StatTxOkCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Transmit errors %s\n", + "Transmit errors %s\n", SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Transmit dropped %s\n", + "Transmit dropped %s\n", SkNumber(test_buf, pPnmiStruct->TxNoBufCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Transmit collisions %s\n", + "Transmit collisions %s\n", SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts, 10,0,-1,0)); len += sprintf(buffer + len, - "Transmited errors types\n"); + "Transmit errors types\n"); len += sprintf(buffer + len, - " aborted errors %ld\n", + " excessive collision %ld\n", pAC->stats.tx_aborted_errors); len += sprintf(buffer + len, - " carrier errors %s\n", + " carrier %s\n", SkNumber(test_buf, pPnmiStat->StatTxCarrierCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " fifo errors %s\n", + " fifo underrun %s\n", SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " heartbeat errors %s\n", + " heartbeat %s\n", SkNumber(test_buf, pPnmiStat->StatTxCarrierCts, 10, 0, -1, 0)); len += sprintf(buffer + len, - " window errors %ld\n", + " window %ld\n", pAC->stats.tx_window_errors); + } } SkgeProcDev = next; @@ -388,7 +465,7 @@ size--; } } - if (type & SPECIAL) { + if (type & SPECIALX) { if (base == 16) size -= 2; else if (base == 8) @@ -408,7 +485,7 @@ *str++ = ' '; if (sign) *str++ = sign; - if (type & SPECIAL) { + if (type & SPECIALX) { if (base==8) *str++ = '0'; else if (base==16) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skqueue.c linux.21pre4-ac6/drivers/net/sk98lin/skqueue.c --- linux.21pre4/drivers/net/sk98lin/skqueue.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skqueue.c 2003-01-06 15:38:18.000000000 +0000 @@ -1,32 +1,23 @@ /****************************************************************************** * * Name: skqueue.c - * Project: PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.14 $ - * Date: $Date: 1998/10/15 15:11:35 $ + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.18 $ + * Date: $Date: 2002/05/07 14:11:11 $ * Purpose: Management of an event queue. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1989-1998 SysKonnect, + * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. - * All Rights Reserved * - * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT - * The copyright notice above does not evidence any - * actual or intended publication of such source code. - * - * This Module contains Proprietary Information of SysKonnect - * and should be treated as Confidential. - * - * The information in this file is provided for the exclusive use of - * the licensees of SysKonnect. - * Such users have the right to use, modify, and incorporate this code - * into products for purposes authorized by the license agreement - * provided they include this notice and the associated copyright notice - * with any such product. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -36,6 +27,18 @@ * History: * * $Log: skqueue.c,v $ + * Revision 1.18 2002/05/07 14:11:11 rwahl + * Fixed Watcom Precompiler error. + * + * Revision 1.17 2002/03/25 10:06:41 mkunz + * SkIgnoreEvent deleted + * + * Revision 1.16 2002/03/15 10:51:59 mkunz + * Added event classes for link aggregation + * + * Revision 1.15 1999/11/22 13:36:29 cgoos + * Changed license header to GPL. + * * Revision 1.14 1998/10/15 15:11:35 gklug * fix: ID_sccs to SysKonnectFileId * @@ -88,7 +91,7 @@ Event queue and dispatcher */ static const char SysKonnectFileId[] = - "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.14 1998/10/15 15:11:35 gklug Exp $" ; + "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.18 2002/05/07 14:11:11 rwahl Exp $" ; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skqueue.h" /* Queue Definitions */ @@ -168,9 +171,7 @@ while (pEv != pAC->Event.EvPut) { PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ; switch(Class = pEv->Class) { - case SKGE_DRV : /* Driver Event */ - Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; +#ifndef SK_USE_LAC_EV case SKGE_RLMT : /* RLMT Event */ Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para); break ; @@ -180,9 +181,33 @@ case SKGE_PNMI : Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para); break ; +#endif /* SK_USE_LAC_EV */ + case SKGE_DRV : /* Driver Event */ + Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; +#ifndef SK_USE_SW_TIMER case SKGE_HWAC : Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para); break ; +#else /* !SK_USE_SW_TIMER */ + case SKGE_SWT : + Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; +#endif /* !SK_USE_SW_TIMER */ +#ifdef SK_USE_LAC_EV + case SKGE_LACP : + Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; + case SKGE_RSF : + Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; + case SKGE_MARKER : + Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; + case SKGE_FD : + Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; +#endif /* SK_USE_LAC_EV */ #ifdef SK_USE_CSUM case SKGE_CSUM : Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skrlmt.c linux.21pre4-ac6/drivers/net/sk98lin/skrlmt.c --- linux.21pre4/drivers/net/sk98lin/skrlmt.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skrlmt.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,8 +2,8 @@ * * Name: skrlmt.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.61 $ - * Date: $Date: 2001/03/14 12:52:08 $ + * Version: $Revision: 1.65 $ + * Date: $Date: 2002/07/22 14:29:48 $ * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. * ******************************************************************************/ @@ -26,6 +26,23 @@ * History: * * $Log: skrlmt.c,v $ + * Revision 1.65 2002/07/22 14:29:48 rwahl + * - Removed BRK statement from debug check. + * + * Revision 1.64 2001/11/28 19:36:14 rwahl + * - RLMT Packets sent to an invalid MAC address in CLP/CLPSS mode + * (#10650). + * - Reworked fix for port switching in CLS mode (#10639) + * (no dependency to RLMT module). + * - Enabled dbg output for entry/exit of event functions. + * - Editorial changes. + * + * Revision 1.63 2001/10/26 07:53:18 afischer + * Port switching bug in `check local link` mode + * + * Revision 1.62 2001/07/03 12:16:30 mkunz + * New Flag ChgBcPrio (Change priority of last broadcast received) + * * Revision 1.61 2001/03/14 12:52:08 rassmann * Fixed reporting of active port up/down to PNMI. * @@ -255,7 +272,7 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skrlmt.c,v 1.61 2001/03/14 12:52:08 rassmann Exp $ (C) SysKonnect."; + "@(#) $Id: skrlmt.c,v 1.65 2002/07/22 14:29:48 rwahl Exp $ (C) SysKonnect."; #endif /* !defined(lint) */ #define __SKRLMT_C @@ -585,8 +602,8 @@ for (i = 0; i < SK_MAX_NETS; i++) { pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; - pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */ pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; + pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */ /* Just assuming. */ pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; @@ -714,7 +731,7 @@ FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; } else { - pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[ + PrevMacUp->PortCheck[ pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr = pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress; PrevMacUp->PortCheck[ @@ -737,7 +754,7 @@ #ifdef DEBUG for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Port %d checks %d other ports: %2X.\n", NetIdx, + ("Port %d checks %d other ports: %2X.\n", i, pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked, pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])) } @@ -773,6 +790,22 @@ SK_MBUF *pMb; SK_RLMT_PACKET *pPacket; +#ifdef DEBUG + SK_U8 CheckSrc = 0; + SK_U8 CheckDest = 0; + + for (i = 0; i < SK_MAC_ADDR_LEN; ++i) { + CheckSrc |= SrcAddr->a[i]; + CheckDest |= DestAddr->a[i]; + } + + if ((CheckSrc == 0) || (CheckDest == 0)) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR, + ("SkRlmtBuildPacket: Invalid %s%saddr.\n", + (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))) + } +#endif + if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) { pPacket = (SK_RLMT_PACKET*)pMb->pData; for (i = 0; i < SK_MAC_ADDR_LEN; i++) { @@ -1504,7 +1537,7 @@ /* Select port with the latest TimeStamp. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { -#ifdef xDEBUG +#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("TimeStamp Port %d: %08x %08x.\n", i, @@ -1521,10 +1554,8 @@ } if (PortFound) { -#if 0 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d received the last broadcast.\n", *pSelect)) -#endif /* 0 */ /* Look if another port's time stamp is similar. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { @@ -1537,7 +1568,7 @@ pAC->Rlmt.Port[i].BcTimeStamp + SK_RLMT_BC_DELTA > BcTimeStamp)) { PortFound = SK_FALSE; -#ifdef xDEBUG +#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d received a broadcast at a similar time.\n", i)) #endif /* DEBUG */ @@ -1546,10 +1577,11 @@ } } -#ifdef xDEBUG +#ifdef DEBUG if (PortFound) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_CHECK_SWITCH found Port %d receiving the substantially latest broadcast (%d).\n", + ("SK_RLMT_CHECK_SWITCH found Port %d receiving the substantially " + "latest broadcast (%d).\n", *pSelect, BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) } @@ -1794,6 +1826,13 @@ PortFound = SK_FALSE; pAC->Rlmt.CheckSwitch = SK_FALSE; +#if 0 /* RW 2001/10/18 - active port becomes always prefered one */ + if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */ + /* disable auto-fail back */ + PrefPort = Active; + } +#endif + if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) { /* Last link went down - shut down the net. */ pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN; @@ -1882,7 +1921,10 @@ * else * SwitchSoft */ - if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) { + /* check of ChgBcPrio flag added */ + if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && + (!pAC->Rlmt.Net[0].ChgBcPrio)) { + if (!PortFound) { PortFound = SkRlmtSelectBcRx( pAC, IoC, Active, PrefPort, &Para.Para32[1]); @@ -1894,6 +1936,20 @@ } } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ + /* with changed priority for last broadcast received */ + if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && + (pAC->Rlmt.Net[0].ChgBcPrio)) { + if (!PortFound) { + PortFound = SkRlmtSelectNotSuspect( + pAC, IoC, Active, PrefPort, &Para.Para32[1]); + } + + if (!PortFound) { + PortFound = SkRlmtSelectBcRx( + pAC, IoC, Active, PrefPort, &Para.Para32[1]); + } + } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ + if (!PortFound) { PortFound = SkRlmtSelectUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); @@ -1927,6 +1983,7 @@ } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ if (PortFound) { + if (Para.Para32[1] != Active) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) @@ -2698,10 +2755,8 @@ SK_U32 PortNumber; SK_U32 i; -#if 0 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_TIM Event BEGIN.\n")) -#endif /* 0 */ if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, @@ -2778,10 +2833,8 @@ SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; } -#if 0 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_TIM Event END.\n")) -#endif /* 0 */ } /* SkRlmtEvtTim */ @@ -2804,7 +2857,7 @@ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ { -#ifdef XDEBUG +#ifdef xDEBUG int j; #endif /* DEBUG */ @@ -2820,7 +2873,7 @@ } #ifdef xDEBUG - for (j = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) { + for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) { SK_ADDR_PORT *pAPort; SK_U32 k; SK_U16 *InAddr; @@ -2842,7 +2895,7 @@ pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])) } } -#endif /* DEBUG */ +#endif /* xDEBUG */ SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]); @@ -2874,10 +2927,9 @@ SK_MBUF *pNextMb; SK_U32 NetNumber; -#if 0 + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")) -#endif /* 0 */ /* Should we ignore frames during port switching? */ @@ -2905,10 +2957,8 @@ } } -#if 0 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PACKET_RECEIVED Event END.\n")) -#endif /* 0 */ } /* SkRlmtEvtPacketRx */ @@ -2987,6 +3037,9 @@ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, + ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")) + if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) @@ -3003,15 +3056,10 @@ return; } -#if 0 - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")) - /* Update statistics - currently always up-to-date. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_STATS_UPDATE Event END.\n")) -#endif /* 0 */ } /* SkRlmtEvtStatsUpdate */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/sktimer.c linux.21pre4-ac6/drivers/net/sk98lin/sktimer.c --- linux.21pre4/drivers/net/sk98lin/sktimer.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/sktimer.c 2003-01-06 15:38:18.000000000 +0000 @@ -1,32 +1,23 @@ /****************************************************************************** * * Name: sktimer.c - * Project: PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.11 $ - * Date: $Date: 1998/12/17 13:24:13 $ + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.12 $ + * Date: $Date: 1999/11/22 13:38:51 $ * Purpose: High level timer functions. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1989-1998 SysKonnect, + * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. - * All Rights Reserved * - * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT - * The copyright notice above does not evidence any - * actual or intended publication of such source code. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This Module contains Proprietary Information of SysKonnect - * and should be treated as Confidential. - * - * The information in this file is provided for the exclusive use of - * the licensees of SysKonnect. - * Such users have the right to use, modify, and incorporate this code - * into products for purposes authorized by the license agreement - * provided they include this notice and the associated copyright notice - * with any such product. * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -36,6 +27,9 @@ * History: * * $Log: sktimer.c,v $ + * Revision 1.12 1999/11/22 13:38:51 cgoos + * Changed license header to GPL. + * * Revision 1.11 1998/12/17 13:24:13 gklug * fix: restart problem: do NOT destroy timer queue if init 1 is done * @@ -82,7 +76,7 @@ Event queue and dispatcher */ static const char SysKonnectFileId[] = - "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.11 1998/12/17 13:24:13 gklug Exp $" ; + "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.12 1999/11/22 13:38:51 cgoos Exp $" ; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skvpd.c linux.21pre4-ac6/drivers/net/sk98lin/skvpd.c --- linux.21pre4/drivers/net/sk98lin/skvpd.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skvpd.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,16 +2,15 @@ * * Name: skvpd.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.26 $ - * Date: $Date: 2000/06/13 08:00:01 $ + * Version: $Revision: 1.32 $ + * Date: $Date: 2002/10/14 16:04:29 $ * Purpose: Shared software to read and write VPD data * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -27,6 +26,32 @@ * History: * * $Log: skvpd.c,v $ + * Revision 1.32 2002/10/14 16:04:29 rschmidt + * Added saving of VPD ROM Size from PCI_OUR_REG_2 + * Avoid reading of PCI_OUR_REG_2 in VpdTransferBlock() + * Editorial changes + * + * Revision 1.31 2002/09/10 09:21:32 mkarl + * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis + * + * Revision 1.30 2002/09/09 14:43:03 mkarl + * changes for diagnostics in order to read VPD data before the adapter + * has been initialized + * editorial changes + * + * Revision 1.29 2002/07/26 13:20:43 mkarl + * added Yukon support + * save size of VPD in pAC->vpd.vpd_size + * + * Revision 1.28 2002/04/02 15:31:47 afischer + * Bug fix in VpdWait() + * + * Revision 1.27 2000/08/10 11:29:06 rassmann + * Editorial changes. + * Preserving 32-bit alignment in structs for the adapter context. + * Removed unused function VpdWriteDword() (#if 0). + * Made VpdReadKeyword() available for SKDIAG only. + * * Revision 1.26 2000/06/13 08:00:01 mkarl * additional cast to avoid compile problems in 64 bit environment * @@ -66,7 +91,7 @@ * * Revision 1.14 1998/10/28 07:20:38 gklug * chg: Interface functions to use IoC as parameter as well - * fix: VpdRead/WriteDWord now return SK_U32 + * fix: VpdRead/WriteDWord now returns SK_U32 * chg: VPD_IN/OUT names conform to SK_IN/OUT * add: usage of VPD_IN/OUT8 macros * add: VpdRead/Write Stream functions to r/w a stream of data @@ -88,7 +113,7 @@ * Revision 1.9 1998/09/16 07:33:52 malthoff * remove memcmp() by SK_MEMCMP and * memcpy() by SK_MEMCPY() to be - * independant from the 'C' Standard Library. + * independent from the 'C' Standard Library. * * Revision 1.8 1998/08/19 12:52:35 malthoff * compiler fix: use SK_VPD_KEY instead of S_VPD. @@ -124,7 +149,7 @@ Please refer skvpd.txt for infomation how to include this module */ static const char SysKonnectFileId[] = - "@(#)$Id: skvpd.c,v 1.26 2000/06/13 08:00:01 mkarl Exp $ (C) SK" ; + "@(#)$Id: skvpd.c,v 1.32 2002/10/14 16:04:29 rschmidt Exp $ (C) SK"; #include "h/skdrv1st.h" #include "h/sktypes.h" @@ -137,46 +162,58 @@ #ifndef SK_KR_PROTO static SK_VPD_PARA *vpd_find_para( SK_AC *pAC, - char *key, - SK_VPD_PARA *p) ; + char *key, + SK_VPD_PARA *p); #else /* SK_KR_PROTO */ -static SK_VPD_PARA *vpd_find_para() ; +static SK_VPD_PARA *vpd_find_para(); #endif /* SK_KR_PROTO */ /* - * waits for a completetion of a VPD transfer + * waits for a completion of a VPD transfer * The VPD transfer must complete within SK_TICKS_PER_SEC/16 * * returns 0: success, transfer completes * error exit(9) with a error message */ static int VpdWait( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC, /* IO Context */ int event) /* event to wait for (VPD_READ / VPD_write) completion*/ { - SK_U64 start_time ; - SK_U16 state ; + SK_U64 start_time; + SK_U16 state; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd wait for %s\n",event?"Write":"Read")) ; - start_time = SkOsGetTime(pAC) ; + SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD wait for %s\n", event?"Write":"Read")); + start_time = SkOsGetTime(pAC); do { if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC/16) { - VPD_STOP(pAC,IoC) ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD, - SK_DBGCAT_FATAL|SK_DBGCAT_ERR, - ("ERROR:vpd wait timeout\n")) ; - return(1) ; - } - VPD_IN16(pAC,IoC,PCI_VPD_ADR_REG,&state) ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("state = %x, event %x\n",state,event)) ; - } while((int)(state & PCI_VPD_FLAG) == event) ; - return(0) ; + /* Bug fix AF: Thu Mar 28 2002 + * Do not call: VPD_STOP(pAC, IoC); + * A pending VPD read cycle can not be aborted by writing + * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register). + * Although the write threshold in the OUR-register protects + * VPD read only space from being overwritten this does not + * protect a VPD read from being `converted` into a VPD write + * operation (on the fly). As a consequence the VPD_STOP would + * delete VPD read only data. In case of any problems with the + * I2C bus we exit the loop here. The I2C read operation can + * not be aborted except by a reset (->LR). + */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR, + ("ERROR:VPD wait timeout\n")); + return(1); + } + VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("state = %x, event %x\n",state,event)); + } while((int)(state & PCI_VPD_FLAG) == event); + + return(0); } +#ifdef SKDIAG /* * Read the dword at address 'addr' from the VPD EEPROM. @@ -188,32 +225,37 @@ * * Returns the data read. */ -SK_U32 VpdReadDWord( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ +SK_U32 VpdReadDWord( +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC, /* IO Context */ int addr) /* VPD address */ { - SK_U32 Rtv ; + SK_U32 Rtv; /* start VPD read */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd read dword at 0x%x\n",addr)) ; - addr &= ~VPD_WRITE ; /* ensure the R/W bit is set to read */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD read dword at 0x%x\n",addr)); + addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */ - VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16) addr) ; + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr); /* ignore return code here */ - (void)VpdWait(pAC,IoC,VPD_READ) ; + (void)VpdWait(pAC, IoC, VPD_READ); /* Don't swap here, it's a data stream of bytes */ - Rtv = 0 ; + Rtv = 0; - VPD_IN32(pAC,IoC,PCI_VPD_DAT_REG,&Rtv) ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd read dword data = 0x%x\n",Rtv)) ; - return (Rtv) ; + VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv); + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD read dword data = 0x%x\n",Rtv)); + return(Rtv); } +#endif /* SKDIAG */ + +#if 0 + /* Write the dword 'data' at address 'addr' into the VPD EEPROM, and verify that the data is written. @@ -233,43 +275,43 @@ Returns 0: success - 1: error, I2C transfer does not terminate - 2: error, data verify error + 1: error, I2C transfer does not terminate + 2: error, data verify error */ -#if 0 /* Unused at the moment */ -static int VpdWriteDWord( -SK_AC *pAC, /* pAC pointer */ -SK_IOC IoC, /* IO Context */ +static int VpdWriteDWord( +SK_AC *pAC, /* pAC pointer */ +SK_IOC IoC, /* IO Context */ int addr, /* VPD address */ -SK_U32 data) /* VPD data to write */ +SK_U32 data) /* VPD data to write */ { /* start VPD write */ /* Don't swap here, it's a data stream of bytes */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd write dword at addr 0x%x, data = 0x%x\n",addr,data)) ; - VPD_OUT32(pAC,IoC,PCI_VPD_DAT_REG, (SK_U32)data) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data)); + VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data); /* But do it here */ - addr |= VPD_WRITE ; + addr |= VPD_WRITE; - VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)) ; + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)); /* this may take up to 10,6 ms */ - if (VpdWait(pAC,IoC,VPD_WRITE)) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("Write Timed Out\n")) ; - return(1) ; - } ; + if (VpdWait(pAC, IoC, VPD_WRITE)) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Write Timed Out\n")); + return(1); + }; /* verify data */ - if (VpdReadDWord(pAC,IoC,addr) != data) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR|SK_DBGCAT_FATAL, - ("Data Verify Error\n")) ; - return(2) ; + if (VpdReadDWord(pAC, IoC, addr) != data) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Data Verify Error\n")); + return(2); } - return(0) ; -} -#endif + return(0); +} /* VpdWriteDWord */ + +#endif /* 0 */ /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from @@ -278,88 +320,85 @@ * Returns number of bytes read / written. */ static int VpdWriteStream( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -char *buf, /* data buffer */ +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC, /* IO Context */ +char *buf, /* data buffer */ int Addr, /* VPD start address */ int Len) /* number of bytes to read / to write */ { - int i ; - int j ; - SK_U16 AdrReg ; - int Rtv ; - SK_U8 * pComp; /* Compare pointer */ - SK_U8 Data ; /* Input Data for Compare */ + int i; + int j; + SK_U16 AdrReg; + int Rtv; + SK_U8 * pComp; /* Compare pointer */ + SK_U8 Data; /* Input Data for Compare */ /* Init Compare Pointer */ pComp = (SK_U8 *) buf; - for (i=0; i < Len; i ++, buf++) { + for (i = 0; i < Len; i++, buf++) { if ((i%sizeof(SK_U32)) == 0) { /* * At the begin of each cycle read the Data Reg * So it is initialized even if only a few bytes * are written. */ - AdrReg = (SK_U16) Addr ; - AdrReg &= ~VPD_WRITE ; /* READ operation */ + AdrReg = (SK_U16) Addr; + AdrReg &= ~VPD_WRITE; /* READ operation */ - VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ; + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); - /* ignore return code here */ - Rtv = VpdWait(pAC,IoC,VPD_READ) ; + /* Wait for termination */ + Rtv = VpdWait(pAC, IoC, VPD_READ); if (Rtv != 0) { - return(i) ; + return(i); } } /* Write current Byte */ - VPD_OUT8(pAC,IoC,PCI_VPD_DAT_REG+(i%sizeof(SK_U32)), - *(SK_U8*)buf) ; + VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), + *(SK_U8*)buf); if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) { /* New Address needs to be written to VPD_ADDR reg */ - AdrReg = (SK_U16) Addr ; + AdrReg = (SK_U16) Addr; Addr += sizeof(SK_U32); - AdrReg |= VPD_WRITE ; /* WRITE operation */ + AdrReg |= VPD_WRITE; /* WRITE operation */ - VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ; + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); /* Wait for termination */ - Rtv = VpdWait(pAC,IoC,VPD_WRITE) ; + Rtv = VpdWait(pAC, IoC, VPD_WRITE); if (Rtv != 0) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("Write Timed Out\n")) ; - return(i - (i%sizeof(SK_U32))) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Write Timed Out\n")); + return(i - (i%sizeof(SK_U32))); } /* * Now re-read to verify */ - AdrReg &= ~VPD_WRITE ; /* READ operation */ + AdrReg &= ~VPD_WRITE; /* READ operation */ - VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ; + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); /* Wait for termination */ - Rtv = VpdWait(pAC,IoC,VPD_READ) ; + Rtv = VpdWait(pAC, IoC, VPD_READ); if (Rtv != 0) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("Verify Timed Out\n")) ; - return(i - (i%sizeof(SK_U32))) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Verify Timed Out\n")); + return(i - (i%sizeof(SK_U32))); } - for (j = 0; j <= (int) (i%sizeof(SK_U32)); - j ++, pComp ++ ) { - VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+j, &Data) ; + for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) { + VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data); if (Data != *pComp) { /* Verify Error */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD, - SK_DBGCAT_ERR, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("WriteStream Verify Error\n")); return(i - (i%sizeof(SK_U32)) + j); } } - } } @@ -374,85 +413,85 @@ * Returns number of bytes read / written. */ static int VpdReadStream( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -char *buf, /* data buffer */ +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC, /* IO Context */ +char *buf, /* data buffer */ int Addr, /* VPD start address */ int Len) /* number of bytes to read / to write */ { - int i ; - SK_U16 AdrReg ; - int Rtv ; + int i; + SK_U16 AdrReg; + int Rtv; - for (i=0; i < Len; i ++, buf++) { + for (i = 0; i < Len; i++, buf++) { if ((i%sizeof(SK_U32)) == 0) { /* New Address needs to be written to VPD_ADDR reg */ - AdrReg = (SK_U16) Addr ; + AdrReg = (SK_U16) Addr; Addr += sizeof(SK_U32); - AdrReg &= ~VPD_WRITE ; /* READ operation */ + AdrReg &= ~VPD_WRITE; /* READ operation */ - VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ; + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); - /* ignore return code here */ - Rtv = VpdWait(pAC,IoC,VPD_READ) ; + /* Wait for termination */ + Rtv = VpdWait(pAC, IoC, VPD_READ); if (Rtv != 0) { - return(i) ; + return(i); } - } - VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+(i%sizeof(SK_U32)), - (SK_U8 *)buf) ; + VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), + (SK_U8 *)buf); } - return(Len) ; + return(Len); } /* - * Read ore wirtes 'len' bytes of VPD data, starting at 'addr' from + * Read ore writes 'len' bytes of VPD data, starting at 'addr' from * or to the I2C EEPROM. * * Returns number of bytes read / written. */ static int VpdTransferBlock( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -char *buf, /* data buffer */ +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC, /* IO Context */ +char *buf, /* data buffer */ int addr, /* VPD start address */ int len, /* number of bytes to read / to write */ int dir) /* transfer direction may be VPD_READ or VPD_WRITE */ { - int Rtv ; /* Return value */ - int vpd_rom_size ; - SK_U32 our_reg2 ; - - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd %s block, addr = 0x%x, len = %d\n", - dir?"write":"read",addr,len)) ; + int Rtv; /* Return value */ + int vpd_rom_size; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD %s block, addr = 0x%x, len = %d\n", + dir ? "write" : "read", addr, len)); if (len == 0) - return (0) ; + return(0); - VPD_IN32(pAC,IoC,PCI_OUR_REG_2,&our_reg2) ; - vpd_rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); + vpd_rom_size = pAC->vpd.rom_size; + if (addr > vpd_rom_size - 4) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR|SK_DBGCAT_FATAL, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ("Address error: 0x%x, exp. < 0x%x\n", - addr, vpd_rom_size - 4)) ; - return (0) ; + addr, vpd_rom_size - 4)); + return(0); } + if (addr + len > vpd_rom_size) { - len = vpd_rom_size - addr ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("Warning: len was cut to %d\n",len)) ; + len = vpd_rom_size - addr; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Warning: len was cut to %d\n", len)); } if (dir == VPD_READ) { Rtv = VpdReadStream(pAC, IoC, buf, addr, len); - } else { + } + else { Rtv = VpdWriteStream(pAC, IoC, buf, addr, len); } - return (Rtv) ; + return(Rtv); } #ifdef SKDIAG @@ -463,13 +502,13 @@ * Returns number of bytes read. */ int VpdReadBlock( -SK_AC *pAC, /* pAC pointer */ -SK_IOC IoC, /* IO Context */ -char *buf, /* buffer were the data should be stored */ +SK_AC *pAC, /* pAC pointer */ +SK_IOC IoC, /* IO Context */ +char *buf, /* buffer were the data should be stored */ int addr, /* start reading at the VPD address */ int len) /* number of bytes to read */ { - return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)) ; + return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)); } /* @@ -478,13 +517,13 @@ * Returns number of bytes writes. */ int VpdWriteBlock( -SK_AC *pAC, /* pAC pointer */ -SK_IOC IoC, /* IO Context */ -char *buf, /* buffer, holds the data to write */ +SK_AC *pAC, /* pAC pointer */ +SK_IOC IoC, /* IO Context */ +char *buf, /* buffer, holds the data to write */ int addr, /* start writing at the VPD address */ int len) /* number of bytes to write */ { - return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)) ; + return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)); } #endif /* SKDIAG */ @@ -498,72 +537,112 @@ * 1: fatal VPD error */ static int VpdInit( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC) /* IO Context */ +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC) /* IO Context */ { - SK_VPD_PARA *r, rp ; /* RW or RV */ - int i ; - unsigned char x ; + SK_VPD_PARA *r, rp; /* RW or RV */ + int i; + unsigned char x; + int vpd_size; + SK_U16 word; + SK_U32 our_reg2; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. ")); + + VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &word); + + VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); + + pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); + + /* + * this function might get used before the hardware is initialized + * therefore we cannot always trust in GIChipId + */ + if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 && + word == VPD_PCI_ID_YUKON) || + ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 && + !(pAC->GIni.GIGenesis))) { + + /* for Yukon the VPD size is always 256 */ + vpd_size = VPD_SIZE_YUKON; + } + else { + /* Genesis uses the maximum ROM size up to 512 for VPD */ + if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) { + vpd_size = VPD_SIZE_GENESIS; + } + else { + vpd_size = pAC->vpd.rom_size; + } + } - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,("VpdInit .. ")) ; /* read the VPD data into the VPD buffer */ - if (VpdTransferBlock(pAC,IoC,pAC->vpd.vpd_buf,0,VPD_SIZE,VPD_READ) - != VPD_SIZE) { + if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ) + != vpd_size) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("Block Read Error\n")) ; - return(1) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Block Read Error\n")); + return(1); } + + pAC->vpd.vpd_size = vpd_size; /* find the end tag of the RO area */ - if (!(r = vpd_find_para(pAC,VPD_RV,&rp))) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: RV Tag not found\n")) ; - return (1) ; + if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Encoding Error: RV Tag not found\n")); + return(1); } - if (r->p_val + r->p_len > pAC->vpd.vpd_buf + VPD_SIZE/2) { + + if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) { SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: Invalid VPD struct size\n")) ; - return (1) ; + ("Encoding Error: Invalid VPD struct size\n")); + return(1); } - pAC->vpd.v.vpd_free_ro = r->p_len - 1 ; + pAC->vpd.v.vpd_free_ro = r->p_len - 1; /* test the checksum */ - for (i = 0, x = 0; (unsigned)i<=(unsigned)VPD_SIZE/2 - r->p_len; i++) { - x += pAC->vpd.vpd_buf[i] ; + for (i = 0, x = 0; (unsigned)i<=(unsigned)vpd_size/2 - r->p_len; i++) { + x += pAC->vpd.vpd_buf[i]; } + if (x != 0) { /* checksum error */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("VPD Checksum Error\n")) ; - return (1) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("VPD Checksum Error\n")); + return(1); } /* find and check the end tag of the RW area */ - if (!(r = vpd_find_para(pAC,VPD_RW,&rp))) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: RV Tag not found\n")) ; - return (1) ; + if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Encoding Error: RV Tag not found\n")); + return(1); } - if (r->p_val < pAC->vpd.vpd_buf + VPD_SIZE/2) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: Invalid VPD struct size\n")) ; - return (1) ; + + if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Encoding Error: Invalid VPD struct size\n")); + return(1); } - pAC->vpd.v.vpd_free_rw = r->p_len ; + pAC->vpd.v.vpd_free_rw = r->p_len; /* everything seems to be ok */ - pAC->vpd.v.vpd_status |= VPD_VALID ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT, + if (pAC->GIni.GIChipId != 0) { + pAC->vpd.v.vpd_status |= VPD_VALID; + } + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("done. Free RO = %d, Free RW = %d\n", - pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)) ; + pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)); - return(0) ; + return(0); } /* * find the Keyword 'key' in the VPD buffer and fills the - * parameter sturct 'p' with it's values + * parameter struct 'p' with it's values * * returns *p success * 0: parameter was not found or VPD encoding error @@ -573,63 +652,64 @@ char *key, /* keyword to find (e.g. "MN") */ SK_VPD_PARA *p) /* parameter description struct */ { - char *v ; /* points to vpd buffer */ - int max ; /* Maximum Number of Iterations */ + char *v ; /* points to VPD buffer */ + int max; /* Maximum Number of Iterations */ - v = pAC->vpd.vpd_buf ; - max = 128 ; + v = pAC->vpd.vpd_buf; + max = 128; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd find para %s .. ",key)) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD find para %s .. ",key)); /* check mandatory resource type ID string (Product Name) */ - if (*v != (char) RES_ID) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Error: 0x%x missing\n",RES_ID)) ; - return (0) ; - } - - if (strcmp(key,VPD_NAME) == 0) { - p->p_len = VPD_GET_RES_LEN(v) ; - p->p_val = VPD_GET_VAL(v) ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("found, len = %d\n",p->p_len)) ; - return(p) ; + if (*v != (char)RES_ID) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Error: 0x%x missing\n", RES_ID)); + return(0); + } + + if (strcmp(key, VPD_NAME) == 0) { + p->p_len = VPD_GET_RES_LEN(v); + p->p_val = VPD_GET_VAL(v); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("found, len = %d\n", p->p_len)); + return(p); } - v += 3 + VPD_GET_RES_LEN(v) + 3 ; - for ( ; ; ) { + v += 3 + VPD_GET_RES_LEN(v) + 3; + for (;; ) { if (SK_MEMCMP(key,v,2) == 0) { - p->p_len = VPD_GET_VPD_LEN(v) ; - p->p_val = VPD_GET_VAL(v) ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("found, len = %d\n",p->p_len)) ; - return (p) ; + p->p_len = VPD_GET_VPD_LEN(v); + p->p_val = VPD_GET_VAL(v); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("found, len = %d\n",p->p_len)); + return(p); } /* exit when reaching the "RW" Tag or the maximum of itera. */ - max-- ; + max--; if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) { - break ; + break; } if (SK_MEMCMP(VPD_RV,v,2) == 0) { - v += 3 + VPD_GET_VPD_LEN(v) + 3 ; /* skip VPD-W */ - } else { - v += 3 + VPD_GET_VPD_LEN(v) ; + v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ } - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("scanning '%c%c' len = %d\n",v[0],v[1],v[2])) ; + else { + v += 3 + VPD_GET_VPD_LEN(v); + } + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("scanning '%c%c' len = %d\n",v[0],v[1],v[2])); } #ifdef DEBUG - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,("not found\n")) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n")); if (max == 0) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Key/Len Encoding error\n")) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Key/Len Encoding error\n")); } -#endif - return (0) ; +#endif /* DEBUG */ + return(0); } /* @@ -643,24 +723,25 @@ char *end, /* end of memory block to move */ int n) /* number of bytes the memory block has to be moved */ { - char *p ; - int i ; /* number of byte copied */ + char *p; + int i; /* number of byte copied */ if (n == 0) - return ; + return; - i = (int) (end - start + 1) ; + i = (int) (end - start + 1); if (n < 0) { - p = start + n ; + p = start + n; while (i != 0) { - *p++ = *start++ ; - i-- ; + *p++ = *start++; + i--; } - } else { - p = end + n ; + } + else { + p = end + n; while (i != 0) { - *p-- = *end-- ; - i-- ; + *p-- = *end--; + i--; } } } @@ -676,13 +757,13 @@ int len, /* length of the value string */ char *ip) /* inseration point */ { - SK_VPD_KEY *p ; + SK_VPD_KEY *p; - p = (SK_VPD_KEY *) ip ; - p->p_key[0] = key[0] ; - p->p_key[1] = key[1] ; - p->p_len = (unsigned char) len ; - SK_MEMCPY(&p->p_val,buf,len) ; + p = (SK_VPD_KEY *) ip; + p->p_key[0] = key[0]; + p->p_key[1] = key[1]; + p->p_len = (unsigned char) len; + SK_MEMCPY(&p->p_val,buf,len); } /* @@ -696,46 +777,50 @@ SK_AC *pAC, /* common data base */ char *etp) /* end pointer input position */ { - SK_VPD_KEY *p ; - unsigned char x ; - int i ; + SK_VPD_KEY *p; + unsigned char x; + int i; + int vpd_size; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])); - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])) ; + vpd_size = pAC->vpd.vpd_size; - p = (SK_VPD_KEY *) etp ; + p = (SK_VPD_KEY *) etp; if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) { /* something wrong here, encoding error */ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: invalid end tag\n")) ; - return(1) ; + ("Encoding Error: invalid end tag\n")); + return(1); } - if (etp > pAC->vpd.vpd_buf + VPD_SIZE/2) { + if (etp > pAC->vpd.vpd_buf + vpd_size/2) { /* create "RW" tag */ - p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE-etp-3-1) ; - pAC->vpd.v.vpd_free_rw = (int) p->p_len ; - i = pAC->vpd.v.vpd_free_rw ; - etp += 3 ; - } else { + p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1); + pAC->vpd.v.vpd_free_rw = (int) p->p_len; + i = pAC->vpd.v.vpd_free_rw; + etp += 3; + } + else { /* create "RV" tag */ - p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE/2-etp-3) ; - pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1 ; + p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3); + pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1; /* setup checksum */ - for (i = 0, x = 0; i < VPD_SIZE/2 - p->p_len; i++) { - x += pAC->vpd.vpd_buf[i] ; + for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) { + x += pAC->vpd.vpd_buf[i]; } - p->p_val = (char) 0 - x ; - i = pAC->vpd.v.vpd_free_ro ; - etp += 4 ; + p->p_val = (char) 0 - x; + i = pAC->vpd.v.vpd_free_ro; + etp += 4; } while (i) { - *etp++ = 0x00 ; - i-- ; + *etp++ = 0x00; + i--; } - return (0) ; + return(0); } /* @@ -760,76 +845,81 @@ int type, /* VPD_RO_KEY or VPD_RW_KEY */ int op) /* operation to do: ADD_KEY or OWR_KEY */ { - SK_VPD_PARA vp ; - char *etp ; /* end tag position */ - int free ; /* remaining space in selected area */ - char *ip ; /* input position inside the VPD buffer */ - int rtv ; /* return code */ - int head ; /* additional haeder bytes to move */ - int found ; /* additinoal bytes if the keyword was found */ + SK_VPD_PARA vp; + char *etp; /* end tag position */ + int free; /* remaining space in selected area */ + char *ip; /* input position inside the VPD buffer */ + int rtv; /* return code */ + int head; /* additional haeder bytes to move */ + int found; /* additinoal bytes if the keyword was found */ + int vpd_size; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("vpd setup para key = %s, val = %s\n",key,buf)) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD setup para key = %s, val = %s\n",key,buf)); + + vpd_size = pAC->vpd.vpd_size; - rtv = 0 ; - ip = 0 ; + rtv = 0; + ip = 0; if (type == VPD_RW_KEY) { /* end tag is "RW" */ - free = pAC->vpd.v.vpd_free_rw ; - etp = pAC->vpd.vpd_buf + (VPD_SIZE - free - 1 - 3) ; - } else { + free = pAC->vpd.v.vpd_free_rw; + etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3); + } + else { /* end tag is "RV" */ - free = pAC->vpd.v.vpd_free_ro ; - etp = pAC->vpd.vpd_buf + (VPD_SIZE/2 - free - 4) ; + free = pAC->vpd.v.vpd_free_ro; + etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4); } - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("Free RO = %d, Free RW = %d\n", - pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)) ; + pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)); - head = 0 ; - found = 0 ; + head = 0; + found = 0; if (op == OWR_KEY) { - if (vpd_find_para(pAC,key,&vp)) { - found = 3 ; - ip = vp.p_val - 3 ; - free += vp.p_len + 3 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("Overwrite Key\n")) ; - } else { - op = ADD_KEY ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL, - ("Add Key\n")) ; + if (vpd_find_para(pAC, key, &vp)) { + found = 3; + ip = vp.p_val - 3; + free += vp.p_len + 3; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("Overwrite Key\n")); + } + else { + op = ADD_KEY; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("Add Key\n")); } } if (op == ADD_KEY) { - ip = etp ; - vp.p_len = 0 ; - head = 3 ; + ip = etp; + vp.p_len = 0; + head = 3; } if (len + 3 > free) { if (free < 7) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD Buffer Overflow, keyword not written\n")); - return (4) ; + return(4); } /* cut it again */ - len = free - 3 ; - rtv = 2 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("VPD Buffer Full, Keyword was cut\n")) ; + len = free - 3; + rtv = 2; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD Buffer Full, Keyword was cut\n")); } - vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head) ; - vpd_insert_key(key, buf, len, ip) ; + vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head); + vpd_insert_key(key, buf, len, ip); if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) { - pAC->vpd.v.vpd_status &= ~VPD_VALID ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("VPD Encoding Error\n")) ; - return(6) ; + pAC->vpd.v.vpd_status &= ~VPD_VALID; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD Encoding Error\n")); + return(6); } - return (rtv) ; + return(rtv); } @@ -837,7 +927,7 @@ * Read the contents of the VPD EEPROM and copy it to the * VPD buffer if not already done. * - * return: A pointer to the vpd_status structure. The structure contain + * return: A pointer to the vpd_status structure. The structure contains * this fields. */ SK_VPD_STATUS *VpdStat( @@ -845,9 +935,9 @@ SK_IOC IoC) /* IO Context */ { if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - (void)VpdInit(pAC,IoC) ; + (void)VpdInit(pAC,IoC); } - return(&pAC->vpd.v) ; + return(&pAC->vpd.v); } @@ -880,67 +970,69 @@ int *len, /* buffer length */ int *elements) /* number of keywords returned */ { - char *v ; - int n ; + char *v; + int n; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("list vpd keys .. ")) ; - *elements = 0 ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. ")); + *elements = 0; if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { if (VpdInit(pAC,IoC) != 0 ) { - *len = 0 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("VPD Init Error, terminated\n")) ; - return(6) ; + *len = 0; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD Init Error, terminated\n")); + return(6); } } if ((signed)strlen(VPD_NAME) + 1 <= *len) { - v = pAC->vpd.vpd_buf ; - strcpy(buf,VPD_NAME) ; - n = strlen(VPD_NAME) + 1 ; - buf += n ; - *elements = 1 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX, - ("'%c%c' ",v[0],v[1])) ; - } else { - *len = 0 ; + v = pAC->vpd.vpd_buf; + strcpy(buf,VPD_NAME); + n = strlen(VPD_NAME) + 1; + buf += n; + *elements = 1; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, + ("'%c%c' ",v[0],v[1])); + } + else { + *len = 0; SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("buffer overflow\n")) ; - return(2) ; + ("buffer overflow\n")); + return(2); } - v += 3 + VPD_GET_RES_LEN(v) + 3 ; - for ( ; ; ) { + v += 3 + VPD_GET_RES_LEN(v) + 3; + for (;; ) { /* exit when reaching the "RW" Tag */ if (SK_MEMCMP(VPD_RW,v,2) == 0) { - break ; + break; } if (SK_MEMCMP(VPD_RV,v,2) == 0) { - v += 3 + VPD_GET_VPD_LEN(v) + 3 ; /* skip VPD-W */ - continue ; + v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ + continue; } if (n+3 <= *len) { - SK_MEMCPY(buf,v,2) ; - buf += 2 ; - *buf++ = '\0' ; - n += 3 ; - v += 3 + VPD_GET_VPD_LEN(v) ; - *elements += 1 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX, - ("'%c%c' ",v[0],v[1])) ; - } else { - *len = n ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("buffer overflow\n")) ; - return (2) ; + SK_MEMCPY(buf,v,2); + buf += 2; + *buf++ = '\0'; + n += 3; + v += 3 + VPD_GET_VPD_LEN(v); + *elements += 1; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, + ("'%c%c' ",v[0],v[1])); + } + else { + *len = n; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("buffer overflow\n")); + return(2); } } - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("\n")) ; - *len = n ; - return(0) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n")); + *len = n; + return(0); } @@ -964,34 +1056,35 @@ char *buf, /* buffer where to copy the keyword value */ int *len) /* buffer length */ { - SK_VPD_PARA *p, vp ; + SK_VPD_PARA *p, vp; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("vpd read %s .. ",key)) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key)); if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { if (VpdInit(pAC,IoC) != 0 ) { - *len = 0 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("vpd init error\n")) ; - return(6) ; + *len = 0; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD init error\n")); + return(6); } } - if ((p = vpd_find_para(pAC,key,&vp))) { + if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { if (p->p_len > (*(unsigned *)len)-1) { - p->p_len = *len - 1 ; + p->p_len = *len - 1; } - SK_MEMCPY(buf,p->p_val,p->p_len) ; - buf[p->p_len] = '\0' ; - *len = p->p_len ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX, + SK_MEMCPY(buf, p->p_val, p->p_len); + buf[p->p_len] = '\0'; + *len = p->p_len; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("%c%c%c%c.., len = %d\n", - buf[0],buf[1],buf[2],buf[3],*len)) ; - } else { - *len = 0 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,("not found\n")) ; - return (1) ; + buf[0],buf[1],buf[2],buf[3],*len)); } - return (0) ; + else { + *len = 0; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n")); + return(1); + } + return(0); } @@ -1009,9 +1102,9 @@ key[1] < '0' || key[1] > 'Z' || (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { - return (SK_FALSE) ; + return(SK_FALSE); } - return (SK_TRUE) ; + return(SK_TRUE); } /* @@ -1033,46 +1126,46 @@ char *key, /* keyword to write (allowed values "Yx", "Vx") */ char *buf) /* buffer where the keyword value can be read from */ { - int len ; /* lenght of the keyword to write */ - int rtv ; /* return code */ - int rtv2 ; + int len; /* length of the keyword to write */ + int rtv; /* return code */ + int rtv2; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX, - ("vpd write %s = %s\n",key,buf)) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, + ("VPD write %s = %s\n",key,buf)); if ((*key != 'Y' && *key != 'V') || key[1] < '0' || key[1] > 'Z' || (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("illegal key tag, keyword not written\n")) ; - return (5) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("illegal key tag, keyword not written\n")); + return(5); } if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { if (VpdInit(pAC,IoC) != 0 ) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("vpd init error\n")) ; - return(6) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD init error\n")); + return(6); } } - rtv = 0 ; - len = strlen(buf) ; + rtv = 0; + len = strlen(buf); if (len > VPD_MAX_LEN) { /* cut it */ - len = VPD_MAX_LEN ; - rtv = 2 ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("keyword to long, cut after %d bytes\n",VPD_MAX_LEN)) ; - } - if ((rtv2 = VpdSetupPara(pAC,key,buf,len,VPD_RW_KEY,OWR_KEY)) != 0) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("vpd write error\n")) ; - return(rtv2) ; + len = VPD_MAX_LEN; + rtv = 2; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("keyword to long, cut after %d bytes\n",VPD_MAX_LEN)); + } + if ((rtv2 = VpdSetupPara(pAC, key,buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD write error\n")); + return(rtv2); } - return (rtv) ; + return(rtv); } /* @@ -1092,43 +1185,47 @@ SK_IOC IoC, /* IO Context */ char *key) /* keyword to read (e.g. "MN") */ { - SK_VPD_PARA *p, vp ; - char *etp ; + SK_VPD_PARA *p, vp; + char *etp; + int vpd_size; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd delete key %s\n",key)) ; + vpd_size = pAC->vpd.vpd_size; + + SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key)); if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { if (VpdInit(pAC,IoC) != 0 ) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("vpd init error\n")) ; - return(6) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD init error\n")); + return(6); } } - if ((p = vpd_find_para(pAC,key,&vp))) { - if (p->p_val < pAC->vpd.vpd_buf + VPD_SIZE/2) { + if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { + if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) { /* try to delete read only keyword */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("cannot delete RO keyword\n")) ; - return (5) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("cannot delete RO keyword\n")); + return(5); } - etp = pAC->vpd.vpd_buf + (VPD_SIZE-pAC->vpd.v.vpd_free_rw-1-3) ; + etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3); vpd_move_para(vp.p_val+vp.p_len, etp+2, - - ((int)(vp.p_len + 3))) ; + - ((int)(vp.p_len + 3))); if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) { - pAC->vpd.v.vpd_status &= ~VPD_VALID ; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("vpd encoding error\n")) ; - return(6) ; + pAC->vpd.v.vpd_status &= ~VPD_VALID; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD encoding error\n")); + return(6); } - } else { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("keyword not found\n")) ; - return (1) ; + } + else { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("keyword not found\n")); + return(1); } - return (0) ; + return(0); } /* @@ -1142,18 +1239,22 @@ SK_AC *pAC, /* Adapters context */ SK_IOC IoC) /* IO Context */ { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd update .. ")) ; + int vpd_size; + + vpd_size = pAC->vpd.vpd_size; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. ")); if (pAC->vpd.v.vpd_status & VPD_VALID) { - if (VpdTransferBlock(pAC,IoC,pAC->vpd.vpd_buf + VPD_SIZE/2, - VPD_SIZE/2, VPD_SIZE/2, VPD_WRITE) != VPD_SIZE/2) { + if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2, + vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("transfer timed out\n")) ; - return(3) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("transfer timed out\n")); + return(3); } } - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("done\n")) ; - return (0) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n")); + return(0); } @@ -1173,32 +1274,33 @@ SK_IOC IoC, /* IO Context */ char *msg) /* error log message */ { - SK_VPD_PARA *v, vf ; /* VF */ - int len ; + SK_VPD_PARA *v, vf; /* VF */ + int len; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX, - ("vpd error log msg %s\n",msg)) ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, + ("VPD error log msg %s\n",msg)); if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { if (VpdInit(pAC,IoC) != 0 ) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("vpd init error\n")) ; - return ; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD init error\n")); + return; } } - len = strlen(msg) ; + len = strlen(msg); if (len > VPD_MAX_LEN) { /* cut it */ - len = VPD_MAX_LEN ; + len = VPD_MAX_LEN; + } + if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n")); + (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY); } - if ((v = vpd_find_para(pAC,VPD_VF,&vf))) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("overwrite VL\n")) ; - (void)VpdSetupPara(pAC,VPD_VL,msg,len,VPD_RW_KEY,OWR_KEY) ; - } else { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("write VF\n")) ; - (void)VpdSetupPara(pAC,VPD_VF,msg,len,VPD_RW_KEY,ADD_KEY) ; + else { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n")); + (void)VpdSetupPara(pAC, VPD_VF, msg,len, VPD_RW_KEY, ADD_KEY); } - (void)VpdUpdate(pAC,IoC) ; + (void)VpdUpdate(pAC, IoC); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/sk98lin/skxmac2.c linux.21pre4-ac6/drivers/net/sk98lin/skxmac2.c --- linux.21pre4/drivers/net/sk98lin/skxmac2.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/sk98lin/skxmac2.c 2003-01-06 15:38:18.000000000 +0000 @@ -2,15 +2,15 @@ * * Name: skxmac2.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.61 $ - * Date: $Date: 2001/02/09 15:40:59 $ - * Purpose: Contains functions to initialize the XMAC II + * Version: $Revision: 1.87 $ + * Date: $Date: 2002/12/10 14:39:05 $ + * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. * * 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 @@ -26,6 +26,152 @@ * History: * * $Log: skxmac2.c,v $ + * Revision 1.87 2002/12/10 14:39:05 rschmidt + * Improved initialization of GPHY in SkGmInitPhyMarv(). + * Editorial changes. + * + * Revision 1.86 2002/12/09 15:01:12 rschmidt + * Added setup of Ext. PHY Specific Ctrl Reg (downshift feature). + * + * Revision 1.85 2002/12/05 14:09:16 rschmidt + * Improved avoiding endless loop in SkGmPhyWrite(), SkGmPhyWrite(). + * Added additional advertising for 10Base-T when 100Base-T is selected. + * Added case SK_PHY_MARV_FIBER for YUKON Fiber adapter. + * Editorial changes. + * + * Revision 1.84 2002/11/15 12:50:09 rschmidt + * Changed SkGmCableDiagStatus() when getting results. + * + * Revision 1.83 2002/11/13 10:28:29 rschmidt + * Added some typecasts to avoid compiler warnings. + * + * Revision 1.82 2002/11/13 09:20:46 rschmidt + * Replaced for(..) with do {} while (...) in SkXmUpdateStats(). + * Replaced 2 macros GM_IN16() with 1 GM_IN32() in SkGmMacStatistic(). + * Added SkGmCableDiagStatus() for Virtual Cable Test (VCT). + * Editorial changes. + * + * Revision 1.81 2002/10/28 14:28:08 rschmidt + * Changed MAC address setup for GMAC in SkGmInitMac(). + * Optimized handling of counter overflow IRQ in SkGmOverflowStatus(). + * Editorial changes. + * + * Revision 1.80 2002/10/14 15:29:44 rschmidt + * Corrected disabling of all PHY IRQs. + * Added WA for deviation #16 (address used for pause packets). + * Set Pause Mode in SkMacRxTxEnable() only for Genesis. + * Added IRQ and counter for Receive FIFO Overflow in DEBUG-mode. + * SkXmTimeStamp() replaced by SkMacTimeStamp(). + * Added clearing of GMAC Tx FIFO Underrun IRQ in SkGmIrq(). + * Editorial changes. + * + * Revision 1.79 2002/10/10 15:55:36 mkarl + * changes for PLinkSpeedUsed + * + * Revision 1.78 2002/09/12 09:39:51 rwahl + * Removed deactivate code for SIRQ overflow event separate for TX/RX. + * + * Revision 1.77 2002/09/09 12:26:37 mkarl + * added handling for Yukon to SkXmTimeStamp + * + * Revision 1.76 2002/08/21 16:41:16 rschmidt + * Added bit GPC_ENA_XC (Enable MDI crossover) in HWCFG_MODE. + * Added forced speed settings in SkGmInitPhyMarv(). + * Added settings of full/half duplex capabilities for YUKON Fiber. + * Editorial changes. + * + * Revision 1.75 2002/08/16 15:12:01 rschmidt + * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. + * Added function SkMacHashing() for ADDR-Module. + * Removed functions SkXmClrSrcCheck(), SkXmClrHashAddr() (calls replaced + * with macros). + * Removed functions SkGmGetMuxConfig(). + * Added HWCFG_MODE init for YUKON Fiber. + * Changed initialization of GPHY in SkGmInitPhyMarv(). + * Changed check of parameter in SkXmMacStatistic(). + * Editorial changes. + * + * Revision 1.74 2002/08/12 14:00:17 rschmidt + * Replaced usage of Broadcom PHY Ids with defines. + * Corrected error messages in SkGmMacStatistic(). + * Made SkMacPromiscMode() public for ADDR-Modul. + * Editorial changes. + * + * Revision 1.73 2002/08/08 16:26:24 rschmidt + * Improved reset sequence for YUKON in SkGmHardRst() and SkGmInitMac(). + * Replaced XMAC Rx High Watermark init value with SK_XM_RX_HI_WM. + * Editorial changes. + * + * Revision 1.72 2002/07/24 15:11:19 rschmidt + * Fixed wrong placement of parenthesis. + * Editorial changes. + * + * Revision 1.71 2002/07/23 16:05:18 rschmidt + * Added global functions for PHY: SkGePhyRead(), SkGePhyWrite(). + * Fixed Tx Counter Overflow IRQ (Bug ID #10730). + * Editorial changes. + * + * Revision 1.70 2002/07/18 14:27:27 rwahl + * Fixed syntax error. + * + * Revision 1.69 2002/07/17 17:08:47 rwahl + * Fixed check in SkXmMacStatistic(). + * + * Revision 1.68 2002/07/16 07:35:24 rwahl + * Removed check for cleared mib counter in SkGmResetCounter(). + * + * Revision 1.67 2002/07/15 18:35:56 rwahl + * Added SkXmUpdateStats(), SkGmUpdateStats(), SkXmMacStatistic(), + * SkGmMacStatistic(), SkXmResetCounter(), SkGmResetCounter(), + * SkXmOverflowStatus(), SkGmOverflowStatus(). + * Changes to SkXmIrq() & SkGmIrq(): Combined SIRQ Overflow for both + * RX & TX. + * Changes to SkGmInitMac(): call to SkGmResetCounter(). + * Editorial changes. + * + * Revision 1.66 2002/07/15 15:59:30 rschmidt + * Added PHY Address in SkXmPhyRead(), SkXmPhyWrite(). + * Added MIB Clear Counter in SkGmInitMac(). + * Added Duplex and Flow-Control settings. + * Reset all Multicast filtering Hash reg. in SkGmInitMac(). + * Added new function: SkGmGetMuxConfig(). + * Editorial changes. + * + * Revision 1.65 2002/06/10 09:35:39 rschmidt + * Replaced C++ comments (//). + * Added #define VCPU around VCPUwaitTime. + * Editorial changes. + * + * Revision 1.64 2002/06/05 08:41:10 rschmidt + * Added function for XMAC2: SkXmTimeStamp(). + * Added function for YUKON: SkGmSetRxCmd(). + * Changed SkGmInitMac() resp. SkGmHardRst(). + * Fixed wrong variable in SkXmAutoNegLipaXmac() (debug mode). + * SkXmRxTxEnable() replaced by SkMacRxTxEnable(). + * Editorial changes. + * + * Revision 1.63 2002/04/25 13:04:44 rschmidt + * Changes for handling YUKON. + * Use of #ifdef OTHER_PHY to eliminate code for unused Phy types. + * Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced + * by functions SkXmPhyRead(), SkXmPhyWrite(); + * Removed use of PRxCmd to setup XMAC. + * Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res. + * Added setting of XM_RX_DIS_CEXT in SkXmInitMac(). + * Removed status parameter from MAC IRQ handler SkMacIrq(), + * SkXmIrq() and SkGmIrq(). + * SkXmAutoNegLipa...() for ext. Phy replaced by SkMacAutoNegLipaPhy(). + * Added SkMac...() functions to handle both XMAC and GMAC. + * Added functions for YUKON: SkGmHardRst(), SkGmSoftRst(), + * SkGmSetRxTxEn(), SkGmIrq(), SkGmInitMac(), SkGmInitPhyMarv(), + * SkGmAutoNegDoneMarv(), SkGmPhyRead(), SkGmPhyWrite(). + * Changes for V-CPU support. + * Editorial changes. + * + * Revision 1.62 2001/08/06 09:50:14 rschmidt + * Workaround BCOM Errata #1 for the C5 type. + * Editorial changes. + * * Revision 1.61 2001/02/09 15:40:59 rassmann * Editorial changes. * @@ -194,7 +340,7 @@ * * Revision 1.12 1998/10/14 14:45:04 malthoff * Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by - * SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independant + * SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independent * from the Sirq module. * * Revision 1.11 1998/10/14 13:59:01 gklug @@ -203,17 +349,16 @@ * Revision 1.10 1998/10/14 11:20:57 malthoff * Make SkXmAutoNegDone() public, because it's * used in diagnostics, too. - * The Link Up event to the RLMT is issued in - * SkXmIrq(). SkXmIrq() is not available in - * diagnostics. Use PHY_READ when reading - * PHY registers. + * The Link Up event to the RLMT is issued in SkXmIrq(). + * SkXmIrq() is not available in diagnostics. + * Use PHY_READ when reading PHY registers. * * Revision 1.9 1998/10/14 05:50:10 cgoos * Added definition for Para. * * Revision 1.8 1998/10/14 05:41:28 gklug * add: Xmac IRQ - * add: auto negotiation done function + * add: auto-negotiation done function * * Revision 1.7 1998/10/09 06:55:20 malthoff * The configuration of the XMACs Tx Request Threshold @@ -246,17 +391,9 @@ ******************************************************************************/ #include "h/skdrv1st.h" -#include "h/xmac_ii.h" #include "h/skdrv2nd.h" -/* defines ********************************************************************/ /* typedefs *******************************************************************/ -/* global variables ***********************************************************/ - -/* local variables ************************************************************/ - -static const char SysKonnectFileId[] = - "@(#)$Id: skxmac2.c,v 1.61 2001/02/09 15:40:59 rassmann Exp $ (C) SK "; /* BCOM PHY magic pattern list */ typedef struct s_PhyHack { @@ -264,6 +401,10 @@ SK_U16 PhyVal; /* Value to write */ } BCOM_HACK; +/* local variables ************************************************************/ +static const char SysKonnectFileId[] = + "@(#)$Id: skxmac2.c,v 1.87 2002/12/10 14:39:05 rschmidt Exp $ (C) SK "; + BCOM_HACK BcomRegA1Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, @@ -279,308 +420,797 @@ /* function prototypes ********************************************************/ static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL); static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL); +static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL); static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int); static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int); +static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int); +#ifdef OTHER_PHY +static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL); +static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL); static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int); static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int); +#endif /* OTHER_PHY */ + + /****************************************************************************** * - * SkXmSetRxCmd() - Modify the value of the XMACs Rx Command Register + * SkXmPhyRead() - Read from XMAC PHY register * - * Description: - * The features - * o FCS stripping, SK_STRIP_FCS_ON/OFF - * o pad byte stripping, SK_STRIP_PAD_ON/OFF - * o don't set XMR_FS_ERR in frame SK_LENERR_OK_ON/OFF - * status for inrange length error - * frames, and - * o don't set XMR_FS_ERR in frame SK_BIG_PK_OK_ON/OFF - * status for frames > 1514 bytes - * - * for incomming packets may be enabled/disabled by this function. - * Additional modes may be added later. - * Multiple modes can be enabled/disabled at the same time. - * The new configuration is stored into the HWAC port configuration - * and is written to the Receive Command register immediatlely. - * The new configuration is saved over any SkGePortStop() and - * SkGeInitPort() calls. The configured value will be overwritten - * when SkGeInit(Level 0) is executed. + * Description: reads a 16-bit word from XMAC PHY or ext. PHY * * Returns: * nothing */ -void SkXmSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* The XMAC to handle with belongs to this Port */ -int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, - SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ +void SkXmPhyRead( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 *pVal) /* Pointer to Value */ { + SK_U16 Mmu; SK_GEPORT *pPrt; - SK_U16 OldRxMode; pPrt = &pAC->GIni.GP[Port]; - OldRxMode = pPrt->PRxCmd; + + /* write the PHY register's address */ + XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); + + /* get the PHY register's value */ + XM_IN16(IoC, Port, XM_PHY_DATA, pVal); + + if (pPrt->PhyType != SK_PHY_XMAC) { + do { + XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); + /* wait until 'Ready' is set */ + } while ((Mmu & XM_MMU_PHY_RDY) == 0); - switch(Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) { - case SK_STRIP_FCS_ON: - pPrt->PRxCmd |= XM_RX_STRIP_FCS; - break; - case SK_STRIP_FCS_OFF: - pPrt->PRxCmd &= ~XM_RX_STRIP_FCS; - break; + /* get the PHY register's value */ + XM_IN16(IoC, Port, XM_PHY_DATA, pVal); } +} /* SkXmPhyRead */ - switch(Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) { - case SK_STRIP_PAD_ON: - pPrt->PRxCmd |= XM_RX_STRIP_PAD; - break; - case SK_STRIP_PAD_OFF: - pPrt->PRxCmd &= ~XM_RX_STRIP_PAD; - break; - } - switch(Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) { - case SK_LENERR_OK_ON: - pPrt->PRxCmd |= XM_RX_LENERR_OK; - break; - case SK_LENERR_OK_OFF: - pPrt->PRxCmd &= ~XM_RX_LENERR_OK; - break; - } +/****************************************************************************** + * + * SkXmPhyWrite() - Write to XMAC PHY register + * + * Description: writes a 16-bit word to XMAC PHY or ext. PHY + * + * Returns: + * nothing + */ +void SkXmPhyWrite( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 Val) /* Value */ +{ + SK_U16 Mmu; + SK_GEPORT *pPrt; - switch(Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) { - case SK_BIG_PK_OK_ON: - pPrt->PRxCmd |= XM_RX_BIG_PK_OK; - break; - case SK_BIG_PK_OK_OFF: - pPrt->PRxCmd &= ~XM_RX_BIG_PK_OK; - break; + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PhyType != SK_PHY_XMAC) { + do { + XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); + /* wait until 'Busy' is cleared */ + } while ((Mmu & XM_MMU_PHY_BUSY) != 0); } - - /* Write the new mode to the receive command register if required */ - if (OldRxMode != pPrt->PRxCmd) { - XM_OUT16(IoC, Port, XM_RX_CMD, pPrt->PRxCmd); + + /* write the PHY register's address */ + XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); + + /* write the PHY register's value */ + XM_OUT16(IoC, Port, XM_PHY_DATA, Val); + + if (pPrt->PhyType != SK_PHY_XMAC) { + do { + XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); + /* wait until 'Busy' is cleared */ + } while ((Mmu & XM_MMU_PHY_BUSY) != 0); } -} /* SkXmSetRxCmd*/ +} /* SkXmPhyWrite */ /****************************************************************************** * - * SkXmClrExactAddr() - Clear Exact Match Address Registers + * SkGmPhyRead() - Read from GPHY register * - * Description: - * All Exact Match Address registers of the XMAC 'Port' will be - * cleared starting with 'StartNum' up to (and including) the - * Exact Match address number of 'StopNum'. + * Description: reads a 16-bit word from GPHY through MDIO * * Returns: * nothing */ -void SkXmClrExactAddr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* The XMAC to handle with belongs to this Port */ -int StartNum, /* Begin with this Address Register Index (0..15) */ -int StopNum) /* Stop after finished with this Register Idx (0..15) */ +void SkGmPhyRead( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 *pVal) /* Pointer to Value */ { - int i; - SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000}; + SK_U16 Ctrl; + SK_GEPORT *pPrt; +#ifdef VCPU + u_long SimCyle; + u_long SimLowTime; + + VCPUgetTime(&SimCyle, &SimLowTime); + VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n", + PhyReg, SimCyle, SimLowTime); +#endif /* VCPU */ + + pPrt = &pAC->GIni.GP[Port]; + + /* set PHY-Register offset and 'Read' OpCode (= 1) */ + *pVal = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg) | + GM_SMI_CT_OP_RD; - if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 || - StartNum > StopNum) { + GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal); - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG); + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + + /* additional check for MDC/MDIO activity */ + if ((Ctrl & GM_SMI_CT_BUSY) == 0) { + *pVal = 0; return; } - for (i = StartNum; i <= StopNum; i++) { - XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]); + *pVal |= GM_SMI_CT_BUSY; + + do { +#ifdef VCPU + VCPUwaitTime(1000); +#endif /* VCPU */ + + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + + /* wait until 'ReadValid' is set */ + } while (Ctrl == *pVal); + + /* get the PHY register's value */ + GM_IN16(IoC, Port, GM_SMI_DATA, pVal); + +#ifdef VCPU + VCPUgetTime(&SimCyle, &SimLowTime); + VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", + SimCyle, SimLowTime); +#endif /* VCPU */ +} /* SkGmPhyRead */ + + +/****************************************************************************** + * + * SkGmPhyWrite() - Write to GPHY register + * + * Description: writes a 16-bit word to GPHY through MDIO + * + * Returns: + * nothing + */ +void SkGmPhyWrite( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 Val) /* Value */ +{ + SK_U16 Ctrl; + SK_GEPORT *pPrt; +#ifdef VCPU + SK_U32 DWord; + u_long SimCyle; + u_long SimLowTime; + + VCPUgetTime(&SimCyle, &SimLowTime); + VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n", + PhyReg, Val, SimCyle, SimLowTime); +#endif /* VCPU */ + + pPrt = &pAC->GIni.GP[Port]; + + /* write the PHY register's value */ + GM_OUT16(IoC, Port, GM_SMI_DATA, Val); + + /* set PHY-Register offset and 'Write' OpCode (= 0) */ + Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg); + + GM_OUT16(IoC, Port, GM_SMI_CTRL, Val); + + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + + /* additional check for MDC/MDIO activity */ + if ((Ctrl & GM_SMI_CT_BUSY) == 0) { + return; } -} /* SkXmClrExactAddr */ + + Val |= GM_SMI_CT_BUSY; + + do { +#ifdef VCPU + /* read Timer value */ + SK_IN32(IoC, B2_TI_VAL, &DWord); + + VCPUwaitTime(1000); +#endif /* VCPU */ + + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + + /* wait until 'Busy' is cleared */ + } while (Ctrl == Val); + +#ifdef VCPU + VCPUgetTime(&SimCyle, &SimLowTime); + VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", + SimCyle, SimLowTime); +#endif /* VCPU */ +} /* SkGmPhyWrite */ /****************************************************************************** * - * SkXmClrSrcCheck() - Clear Source Check Address Register + * SkGePhyRead() - Read from PHY register * - * Description: - * The Source Check Address Register of the XMAC 'Port' number - * will be cleared. + * Description: calls a read PHY routine dep. on board type * * Returns: * nothing */ -static void SkXmClrSrcCheck( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */ +void SkGePhyRead( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 *pVal) /* Pointer to Value */ { - SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000}; + void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal); - XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr); -} /* SkXmClrSrcCheck */ + if (pAC->GIni.GIGenesis) { + r_func = SkXmPhyRead; + } + else { + r_func = SkGmPhyRead; + } + + r_func(pAC, IoC, Port, PhyReg, pVal); +} /* SkGePhyRead */ /****************************************************************************** * - * SkXmClrHashAddr() - Clear Hash Address Registers + * SkGePhyWrite() - Write to PHY register * - * Description: - * The Hash Address Register of the XMAC 'Port' will be cleared. + * Description: calls a write PHY routine dep. on board type * * Returns: * nothing */ -static void SkXmClrHashAddr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */ +void SkGePhyWrite( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 Val) /* Value */ { - SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000}; + void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val); - XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr); -} /* SkXmClrHashAddr*/ + if (pAC->GIni.GIGenesis) { + w_func = SkXmPhyWrite; + } + else { + w_func = SkGmPhyWrite; + } + + w_func(pAC, IoC, Port, PhyReg, Val); +} /* SkGePhyWrite */ /****************************************************************************** * - * SkXmFlushTxFifo() - Flush the XMACs transmit FIFO + * SkMacPromiscMode() - Enable / Disable Promiscuous Mode * * Description: - * Flush the transmit FIFO of the XMAC specified by the index 'Port' + * enables / disables promiscuous mode by setting Mode Register (XMAC) or + * Receive Control Register (GMAC) dep. on board type * * Returns: * nothing */ -void SkXmFlushTxFifo( +void SkMacPromiscMode( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL Enable) /* Enable / Disable */ { + SK_U16 RcReg; SK_U32 MdReg; - XM_IN32(IoC, Port, XM_MODE, &MdReg); - MdReg |= XM_MD_FTF; - XM_OUT32(IoC, Port, XM_MODE, MdReg); -} /* SkXmFlushTxFifo */ + if (pAC->GIni.GIGenesis) { + + XM_IN32(IoC, Port, XM_MODE, &MdReg); + /* enable or disable promiscuous mode */ + if (Enable) { + MdReg |= XM_MD_ENA_PROM; + } + else { + MdReg &= ~XM_MD_ENA_PROM; + } + /* setup Mode Register */ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + else { + + GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); + + /* enable or disable unicast and multicast filtering */ + if (Enable) { + RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); + } + else { + RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); + } + /* setup Receive Control Register */ + GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg); + } +} /* SkMacPromiscMode*/ /****************************************************************************** * - * SkXmFlushRxFifo() - Flush the XMACs receive FIFO + * SkMacHashing() - Enable / Disable Hashing * * Description: - * Flush the receive FIFO of the XMAC specified by the index 'Port' + * enables / disables hashing by setting Mode Register (XMAC) or + * Receive Control Register (GMAC) dep. on board type * * Returns: * nothing */ -void SkXmFlushRxFifo( +void SkMacHashing( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL Enable) /* Enable / Disable */ { + SK_U16 RcReg; SK_U32 MdReg; - XM_IN32(IoC, Port, XM_MODE, &MdReg); - MdReg |= XM_MD_FRF; - XM_OUT32(IoC, Port, XM_MODE, MdReg); -} /* SkXmFlushRxFifo*/ + if (pAC->GIni.GIGenesis) { + + XM_IN32(IoC, Port, XM_MODE, &MdReg); + /* enable or disable hashing */ + if (Enable) { + MdReg |= XM_MD_ENA_HASH; + } + else { + MdReg &= ~XM_MD_ENA_HASH; + } + /* setup Mode Register */ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + else { + + GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); + + /* enable or disable multicast filtering */ + if (Enable) { + RcReg |= GM_RXCR_MCF_ENA; + } + else { + RcReg &= ~GM_RXCR_MCF_ENA; + } + /* setup Receive Control Register */ + GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg); + } +} /* SkMacHashing*/ +#ifdef SK_DIAG /****************************************************************************** * - * SkXmSoftRst() - Do a XMAC software reset + * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register * * Description: - * The PHY registers should not be destroyed during this - * kind of software reset. Therefore the XMAC Software Reset - * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used! - * - * The software reset is done by - * - disabling the Rx and Tx state maschine, - * - reseting the statistics module, - * - clear all other significant XMAC Mode, - * Command, and Control Registers - * - clearing the Hash Register and the - * Exact Match Address registers, and - * - flushing the XMAC's Rx and Tx FIFOs. - * - * Note: - * Another requirement when stopping the XMAC is to - * avoid sending corrupted frames on the network. - * Disabling the Tx state maschine will NOT interrupt - * the currently transmitted frame. But we must take care - * that the tx FIFO is cleared AFTER the current frame - * is complete sent to the network. + * The features + * - FCS stripping, SK_STRIP_FCS_ON/OFF + * - pad byte stripping, SK_STRIP_PAD_ON/OFF + * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF + * for inrange length error frames + * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF + * for frames > 1514 bytes + * - enable Rx of own packets SK_SELF_RX_ON/OFF * - * It takes about 12ns to send a frame with 1538 bytes. - * One PCI clock goes at least 15ns (66MHz). Therefore - * after reading XM_GP_PORT back, we are sure that the - * transmitter is disabled AND idle. And this means - * we may flush the transmit FIFO now. + * for incoming packets may be enabled/disabled by this function. + * Additional modes may be added later. + * Multiple modes can be enabled/disabled at the same time. + * The new configuration is written to the Rx Command register immediately. * * Returns: * nothing */ -void SkXmSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* port to stop (MAC_1 + n) */ +static void SkXmSetRxCmd( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, + SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ { - SK_GEPORT *pPrt; - SK_U16 Word; + SK_U16 OldRxCmd; + SK_U16 RxCmd; - pPrt = &pAC->GIni.GP[Port]; - - /* disable the receiver and transmitter */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX|XM_MMU_ENA_TX)); - - /* reset the statistics module */ - XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT); + XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd); - /* - * clear all other significant XMAC Mode, - * Command, and Control Registers - */ - XM_OUT16(IoC, Port, XM_IMSK, 0xffff); /* disable all IRQs */ - XM_OUT32(IoC, Port, XM_MODE, 0x00000000); /* clear Mode Reg */ - XM_OUT16(IoC, Port, XM_TX_CMD, 0x0000); /* reset TX CMD Reg */ - XM_OUT16(IoC, Port, XM_RX_CMD, 0x0000); /* reset RX CMD Reg */ + RxCmd = OldRxCmd; + + switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) { + case SK_STRIP_FCS_ON: + RxCmd |= XM_RX_STRIP_FCS; + break; + case SK_STRIP_FCS_OFF: + RxCmd &= ~XM_RX_STRIP_FCS; + break; + } + + switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) { + case SK_STRIP_PAD_ON: + RxCmd |= XM_RX_STRIP_PAD; + break; + case SK_STRIP_PAD_OFF: + RxCmd &= ~XM_RX_STRIP_PAD; + break; + } + + switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) { + case SK_LENERR_OK_ON: + RxCmd |= XM_RX_LENERR_OK; + break; + case SK_LENERR_OK_OFF: + RxCmd &= ~XM_RX_LENERR_OK; + break; + } + + switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) { + case SK_BIG_PK_OK_ON: + RxCmd |= XM_RX_BIG_PK_OK; + break; + case SK_BIG_PK_OK_OFF: + RxCmd &= ~XM_RX_BIG_PK_OK; + break; + } + + switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) { + case SK_SELF_RX_ON: + RxCmd |= XM_RX_SELF_RX; + break; + case SK_SELF_RX_OFF: + RxCmd &= ~XM_RX_SELF_RX; + break; + } + + /* Write the new mode to the Rx command register if required */ + if (OldRxCmd != RxCmd) { + XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd); + } +} /* SkXmSetRxCmd */ + + +/****************************************************************************** + * + * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register + * + * Description: + * The features + * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF + * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF + * for frames > 1514 bytes + * - enable Rx of own packets SK_SELF_RX_ON/OFF + * + * for incoming packets may be enabled/disabled by this function. + * Additional modes may be added later. + * Multiple modes can be enabled/disabled at the same time. + * The new configuration is written to the Rx Command register immediately. + * + * Returns: + * nothing + */ +static void SkGmSetRxCmd( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, + SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ +{ + SK_U16 OldRxCmd; + SK_U16 RxCmd; + + if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) { + + GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd); + + RxCmd = OldRxCmd; + + if ((Mode & SK_STRIP_FCS_ON) != 0) { + RxCmd |= GM_RXCR_CRC_DIS; + } + else { + RxCmd &= ~GM_RXCR_CRC_DIS; + } + /* Write the new mode to the Rx control register if required */ + if (OldRxCmd != RxCmd) { + GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); + } + } + + if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) { + + GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd); + + RxCmd = OldRxCmd; + + if ((Mode & SK_BIG_PK_OK_ON) != 0) { + RxCmd |= GM_SMOD_JUMBO_ENA; + } + else { + RxCmd &= ~GM_SMOD_JUMBO_ENA; + } + /* Write the new mode to the Rx control register if required */ + if (OldRxCmd != RxCmd) { + GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); + } + } +} /* SkGmSetRxCmd */ + + +/****************************************************************************** + * + * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register + * + * Description: modifies the MAC's Rx Control reg. dep. on board type + * + * Returns: + * nothing + */ +void SkMacSetRxCmd( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Mode) /* Rx Mode */ +{ + if (pAC->GIni.GIGenesis) { + + SkXmSetRxCmd(pAC, IoC, Port, Mode); + } + else { + + SkGmSetRxCmd(pAC, IoC, Port, Mode); + } +} /* SkMacSetRxCmd */ + + +/****************************************************************************** + * + * SkMacCrcGener() - Enable / Disable CRC Generation + * + * Description: enables / disables CRC generation dep. on board type + * + * Returns: + * nothing + */ +void SkMacCrcGener( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL Enable) /* Enable / Disable */ +{ + SK_U16 Word; + + if (pAC->GIni.GIGenesis) { + + XM_IN16(IoC, Port, XM_TX_CMD, &Word); + + if (Enable) { + Word &= ~XM_TX_NO_CRC; + } + else { + Word |= XM_TX_NO_CRC; + } + /* setup Tx Command Register */ + XM_OUT16(pAC, Port, XM_TX_CMD, Word); + } + else { + + GM_IN16(IoC, Port, GM_TX_CTRL, &Word); + + if (Enable) { + Word &= ~GM_TXCR_CRC_DIS; + } + else { + Word |= GM_TXCR_CRC_DIS; + } + /* setup Tx Control Register */ + GM_OUT16(IoC, Port, GM_TX_CTRL, Word); + } +} /* SkMacCrcGener*/ + +#endif /* SK_DIAG */ + + +/****************************************************************************** + * + * SkXmClrExactAddr() - Clear Exact Match Address Registers + * + * Description: + * All Exact Match Address registers of the XMAC 'Port' will be + * cleared starting with 'StartNum' up to (and including) the + * Exact Match address number of 'StopNum'. + * + * Returns: + * nothing + */ +void SkXmClrExactAddr( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int StartNum, /* Begin with this Address Register Index (0..15) */ +int StopNum) /* Stop after finished with this Register Idx (0..15) */ +{ + int i; + SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000}; + + if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 || + StartNum > StopNum) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG); + return; + } + + for (i = StartNum; i <= StopNum; i++) { + XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]); + } +} /* SkXmClrExactAddr */ + + +/****************************************************************************** + * + * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO + * + * Description: + * Flush the transmit FIFO of the MAC specified by the index 'Port' + * + * Returns: + * nothing + */ +void SkMacFlushTxFifo( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U32 MdReg; + + if (pAC->GIni.GIGenesis) { + + XM_IN32(IoC, Port, XM_MODE, &MdReg); + + XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF); + } + else { + /* no way to flush the FIFO we have to issue a reset */ + /* TBD */ + } +} /* SkMacFlushTxFifo */ + + +/****************************************************************************** + * + * SkMacFlushRxFifo() - Flush the MAC's receive FIFO + * + * Description: + * Flush the receive FIFO of the MAC specified by the index 'Port' + * + * Returns: + * nothing + */ +void SkMacFlushRxFifo( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U32 MdReg; + + if (pAC->GIni.GIGenesis) { + + XM_IN32(IoC, Port, XM_MODE, &MdReg); + + XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF); + } + else { + /* no way to flush the FIFO we have to issue a reset */ + /* TBD */ + } +} /* SkMacFlushRxFifo */ + + +/****************************************************************************** + * + * SkXmSoftRst() - Do a XMAC software reset + * + * Description: + * The PHY registers should not be destroyed during this + * kind of software reset. Therefore the XMAC Software Reset + * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used! + * + * The software reset is done by + * - disabling the Rx and Tx state machine, + * - resetting the statistics module, + * - clear all other significant XMAC Mode, + * Command, and Control Registers + * - clearing the Hash Register and the + * Exact Match Address registers, and + * - flushing the XMAC's Rx and Tx FIFOs. + * + * Note: + * Another requirement when stopping the XMAC is to + * avoid sending corrupted frames on the network. + * Disabling the Tx state machine will NOT interrupt + * the currently transmitted frame. But we must take care + * that the Tx FIFO is cleared AFTER the current frame + * is complete sent to the network. + * + * It takes about 12ns to send a frame with 1538 bytes. + * One PCI clock goes at least 15ns (66MHz). Therefore + * after reading XM_GP_PORT back, we are sure that the + * transmitter is disabled AND idle. And this means + * we may flush the transmit FIFO now. + * + * Returns: + * nothing + */ +static void SkXmSoftRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000}; + + /* reset the statistics module */ + XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT); + + /* disable all XMAC IRQs */ + XM_OUT16(IoC, Port, XM_IMSK, 0xffff); + + XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */ + + XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */ + XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */ /* disable all PHY IRQs */ switch (pAC->GIni.GP[Port].PhyType) { case SK_PHY_BCOM: - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 0xffff); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff); break; +#ifdef OTHER_PHY case SK_PHY_LONE: - PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 0x0); + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0); break; case SK_PHY_NAT: /* todo: National - PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, - 0xffff); */ + SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */ break; +#endif /* OTHER_PHY */ } /* clear the Hash Register */ - SkXmClrHashAddr(pAC, IoC, Port); + XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr); /* clear the Exact Match Address registers */ SkXmClrExactAddr(pAC, IoC, Port, 0, 15); - SkXmClrSrcCheck(pAC, IoC, Port); - - /* flush the XMAC's Rx and Tx FIFOs */ - SkXmFlushTxFifo(pAC, IoC, Port); - SkXmFlushRxFifo(pAC, IoC, Port); + + /* clear the Source Check Address registers */ + XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr); - pAC->GIni.GP[Port].PState = SK_PRT_STOP; -} /* SkXmSoftRst*/ +} /* SkXmSoftRst */ /****************************************************************************** @@ -589,23 +1219,21 @@ * * Description: * The XMAC of the specified 'Port' and all connected devices - * (PHY and SERDES) will receive a reset signal on its *Reset - * pins. - * External PHYs must be reset be clearing a bit in the GPIO - * register (Timing requirements: Broadcom: 400ns, Level One: - * none, National: 80ns). + * (PHY and SERDES) will receive a reset signal on its *Reset pins. + * External PHYs must be reset be clearing a bit in the GPIO register + * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns). * * ATTENTION: - * It is absolutely neccessary to reset the SW_RST Bit first + * It is absolutely necessary to reset the SW_RST Bit first * before calling this function. * * Returns: * nothing */ -void SkXmHardRst( +static void SkXmHardRst( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port) /* port to stop (MAC_1 + n) */ +int Port) /* Port Index (MAC_1 + n) */ { SK_U32 Reg; int i; @@ -613,14 +1241,12 @@ SK_U16 Word; for (i = 0; i < 4; i++) { - /* TX_MFF_CTRL1 is a 32 bit register but only the lowest 16 */ - /* bit contains buttoms to press */ - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST); + /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */ + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); TOut = 0; do { - TOut ++; - if (TOut > 10000) { + if (TOut++ > 10000) { /* * Adapter seems to be in RESET state. * Registers cannot be written. @@ -628,9 +1254,10 @@ return; } - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), - (SK_U16) MFF_SET_MAC_RST); - SK_IN16(IoC,MR_ADDR(Port,TX_MFF_CTRL1), &Word); + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST); + + SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word); + } while ((Word & MFF_SET_MAC_RST) == 0); } @@ -652,16 +1279,151 @@ SK_IN32(IoC, B2_GP_IO, &Reg); } - pAC->GIni.GP[Port].PState = SK_PRT_RESET; } /* SkXmHardRst */ /****************************************************************************** * + * SkGmSoftRst() - Do a GMAC software reset + * + * Description: + * The GPHY registers should not be destroyed during this + * kind of software reset. + * + * Returns: + * nothing + */ +static void SkGmSoftRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000}; + SK_U16 RxCtrl; + + /* reset the statistics module */ + + /* disable all GMAC IRQs */ + SK_OUT8(IoC, GMAC_IRQ_MSK, 0); + + /* disable all PHY IRQs */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); + + /* clear the Hash Register */ + GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, &EmptyHash); + + /* Enable Unicast and Multicast filtering */ + GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); + + GM_OUT16(IoC, Port, GM_RX_CTRL, + RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); + +} /* SkGmSoftRst */ + + +/****************************************************************************** + * + * SkGmHardRst() - Do a GMAC hardware reset + * + * Description: + * + * ATTENTION: + * It is absolutely necessary to reset the SW_RST Bit first + * before calling this function. + * + * Returns: + * nothing + */ +static void SkGmHardRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + /* set GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); + + /* set GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + +} /* SkGmHardRst */ + + +/****************************************************************************** + * + * SkMacSoftRst() - Do a MAC software reset + * + * Description: calls a MAC software reset routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacSoftRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + /* disable receiver and transmitter */ + SkMacRxTxDisable(pAC, IoC, Port); + + if (pAC->GIni.GIGenesis) { + + SkXmSoftRst(pAC, IoC, Port); + } + else { + + SkGmSoftRst(pAC, IoC, Port); + } + + /* flush the MAC's Rx and Tx FIFOs */ + SkMacFlushTxFifo(pAC, IoC, Port); + + SkMacFlushRxFifo(pAC, IoC, Port); + + pPrt->PState = SK_PRT_STOP; + +} /* SkMacSoftRst */ + + +/****************************************************************************** + * + * SkMacHardRst() - Do a MAC hardware reset + * + * Description: calls a MAC hardware reset routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacHardRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + + if (pAC->GIni.GIGenesis) { + + SkXmHardRst(pAC, IoC, Port); + } + else { + + SkGmHardRst(pAC, IoC, Port); + } + + pAC->GIni.GP[Port].PState = SK_PRT_RESET; + +} /* SkMacHardRst */ + + + +/****************************************************************************** + * * SkXmInitMac() - Initialize the XMAC II * * Description: - * Initialize all the XMAC of the specified port. + * Initialize the XMAC of the specified port. * The XMAC must be reset or stopped before calling this function. * * Note: @@ -679,7 +1441,6 @@ SK_U32 Reg; int i; SK_U16 SWord; - SK_U16 PhyId; pPrt = &pAC->GIni.GP[Port]; @@ -687,10 +1448,11 @@ /* Port State: SK_PRT_STOP */ /* Verify that the reset bit is cleared */ SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); - if (SWord & (SK_U16)MFF_SET_MAC_RST) { + + if ((SWord & MFF_SET_MAC_RST) != 0) { /* PState does not match HW state */ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); - /* Correct it. */ + /* Correct it */ pPrt->PState = SK_PRT_RESET; } } @@ -701,115 +1463,84 @@ * Note: The SW reset is self clearing, therefore there is * nothing to do here. */ - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST); + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); - /* Ensure that XMAC reset release is done (errata from LReinbold?). */ + /* Ensure that XMAC reset release is done (errata from LReinbold?) */ SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); - /* Clear PHY reset. */ - if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { + /* Clear PHY reset */ + if (pPrt->PhyType != SK_PHY_XMAC) { + SK_IN32(IoC, B2_GP_IO, &Reg); + if (Port == 0) { - Reg |= GP_DIR_0; /* Set to output. */ - Reg |= GP_IO_0; + Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */ } else { - Reg |= GP_DIR_2; /* Set to output. */ - Reg |= GP_IO_2; + Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */ } SK_OUT32(IoC, B2_GP_IO, Reg); - /* Enable GMII interface. */ + /* Enable GMII interface */ XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); - PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &PhyId); -#ifdef xDEBUG - if (SWord == 0xFFFF) { - i = 1; - do { - PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &SWord); - i++; - /* Limit retries; else machine may hang. */ - } while (SWord == 0xFFFF && i < 500000); - - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "ID1 is %x after %d reads.", - (void *)SWord, - (void *)i); - - /* Trigger PCI analyzer */ - /* SK_IN32(IoC, 0x012c, &Reg); */ - } -#endif /* DEBUG */ + /* read Id from external PHY (all have the same address) */ + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1); /* * Optimize MDIO transfer by suppressing preamble. * Must be done AFTER first access to BCOM chip. */ XM_IN16(IoC, Port, XM_MMU_CMD, &SWord); + XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE); - if (PhyId == 0x6044) { - /* Workaround BCOM Errata for the C0 type. */ - /* Write magic patterns to reserved registers. */ + if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) { + /* + * Workaround BCOM Errata for the C0 type. + * Write magic patterns to reserved registers. + */ i = 0; while (BcomRegC0Hack[i].PhyReg != 0) { - PHY_WRITE(IoC, pPrt, Port, BcomRegC0Hack[i].PhyReg, + SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg, BcomRegC0Hack[i].PhyVal); i++; } } - else if (PhyId == 0x6041) { - /* Workaround BCOM Errata for the A1 type. */ - /* Write magic patterns to reserved registers. */ + else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) { + /* + * Workaround BCOM Errata for the A1 type. + * Write magic patterns to reserved registers. + */ i = 0; while (BcomRegA1Hack[i].PhyReg != 0) { - PHY_WRITE(IoC, pPrt, Port, BcomRegA1Hack[i].PhyReg, + SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg, BcomRegA1Hack[i].PhyVal); i++; } } - /* Workaround BCOM Errata (#10523) for all BCom PHYs. */ - /* Disable Power Management after reset. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord); -#ifdef xDEBUG - if (SWord == 0xFFFF) { - i = 1; - do { - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord); - i++; - /* Limit retries; else machine may hang. */ - } while (SWord == 0xFFFF && i < 500000); - - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "AUX_CTRL is %x after %d reads.", - (void *)SWord, - (void *)i); - - /* Trigger PCI analyzer */ - /* SK_IN32(IoC, 0x012c, &Reg); */ - } -#endif /* DEBUG */ - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, - SWord | PHY_B_AC_DIS_PM); + /* + * Workaround BCOM Errata (#10523) for all BCom PHYs. + * Disable Power Management after reset. + */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); + + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, + (SK_U16)(SWord | PHY_B_AC_DIS_PM)); - /* PHY LED initialization is done in SkGeXmitLED(), not here. */ + /* PHY LED initialization is done in SkGeXmitLED() */ } /* Dummy read the Interrupt source register */ XM_IN16(IoC, Port, XM_ISRC, &SWord); /* - * The autonegotiation process starts immediately after - * clearing the reset. The autonegotiation process should be + * The auto-negotiation process starts immediately after + * clearing the reset. The auto-negotiation process should be * started by the SIRQ, therefore stop it here immediately. */ - SkXmInitPhy(pAC, IoC, Port, SK_FALSE); + SkMacInitPhy(pAC, IoC, Port, SK_FALSE); #if 0 /* temp. code: enable signal detect */ @@ -820,15 +1551,16 @@ /* * configure the XMACs Station Address - * B2_MAC_2 = xx xx xx xx xx x1 is programed to XMAC A - * B2_MAC_3 = xx xx xx xx xx x2 is programed to XMAC B + * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A + * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B */ for (i = 0; i < 3; i++) { /* * The following 2 statements are together endianess - * independant. Remember this when changing. + * independent. Remember this when changing. */ SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); + XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord); } @@ -840,49 +1572,54 @@ /* Rx Low Water Mark (XM_RX_LO_WM): use default */ /* configure Rx High Water Mark (XM_RX_HI_WM) */ - XM_OUT16(IoC, Port, XM_RX_HI_WM, 0x05aa); + XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM); + + /* Configure Tx Request Threshold */ + SWord = SK_XM_THR_SL; /* for single port */ if (pAC->GIni.GIMacsFound > 1) { switch (pAC->GIni.GIPortUsage) { case SK_RED_LINK: - /* Configure Tx Request Threshold for red. link */ - XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_REDL); + SWord = SK_XM_THR_REDL; /* redundant link */ break; case SK_MUL_LINK: - /* Configure Tx Request Threshold for load bal. */ - XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_MULL); + SWord = SK_XM_THR_MULL; /* load balancing */ break; case SK_JUMBO_LINK: - /* Configure Tx Request Threshold for jumbo frames */ - XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_JUMBO); + SWord = SK_XM_THR_JUMBO; /* jumbo frames */ break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, - SKERR_HWI_E014MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG); break; } } - else { - /* Configure Tx Request Threshold for single port */ - XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_SL); - } + XM_OUT16(IoC, Port, XM_TX_THR, SWord); - /* - * setup register defaults for the Rx Command Register - * - Enable Automatic Frame Padding on Tx side - */ + /* setup register defaults for the Tx Command Register */ XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD); - /* - * setup register defaults for the Rx Command Register, - * program value of PRxCmd - */ - XM_OUT16(IoC, Port, XM_RX_CMD, pPrt->PRxCmd); + /* setup register defaults for the Rx Command Register */ + SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK; + + if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + SWord |= XM_RX_BIG_PK_OK; + } + + if (pPrt->PLinkModeConf == SK_LMODE_HALF) { + /* + * If in manual half duplex mode the other side might be in + * full duplex mode, so ignore if a carrier extension is not seen + * on frames received + */ + SWord |= XM_RX_DIS_CEXT; + } + + XM_OUT16(IoC, Port, XM_RX_CMD, SWord); /* * setup register defaults for the Mode Register * - Don't strip error frames to avoid Store & Forward - * on the rx side. + * on the Rx side. * - Enable 'Check Station Address' bit * - Enable 'Check Address Array' bit */ @@ -906,15 +1643,226 @@ * Do NOT init XMAC interrupt mask here. * All interrupts remain disable until link comes up! */ - pPrt->PState = SK_PRT_INIT; /* * Any additional configuration changes may be done now. - * The last action is to enable the rx and tx state machine. - * This should be done after the autonegotiation process + * The last action is to enable the Rx and Tx state machine. + * This should be done after the auto-negotiation process * has been completed successfully. */ -} /* SkXmInitMac*/ +} /* SkXmInitMac */ + +/****************************************************************************** + * + * SkGmInitMac() - Initialize the GMAC + * + * Description: + * Initialize the GMAC of the specified port. + * The GMAC must be reset or stopped before calling this function. + * + * Note: + * The GMAC's Rx and Tx state machine is still disabled when returning. + * + * Returns: + * nothing + */ +void SkGmInitMac( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + int i; + SK_U16 SWord; + SK_U32 DWord; + + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PState == SK_PRT_STOP) { + /* Port State: SK_PRT_STOP */ + /* Verify that the reset bit is cleared */ + SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord); + + if ((DWord & GMC_RST_SET) != 0) { + /* PState does not match HW state */ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); + /* Correct it */ + pPrt->PState = SK_PRT_RESET; + } + } + + if (pPrt->PState == SK_PRT_RESET) { + /* set GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); + + /* set GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + + /* clear GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); + + /* set GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + + /* set HWCFG_MODE */ + DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | + GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | + (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : + GPC_HWCFG_GMII_FIB); + + /* set GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + + /* release GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); + + /* clear GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + + /* Dummy read the Interrupt source register */ + SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); + +#ifndef VCPU + /* read Id from PHY */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1); + + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); +#endif /* VCPU */ + } + + (void)SkGmResetCounter(pAC, IoC, Port); + + SWord = 0; + + /* speed settings */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + /* auto update for speed is already set */ + break; + case SK_LSPEED_1000MBPS: + SWord |= GM_GPCR_SPEED_1000; + break; + case SK_LSPEED_100MBPS: + SWord |= GM_GPCR_SPEED_100; + break; + case SK_LSPEED_10MBPS: + break; + } + + /* duplex settings */ + if (pPrt->PLinkModeConf == SK_LMODE_FULL || + pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE) { + + SWord |= GM_GPCR_DUP_FULL; + } + + /* flow control settings */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + /* disable auto-neg of flow control */ + SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS; + break; + case SK_FLOW_MODE_LOC_SEND: + SWord |= GM_GPCR_FC_RX_DIS; + break; + case SK_FLOW_MODE_SYMMETRIC: + /* TBD */ + case SK_FLOW_MODE_SYM_OR_REM: + /* do nothing means to enable autoneg for flowcontrol and */ + /* enable rx and tx of pause frames */ + break; + } + + /* setup General Purpose Control Register */ + GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); + + /* setup Transmit Control Register */ + GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR); + + /* setup Receive Control Register */ + GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | + GM_RXCR_CRC_DIS); + + /* setup Transmit Flow Control Register */ + GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff); + + /* setup Transmit Parameter Register */ +#ifdef VCPU + GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); +#endif /* VCPU */ + + SWord = JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26); + + GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); + + /* configure the Serial Mode Register */ +#ifdef VCPU + GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); +#endif /* VCPU */ + + SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH; + + if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + /* enable jumbo mode (Max. Frame Length = 9018) */ + SWord |= GM_SMOD_JUMBO_ENA; + } + + GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord); + + /* + * configure the GMACs Station Addresses + * in PROM you can find our addresses at: + * B2_MAC_1 = xx xx xx xx xx x0 virtual address + * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A + * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort + */ + + for (i = 0; i < 3; i++) { + /* + * The following 2 statements are together endianess + * independent. Remember this when changing. + */ + /* physical address: will be used for pause frames */ + SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); + +#ifdef WA_DEV_16 + /* WA for deviation #16 */ + if (pAC->GIni.GIChipRev == 0) { + /* swap the address bytes */ + SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8); + + /* write to register in reversed order */ + GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord); + } + else { + GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); + } +#else + GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); +#endif /* WA_DEV_16 */ + + /* virtual address: will be used for data */ + SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); + + GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); + } + + /* reset all Multicast filtering Hash registers */ + GM_OUT16(IoC, Port, GM_MC_ADDR_H1, 0); + GM_OUT16(IoC, Port, GM_MC_ADDR_H2, 0); + GM_OUT16(IoC, Port, GM_MC_ADDR_H3, 0); + GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0); + + /* enable interrupt mask for counter overflows */ + GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0); + GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); + GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); + +#ifdef VCPU + /* read General Purpose Status */ + GM_IN16(IoC, Port, GM_GP_STAT, &SWord); +#endif /* VCPU */ +} /* SkGmInitMac */ /****************************************************************************** @@ -922,9 +1870,9 @@ * SkXmInitDupMd() - Initialize the XMACs Duplex Mode * * Description: - * This function initilaizes the XMACs Duplex Mode. + * This function initializes the XMACs Duplex Mode. * It should be called after successfully finishing - * the Autonegotiation Process + * the Auto-negotiation Process * * Returns: * nothing @@ -939,9 +1887,9 @@ case SK_LMODE_STAT_HALF: /* Configuration Actions for Half Duplex Mode */ /* - * XM_BURST = default value. We are propable not quick + * XM_BURST = default value. We are probable not quick * enough at the 'XMAC' bus to burst 8kB. - * The XMAC stopps bursting if no transmit frames + * The XMAC stops bursting if no transmit frames * are available or the burst limit is exceeded. */ /* XM_TX_RT_LIM = default value (15) */ @@ -969,10 +1917,10 @@ * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port * * Description: - * This function initilaizes the Pause Mode which should + * This function initializes the Pause Mode which should * be used for this port. * It should be called after successfully finishing - * the Autonegotiation Process + * the Auto-negotiation Process * * Returns: * nothing @@ -988,22 +1936,26 @@ pPrt = &pAC->GIni.GP[Port]; + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { /* Disable Pause Frame Reception */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_IGN_PF); + Word |= XM_MMU_IGN_PF; } else { /* - * enabling pause frame reception is required for 1000BT + * enabling pause frame reception is required for 1000BT * because the XMAC is not reset if the link is going down */ /* Enable Pause Frame Reception */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~XM_MMU_IGN_PF); + Word &= ~XM_MMU_IGN_PF; } + + XM_OUT16(IoC, Port, XM_MMU_CMD, Word); + + XM_IN32(IoC, Port, XM_MODE, &DWord); if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC || pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { @@ -1011,11 +1963,10 @@ /* * Configure Pause Frame Generation * Use internal and external Pause Frame Generation. - * Sending pause frames is edge triggert. Send a - * Pause frame with the maximum pause time if - * internal oder external FIFO full condition - * occurs. Send a zero pause time frame to - * start transmission again. + * Sending pause frames is edge triggered. + * Send a Pause frame with the maximum pause time if + * internal oder external FIFO full condition occurs. + * Send a zero pause time frame to re-start transmission. */ /* XM_PAUSE_DA = '010000C28001' (default) */ @@ -1025,71 +1976,32 @@ XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff); /* Set Pause Mode in Mode Register */ - XM_IN32(IoC, Port, XM_MODE, &DWord); - XM_OUT32(IoC, Port, XM_MODE, DWord | XM_PAUSE_MODE); + DWord |= XM_PAUSE_MODE; /* Set Pause Mode in MAC Rx FIFO */ - SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_ENA_PAUSE); + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE); } else { /* - * disable pause frame generation is required for 1000BT + * disable pause frame generation is required for 1000BT * because the XMAC is not reset if the link is going down */ /* Disable Pause Mode in Mode Register */ - XM_IN32(IoC, Port, XM_MODE, &DWord); - XM_OUT32(IoC, Port, XM_MODE, DWord & ~XM_PAUSE_MODE); + DWord &= ~XM_PAUSE_MODE; /* Disable Pause Mode in MAC Rx FIFO */ - SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_DIS_PAUSE); + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE); } + + XM_OUT32(IoC, Port, XM_MODE, DWord); } /* SkXmInitPauseMd*/ /****************************************************************************** * - * SkXmInitPhy() - Initialize the XMAC II Phy registers - * - * Description: - * Initialize all the XMACs Phy registers - * - * Note: - * - * Returns: - * nothing - */ -void SkXmInitPhy( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - switch (pPrt->PhyType) { - case SK_PHY_XMAC: - SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_BCOM: - SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_LONE: - SkXmInitPhyLone(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_NAT: - SkXmInitPhyNat(pAC, IoC, Port, DoLoop); - break; - } -} /* SkXmInitPhy*/ - - -/****************************************************************************** - * - * SkXmInitPhyXmac() - Initialize the XMAC II Phy registers + * SkXmInitPhyXmac() - Initialize the XMAC Phy registers * - * Description: - * Initialize all the XMACs Phy registers + * Description: initializes all the XMACs Phy registers * * Note: * @@ -1100,32 +2012,32 @@ SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */ +SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { SK_GEPORT *pPrt; SK_U16 Ctrl; pPrt = &pAC->GIni.GP[Port]; - - /* Autonegotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("InitPhyXmac: no autonegotiation Port %d\n", Port)); - /* No Autonegiotiation */ + Ctrl = 0; + + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyXmac: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ - Ctrl = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl |= PHY_CT_DUP_MD; + } /* - * Do NOT enable Autonegotiation here. This would hold - * the link down because no IDLES are transmitted + * Do NOT enable Auto-negotiation here. This would hold + * the link down because no IDLEs are transmitted */ } else { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("InitPhyXmac: with autonegotiation Port %d\n", Port)); - /* Set Autonegotiation advertisement */ - Ctrl = 0; + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyXmac: with auto-negotiation Port %d\n", Port)); + /* Set Auto-negotiation advertisement */ /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { @@ -1139,8 +2051,8 @@ Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD; break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E015, SKERR_HWI_E015MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); } switch (pPrt->PFlowCtrlMode) { @@ -1157,14 +2069,14 @@ Ctrl |= PHY_X_P_BOTH_MD; break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E016, SKERR_HWI_E016MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); } /* Write AutoNeg Advertisement Register */ - PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_AUNE_ADV, Ctrl); + SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl); - /* Restart Autonegotiation */ + /* Restart Auto-negotiation */ Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG; } @@ -1174,16 +2086,15 @@ } /* Write to the Phy control register */ - PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_CTRL, Ctrl); -} /* SkXmInitPhyXmac*/ + SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl); +} /* SkXmInitPhyXmac */ /****************************************************************************** * * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers * - * Description: - * Initialize all the Broadcom Phy registers + * Description: initializes all the Broadcom Phy registers * * Note: * @@ -1194,7 +2105,7 @@ SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */ +SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { SK_GEPORT *pPrt; SK_U16 Ctrl1; @@ -1203,7 +2114,7 @@ SK_U16 Ctrl4; SK_U16 Ctrl5; - Ctrl1 = PHY_B_CT_SP1000; + Ctrl1 = PHY_CT_SP1000; Ctrl2 = 0; Ctrl3 = PHY_SEL_TYPE; Ctrl4 = PHY_B_PEC_EN_LTR; @@ -1213,120 +2124,452 @@ /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { - Ctrl2 |= PHY_B_1000C_MSE; + Ctrl2 |= PHY_B_1000C_MSE; + + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { + Ctrl2 |= PHY_B_1000C_MSC; + } + } + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); + /* Set DuplexMode in Config register */ + Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + + /* Determine Master/Slave manually if not already done */ + if (pPrt->PMSMode == SK_MS_MODE_AUTO) { + Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ + } + + /* + * Do NOT enable Auto-negotiation here. This would hold + * the link down because no IDLES are transmitted + */ + } + else { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyBcom: with auto-negotiation Port %d\n", Port)); + /* Set Auto-negotiation advertisement */ + + /* + * Workaround BCOM Errata #1 for the C5 type. + * 1000Base-T Link Acquisition Failure in Slave Mode + * Set Repeater/DTE bit 10 of the 1000Base-T Control Register + */ + Ctrl2 |= PHY_B_1000C_RD; + + /* Set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + Ctrl2 |= PHY_B_1000C_AHD; + break; + case SK_LMODE_AUTOFULL: + Ctrl2 |= PHY_B_1000C_AFD; + break; + case SK_LMODE_AUTOBOTH: + Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD; + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); + } + + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + Ctrl3 |= PHY_B_P_NO_PAUSE; + break; + case SK_FLOW_MODE_LOC_SEND: + Ctrl3 |= PHY_B_P_ASYM_MD; + break; + case SK_FLOW_MODE_SYMMETRIC: + Ctrl3 |= PHY_B_P_SYM_MD; + break; + case SK_FLOW_MODE_SYM_OR_REM: + Ctrl3 |= PHY_B_P_BOTH_MD; + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); + } + + /* Restart Auto-negotiation */ + Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; + } + + /* Initialize LED register here? */ + /* No. Please do it in SkDgXmitLed() (if required) and swap + init order of LEDs and XMAC. (MAl) */ + + /* Write 1000Base-T Control Register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); + + /* Write AutoNeg Advertisement Register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3)); + + if (DoLoop) { + /* Set the Phy Loopback bit, too */ + Ctrl1 |= PHY_CT_LOOP; + } + + if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + /* configure FIFO to high latency for transmission of ext. packets */ + Ctrl4 |= PHY_B_PEC_HIGH_LA; + + /* configure reception of extended packets */ + Ctrl5 |= PHY_B_AC_LONG_PACK; + + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5); + } + + /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); + + /* Write to the Phy control register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Control Reg=0x%04X\n", Ctrl1)); +} /* SkXmInitPhyBcom */ + + +/****************************************************************************** + * + * SkGmInitPhyMarv() - Initialize the Marvell Phy registers + * + * Description: initializes all the Marvell Phy registers + * + * Note: + * + * Returns: + * nothing + */ +static void SkGmInitPhyMarv( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ +{ + SK_GEPORT *pPrt; + SK_U16 PhyCtrl; + SK_U16 PhyStat; + SK_U16 PhyStat1; + SK_U16 PhySpec; + SK_U16 C1000BaseT; + SK_U16 AutoNegAdv; + SK_U16 ExtPhyCtrl; + +#ifdef VCPU + VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", + Port, DoLoop); +#else /* VCPU */ + + if (!DoLoop) { + /* Read Ext. PHY Specific Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); + + ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | + PHY_M_EC_MAC_S_MSK); + + ExtPhyCtrl |= PHY_M_EC_M_DSC(1) | PHY_M_EC_S_DSC(1) | + PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Ext.PHYCtrl=0x%04X\n", ExtPhyCtrl)); + + /* Read PHY Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); + + /* Assert software reset */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl | PHY_CT_RESET); + } +#endif /* VCPU */ + + pPrt = &pAC->GIni.GP[Port]; + + PhyCtrl = PHY_CT_COL_TST; + C1000BaseT = 0; + AutoNegAdv = PHY_SEL_TYPE; + + /* manually Master/Slave ? */ + if (pPrt->PMSMode != SK_MS_MODE_AUTO) { + /* enable Manual Master/Slave */ + C1000BaseT |= PHY_M_1000C_MSE; + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { - Ctrl2 |= PHY_B_1000C_MSC; + C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */ } } - /* Autonegotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("InitPhyBcom: no autonegotiation Port %d\n", Port)); - /* No Autonegiotiation */ - /* Set DuplexMode in Config register */ - Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyMarv: no auto-negotiation Port %d\n", Port)); + + if (pPrt->PLinkMode == SK_LMODE_FULL) { + /* Set Full Duplex Mode */ + PhyCtrl |= PHY_CT_DUP_MD; + } - /* Determine Master/Slave manually if not already done. */ + /* Set Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { - Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ + C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ } - /* - * Do NOT enable Autonegotiation here. This would hold - * the link down because no IDLES are transmitted - */ - } - else { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("InitPhyBcom: with autonegotiation Port %d\n", Port)); - /* Set Autonegotiation advertisement */ - - /* Set Full/half duplex capabilities */ - switch (pPrt->PLinkMode) { - case SK_LMODE_AUTOHALF: - Ctrl2 |= PHY_B_1000C_AHD; + /* Set Speed */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + case SK_LSPEED_1000MBPS: + PhyCtrl |= PHY_CT_SP1000; break; - case SK_LMODE_AUTOFULL: - Ctrl2 |= PHY_B_1000C_AFD; + case SK_LSPEED_100MBPS: + PhyCtrl |= PHY_CT_SP100; break; - case SK_LMODE_AUTOBOTH: - Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD; + case SK_LSPEED_10MBPS: break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E015, SKERR_HWI_E015MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, + SKERR_HWI_E019MSG); } - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - Ctrl3 |= PHY_B_P_NO_PAUSE; - break; - case SK_FLOW_MODE_LOC_SEND: - Ctrl3 |= PHY_B_P_ASYM_MD; - break; - case SK_FLOW_MODE_SYMMETRIC: - Ctrl3 |= PHY_B_P_SYM_MD; - break; - case SK_FLOW_MODE_SYM_OR_REM: - Ctrl3 |= PHY_B_P_BOTH_MD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E016, SKERR_HWI_E016MSG); + if (!DoLoop) { + PhyCtrl |= PHY_CT_RESET; } + /* + * Do NOT enable Auto-negotiation here. This would hold + * the link down because no IDLES are transmitted + */ + } + else { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyMarv: with auto-negotiation Port %d\n", Port)); + + PhyCtrl |= PHY_CT_ANE; + + if (pAC->GIni.GICopperType) { + /* Set Speed capabilities */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; + AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | + PHY_M_AN_10_FD | PHY_M_AN_10_HD; + break; + case SK_LSPEED_1000MBPS: + C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; + break; + case SK_LSPEED_100MBPS: + AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | + PHY_M_AN_10_FD | PHY_M_AN_10_HD; + break; + case SK_LSPEED_10MBPS: + AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, + SKERR_HWI_E019MSG); + } - /* Restart Autonegotiation */ - Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; + /* Set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + C1000BaseT &= ~PHY_M_1000C_AFD; + AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD); + break; + case SK_LMODE_AUTOFULL: + C1000BaseT &= ~PHY_M_1000C_AHD; + AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD); + break; + case SK_LMODE_AUTOBOTH: + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); + } + + /* Set Auto-negotiation advertisement */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + AutoNegAdv |= PHY_B_P_NO_PAUSE; + break; + case SK_FLOW_MODE_LOC_SEND: + AutoNegAdv |= PHY_B_P_ASYM_MD; + break; + case SK_FLOW_MODE_SYMMETRIC: + AutoNegAdv |= PHY_B_P_SYM_MD; + break; + case SK_FLOW_MODE_SYM_OR_REM: + AutoNegAdv |= PHY_B_P_BOTH_MD; + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); + } + } + else { /* special defines for FIBER (88E1011S only) */ + + /* Set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + AutoNegAdv |= PHY_M_AN_1000X_AHD; + break; + case SK_LMODE_AUTOFULL: + AutoNegAdv |= PHY_M_AN_1000X_AFD; + break; + case SK_LMODE_AUTOBOTH: + AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); + } + + /* Set Auto-negotiation advertisement */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + AutoNegAdv |= PHY_M_P_NO_PAUSE_X; + break; + case SK_FLOW_MODE_LOC_SEND: + AutoNegAdv |= PHY_M_P_ASYM_MD_X; + break; + case SK_FLOW_MODE_SYMMETRIC: + AutoNegAdv |= PHY_M_P_SYM_MD_X; + break; + case SK_FLOW_MODE_SYM_OR_REM: + AutoNegAdv |= PHY_M_P_BOTH_MD_X; + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); + } + } + if (!DoLoop) { + /* Restart Auto-negotiation */ + PhyCtrl |= PHY_CT_RE_CFG; + } } - /* Initialize LED register here? */ - /* No. Please do it in SkDgXmitLed() (if required) and swap - init order of LEDs and XMAC. (MAl) */ +#ifdef VCPU + /* + * E-mail from Gu Lin (08-03-2002): + */ + + /* Program PHY register 30 as 16'h0708 for simulation speed up */ + SkGmPhyWrite(pAC, IoC, Port, 30, 0x0708); + +#if 0 + /* Program PHY register 20 as 16'h2070 */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, 0x2070); +#endif /* 0 */ + + VCpuWait(2000); + +#else /* VCPU */ /* Write 1000Base-T Control Register */ - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_1000T_CTRL, Ctrl2); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("1000Base-T Control Reg = %x\n", Ctrl2)); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("1000B-T Ctrl=0x%04X\n", C1000BaseT)); /* Write AutoNeg Advertisement Register */ - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUNE_ADV, Ctrl3); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNeg Advertisment Reg = %x\n", Ctrl3)); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv)); +#endif /* VCPU */ - if (DoLoop) { - /* Set the Phy Loopback bit, too */ - Ctrl1 |= PHY_CT_LOOP; - } - - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - /* configure fifo to high latency for xmission of ext. packets*/ - Ctrl4 |= PHY_B_PEC_HIGH_LA; + /* Set the PHY Loopback bit */ + PhyCtrl |= PHY_CT_LOOP; - /* configure reception of extended packets */ - Ctrl5 |= PHY_B_AC_LONG_PACK; + /* Program PHY register 16 as 16'h0400 to force link good */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, Ctrl5); +#if 0 + if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { + /* Write Ext. PHY Specific Control */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, + (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); + } + } + else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { + /* Write PHY Specific Control */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK); + } +#endif /* 0 */ } - /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); + /* Write to the PHY Control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); + +#ifdef VCPU + VCpuWait(2000); +#endif /* VCPU */ + +#ifdef SK_DIAG + c_print("PHY Ctrl Val=0x%04X\n", PhyCtrl); + c_print("1000 B-T Val=0x%04X\n", C1000BaseT); + c_print("Auto-Neg Val=0x%04X\n", AutoNegAdv); + c_print("Ext Ctrl Val=0x%04X\n", ExtPhyCtrl); +#endif /* SK_DIAG */ + +#ifndef VCPU + /* Read PHY Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); - /* Write to the Phy control register */ - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl1); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("PHY Control Reg = %x\n", Ctrl1)); -} /* SkXmInitPhyBcom */ + /* Read 1000Base-T Control Register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("1000B-T Ctrl =0x%04X\n", C1000BaseT)); + + /* Read AutoNeg Advertisement Register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv)); + + /* Read Ext. PHY Specific Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Ext PHY Ctrl=0x%04X\n", ExtPhyCtrl)); + + /* Read PHY Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Stat Reg.=0x%04X\n", PhyStat)); + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Stat Reg.=0x%04X\n", PhyStat1)); + + /* Read PHY Specific Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpec); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Spec Stat=0x%04X\n", PhySpec)); +#endif /* VCPU */ + +#ifdef SK_DIAG + c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); + c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT); + c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv); + c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); + c_print("PHY Stat Reg=0x%04X\n", PhyStat); + c_print("PHY Stat Reg=0x%04X\n", PhyStat1); + c_print("PHY Spec Reg=0x%04X\n", PhySpec); +#endif /* SK_DIAG */ + +} /* SkGmInitPhyMarv */ +#ifdef OTHER_PHY /****************************************************************************** * * SkXmInitPhyLone() - Initialize the Level One Phy registers * - * Description: - * Initialize all the Level One Phy registers + * Description: initializes all the Level One Phy registers * * Note: * @@ -1337,14 +2580,14 @@ SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */ +SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { SK_GEPORT *pPrt; SK_U16 Ctrl1; SK_U16 Ctrl2; SK_U16 Ctrl3; - Ctrl1 = PHY_L_CT_SP1000; + Ctrl1 = PHY_CT_SP1000; Ctrl2 = 0; Ctrl3 = PHY_SEL_TYPE; @@ -1353,39 +2596,36 @@ /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Ctrl2 |= PHY_L_1000C_MSE; + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Ctrl2 |= PHY_L_1000C_MSC; } } - /* Autonegotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL) { + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* * level one spec say: "1000Mbps: manual mode not allowed" * but lets see what happens... */ - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - 0, "Level One PHY only works with Autoneg"); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("InitPhyLone: no autonegotiation Port %d\n", Port)); - /* No Autonegiotiation */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyLone: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); - /* Determine Master/Slave manually if not already done. */ + /* Determine Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */ } /* - * Do NOT enable Autonegotiation here. This would hold + * Do NOT enable Auto-negotiation here. This would hold * the link down because no IDLES are transmitted */ } else { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("InitPhyLone: with autonegotiation Port %d\n", Port)); - /* Set Autonegotiation advertisement */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyLone: with auto-negotiation Port %d\n", Port)); + /* Set Auto-negotiation advertisement */ /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { @@ -1399,8 +2639,8 @@ Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD; break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E015, SKERR_HWI_E015MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); } switch (pPrt->PFlowCtrlMode) { @@ -1417,11 +2657,11 @@ Ctrl3 |= PHY_L_P_BOTH_MD; break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E016, SKERR_HWI_E016MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); } - /* Restart Autonegotiation */ + /* Restart Auto-negotiation */ Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; } @@ -1431,14 +2671,14 @@ init order of LEDs and XMAC. (MAl) */ /* Write 1000Base-T Control Register */ - PHY_WRITE(IoC, pPrt, Port, PHY_LONE_1000T_CTRL, Ctrl2); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("1000Base-T Control Reg = %x\n", Ctrl2)); + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); /* Write AutoNeg Advertisement Register */ - PHY_WRITE(IoC, pPrt, Port, PHY_LONE_AUNE_ADV, Ctrl3); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNeg Advertisment Reg = %x\n", Ctrl3)); + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3)); if (DoLoop) { @@ -1446,26 +2686,18 @@ Ctrl1 |= PHY_CT_LOOP; } - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - /* - * nothing to do for Level one. - * PHY supports frames up to 10k. - */ - } - /* Write to the Phy control register */ - PHY_WRITE(IoC, pPrt, Port, PHY_LONE_CTRL, Ctrl1); - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("PHY Control Reg = %x\n", Ctrl1)); -} /* SkXmInitPhyLone*/ + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Control Reg=0x%04X\n", Ctrl1)); +} /* SkXmInitPhyLone */ /****************************************************************************** * * SkXmInitPhyNat() - Initialize the National Phy registers * - * Description: - * Initialize all the National Phy registers + * Description: initializes all the National Phy registers * * Note: * @@ -1476,103 +2708,96 @@ SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */ +SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { /* todo: National */ -} /* SkXmInitPhyNat*/ +} /* SkXmInitPhyNat */ +#endif /* OTHER_PHY */ /****************************************************************************** * - * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do autoneg + * SkMacInitPhy() - Initialize the PHY registers * - * This function analyses the Interrupt status word. If any of the - * Autonegotiating interrupt bits are set, the PLipaAutoNeg variable - * is set true. - */ -void SkXmAutoNegLipaXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus) /* Interrupt Status word to analyse */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (IStatus & (XM_IS_LIPA_RC|XM_IS_RX_PAGE|XM_IS_AND))) { - - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, IStatus)); - pPrt->PLipaAutoNeg = SK_LIPA_AUTO; - } -} /* SkXmAutoNegLipaXmac*/ - - -/****************************************************************************** + * Description: calls the Init PHY routines dep. on board type * - * SkXmAutoNegLipaBcom() - Decides whether Link Partner could do autoneg + * Note: * - * This function analyses the PHY status word. If any of the - * Autonegotiating bits are set, The PLipaAutoNeg variable - * is set true. + * Returns: + * nothing */ -void SkXmAutoNegLipaBcom( +void SkMacInitPhy( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ -SK_U16 PhyStat) /* PHY Status word to analyse */ +SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; - if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & PHY_ST_AN_OVER)) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat)); - pPrt->PLipaAutoNeg = SK_LIPA_AUTO; + switch (pPrt->PhyType) { + case SK_PHY_XMAC: + SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); + break; + case SK_PHY_BCOM: + SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); + break; + case SK_PHY_MARV_COPPER: + case SK_PHY_MARV_FIBER: + SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); + break; +#ifdef OTHER_PHY + case SK_PHY_LONE: + SkXmInitPhyLone(pAC, IoC, Port, DoLoop); + break; + case SK_PHY_NAT: + SkXmInitPhyNat(pAC, IoC, Port, DoLoop); + break; +#endif /* OTHER_PHY */ } -} /* SkXmAutoNegLipaBcom*/ +} /* SkMacInitPhy */ +#ifndef SK_DIAG /****************************************************************************** * - * SkXmAutoNegLipaLone() - Decides whether Link Partner could do autoneg + * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg * - * This function analyses the PHY status word. If any of the - * Autonegotiating bits are set, The PLipaAutoNeg variable + * This function analyses the Interrupt status word. If any of the + * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable * is set true. */ -void SkXmAutoNegLipaLone( +void SkXmAutoNegLipaXmac( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 PhyStat) /* PHY Status word to analyse */ +int Port, /* Port Index (MAC_1 + n) */ +SK_U16 IStatus) /* Interrupt Status word to analyse */ { SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (PhyStat & (PHY_ST_AN_OVER))) { + (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04x\n", + Port, IStatus)); pPrt->PLipaAutoNeg = SK_LIPA_AUTO; } -} /* SkXmAutoNegLipaLone*/ +} /* SkXmAutoNegLipaXmac */ /****************************************************************************** * - * SkXmAutoNegLipaNat() - Decides whether Link Partner could do autoneg + * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg * - * This function analyses the PHY status word. If any of the - * Autonegotiating bits are set, The PLipaAutoNeg variable + * This function analyses the PHY status word. + * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable * is set true. */ -void SkXmAutoNegLipaNat( +void SkMacAutoNegLipaPhy( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ @@ -1583,67 +2808,30 @@ pPrt = &pAC->GIni.GP[Port]; if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (PhyStat & (PHY_ST_AN_OVER))) { + (PhyStat & PHY_ST_AN_OVER) != 0) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04x\n", + Port, PhyStat)); pPrt->PLipaAutoNeg = SK_LIPA_AUTO; } -} /* SkXmAutoNegLipaNat*/ - - -/****************************************************************************** - * - * SkXmAutoNegDone() - Auto negotiation handling - * - * Description: - * This function handles the autonegotiation if the Done bit is set. - * - * Note: - * o The XMACs interrupt source register is NOT read here. - * o This function is public because it is used in the diagnostics - * tool, too. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -int SkXmAutoNegDone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - switch (pAC->GIni.GP[Port].PhyType) { - case SK_PHY_XMAC: - return (SkXmAutoNegDoneXmac(pAC, IoC, Port)); - case SK_PHY_BCOM: - return (SkXmAutoNegDoneBcom(pAC, IoC, Port)); - case SK_PHY_LONE: - return (SkXmAutoNegDoneLone(pAC, IoC, Port)); - case SK_PHY_NAT: - return (SkXmAutoNegDoneNat(pAC, IoC, Port)); - } - return (SK_AND_OTHER); -} /* SkXmAutoNegDone*/ +} /* SkMacAutoNegLipaPhy */ +#endif /* SK_DIAG */ /****************************************************************************** * - * SkXmAutoNegDoneXmac() - Auto negotiation handling + * SkXmAutoNegDoneXmac() - Auto-negotiation handling * * Description: - * This function handles the autonegotiation if the Done bit is set. - * - * Note: - * o The XMACs interrupt source register is NOT read here. + * This function handles the auto-negotiation if the Done bit is set. * * Returns: * SK_AND_OK o.k. * SK_AND_DUP_CAP Duplex capability error happened * SK_AND_OTHER Other error happened */ -static int SkXmAutoNegDoneXmac( +static int SkXmAutoNegDoneXmac( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1652,22 +2840,22 @@ SK_U16 ResAb; /* Resolved Ability */ SK_U16 LPAb; /* Link Partner Ability */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneXmac" - "Port %d\n",Port)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegDoneXmac, Port %d\n",Port)); pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ - PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP, &LPAb); - PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI, &ResAb); + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb); + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); - if (LPAb & PHY_X_AN_RFB) { + if ((LPAb & PHY_X_AN_RFB) != 0) { /* At least one of the remote fault bit is set */ /* Error */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - return (SK_AND_OTHER); + return(SK_AND_OTHER); } /* Check Duplex mismatch */ @@ -1679,10 +2867,10 @@ } else { /* Error */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNegFail: Duplex mode mismatch port %d\n", Port)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - return (SK_AND_DUP_CAP); + return(SK_AND_DUP_CAP); } /* Check PAUSE mismatch */ @@ -1690,7 +2878,7 @@ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC || pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && - (LPAb & PHY_X_P_SYM_MD)) { + (LPAb & PHY_X_P_SYM_MD) != 0) { /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } @@ -1708,31 +2896,25 @@ /* PAUSE mismatch -> no PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; - /* We checked everything and may now enable the link */ - pPrt->PAutoNegFail = SK_FALSE; - - SkXmRxTxEnable(pAC, IoC, Port); - return (SK_AND_OK); -} /* SkXmAutoNegDoneXmac*/ + return(SK_AND_OK); +} /* SkXmAutoNegDoneXmac */ /****************************************************************************** * - * SkXmAutoNegDoneBcom() - Auto negotiation handling + * SkXmAutoNegDoneBcom() - Auto-negotiation handling * * Description: - * This function handles the autonegotiation if the Done bit is set. - * - * Note: - * o The XMACs interrupt source register is NOT read here. + * This function handles the auto-negotiation if the Done bit is set. * * Returns: * SK_AND_OK o.k. * SK_AND_DUP_CAP Duplex capability error happened * SK_AND_OTHER Other error happened */ -static int SkXmAutoNegDoneBcom( +static int SkXmAutoNegDoneBcom( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1746,105 +2928,199 @@ SK_U16 ResAb; /* Resolved Ability */ #endif /* 0 */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegDoneBcom, Port %d\n", Port)); pPrt = &pAC->GIni.GP[Port]; - /* Get PHY parameters. */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LPAb); + /* Get PHY parameters */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb); #if 0 01-Sep-2000 RA;:;: - PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); #endif /* 0 */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_STAT, &AuxStat); + + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat); - if (LPAb & PHY_B_AN_RF) { - /* Remote fault bit is set: Error. */ + if ((LPAb & PHY_B_AN_RF) != 0) { + /* Remote fault bit is set: Error */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - return (SK_AND_OTHER); + return(SK_AND_OTHER); } - /* Check Duplex mismatch. */ - if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000FD) { + /* Check Duplex mismatch */ + if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; } - else if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000HD) { + else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; } else { - /* Error. */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("AutoNegFail: Duplex mode mismatch port %d\n", Port)); + /* Error */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - return (SK_AND_DUP_CAP); + return(SK_AND_DUP_CAP); } #if 0 01-Sep-2000 RA;:;: - /* Check Master/Slave resolution. */ - if (ResAb & PHY_B_1000S_MSF) { - /* Error. */ + /* Check Master/Slave resolution */ + if ((ResAb & PHY_B_1000S_MSF) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault port %d\n", Port)); + ("Master/Slave Fault Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; - return (SK_AND_OTHER); + return(SK_AND_OTHER); } - else if (ResAb & PHY_B_1000S_MSR) { - pPrt->PMSStatus = SK_MS_STAT_MASTER; + + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; +#endif /* 0 */ + + /* Check PAUSE mismatch */ + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) { + /* Symmetric PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; + } + else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) { + /* Enable PAUSE receive, disable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; + } + else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) { + /* Disable PAUSE receive, enable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } else { - pPrt->PMSStatus = SK_MS_STAT_SLAVE; + /* PAUSE mismatch -> no PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + } + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + + return(SK_AND_OK); +} /* SkXmAutoNegDoneBcom */ + + +/****************************************************************************** + * + * SkGmAutoNegDoneMarv() - Auto-negotiation handling + * + * Description: + * This function handles the auto-negotiation if the Done bit is set. + * + * Returns: + * SK_AND_OK o.k. + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened + */ +static int SkGmAutoNegDoneMarv( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + SK_U16 LPAb; /* Link Partner Ability */ + SK_U16 ResAb; /* Resolved Ability */ + SK_U16 AuxStat; /* Auxiliary Status */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegDoneMarv, Port %d\n", Port)); + pPrt = &pAC->GIni.GP[Port]; + + /* Get PHY parameters */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); + + if ((LPAb & PHY_B_AN_RF) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegFail: Remote fault bit set Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_OTHER); + } + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); + + /* Check Master/Slave resolution */ + if ((ResAb & PHY_B_1000S_MSF) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Master/Slave Fault Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; + return(SK_AND_OTHER); + } + + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; + + /* Read PHY Specific Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat); + + /* Check Speed & Duplex resolved */ + if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegFail: Speed & Duplex not resolved Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; + return(SK_AND_DUP_CAP); + } + + if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { + pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + } + else { + pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; } -#endif /* 0 */ - - /* Check PAUSE mismatch. */ - /* We are NOT using chapter 4.23 of the Xaqti manual. */ - /* We are using IEEE 802.3z/D5.0 Table 37-4. */ - if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == - (PHY_B_AS_PRR | PHY_B_AS_PRT)) { - /* Symmetric PAUSE. */ + + /* Check PAUSE mismatch */ + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) { + /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } - else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRR) { - /* Enable PAUSE receive, disable PAUSE transmit. */ + else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) { + /* Enable PAUSE receive, disable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } - else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRT) { - /* Disable PAUSE receive, enable PAUSE transmit. */ + else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) { + /* Disable PAUSE receive, enable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } else { - /* PAUSE mismatch -> no PAUSE. */ + /* PAUSE mismatch -> no PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } + + /* set used link speed */ + switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { + case (unsigned)PHY_M_PS_SPEED_1000: + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + break; + case PHY_M_PS_SPEED_100: + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS; + break; + default: + pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS; + } - /* We checked everything and may now enable the link. */ - pPrt->PAutoNegFail = SK_FALSE; - - SkXmRxTxEnable(pAC, IoC, Port); - return (SK_AND_OK); -} /* SkXmAutoNegDoneBcom*/ + return(SK_AND_OK); +} /* SkGmAutoNegDoneMarv */ +#ifdef OTHER_PHY /****************************************************************************** * - * SkXmAutoNegDoneLone() - Auto negotiation handling + * SkXmAutoNegDoneLone() - Auto-negotiation handling * * Description: - * This function handles the autonegotiation if the Done bit is set. - * - * Note: - * o The XMACs interrupt source register is NOT read here. + * This function handles the auto-negotiation if the Done bit is set. * * Returns: * SK_AND_OK o.k. * SK_AND_DUP_CAP Duplex capability error happened * SK_AND_OTHER Other error happened */ -static int SkXmAutoNegDoneLone( +static int SkXmAutoNegDoneLone( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1854,26 +3130,26 @@ SK_U16 LPAb; /* Link Partner Ability */ SK_U16 QuickStat; /* Auxiliary Status */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneLone" - "Port %d\n",Port)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegDoneLone, Port %d\n",Port)); pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ - PHY_READ(IoC, pPrt, Port, PHY_LONE_AUNE_LP, &LPAb); - PHY_READ(IoC, pPrt, Port, PHY_LONE_1000T_STAT, &ResAb); - PHY_READ(IoC, pPrt, Port, PHY_LONE_Q_STAT, &QuickStat); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat); - if (LPAb & PHY_L_AN_RF) { + if ((LPAb & PHY_L_AN_RF) != 0) { /* Remote fault bit is set */ /* Error */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - return (SK_AND_OTHER); + return(SK_AND_OTHER); } /* Check Duplex mismatch */ - if (QuickStat & PHY_L_QS_DUP_MOD) { + if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; } else { @@ -1881,13 +3157,13 @@ } /* Check Master/Slave resolution */ - if (ResAb & (PHY_L_1000S_MSF)) { + if ((ResAb & PHY_L_1000S_MSF) != 0) { /* Error */ - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, - ("Master/Slave Fault port %d\n", Port)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Master/Slave Fault Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; - return (SK_AND_OTHER); + return(SK_AND_OTHER); } else if (ResAb & PHY_L_1000S_MSR) { pPrt->PMSStatus = SK_MS_STAT_MASTER; @@ -1897,7 +3173,6 @@ } /* Check PAUSE mismatch */ - /* We are NOT using chapter 4.23 of the Xaqti manual */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ /* we must manually resolve the abilities here */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; @@ -1913,7 +3188,7 @@ } break; case SK_FLOW_MODE_SYMMETRIC: - if ((QuickStat & PHY_L_QS_PAUSE) == PHY_L_QS_PAUSE) { + if ((QuickStat & PHY_L_QS_PAUSE) != 0) { /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } @@ -1924,154 +3199,545 @@ /* Enable PAUSE receive, disable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } - else if ((QuickStat & PHY_L_QS_PAUSE) == PHY_L_QS_PAUSE) { + else if ((QuickStat & PHY_L_QS_PAUSE) != 0) { /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } break; default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, - SKERR_HWI_E016, SKERR_HWI_E016MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); } - - /* We checked everything and may now enable the link */ - pPrt->PAutoNegFail = SK_FALSE; - - SkXmRxTxEnable(pAC, IoC, Port); - return (SK_AND_OK); + + return(SK_AND_OK); } /* SkXmAutoNegDoneLone */ /****************************************************************************** * - * SkXmAutoNegDoneNat() - Auto negotiation handling + * SkXmAutoNegDoneNat() - Auto-negotiation handling * * Description: - * This function handles the autonegotiation if the Done bit is set. - * - * Note: - * o The XMACs interrupt source register is NOT read here. - * o This function is public because it is used in the diagnostics - * tool, too. + * This function handles the auto-negotiation if the Done bit is set. * * Returns: * SK_AND_OK o.k. * SK_AND_DUP_CAP Duplex capability error happened * SK_AND_OTHER Other error happened */ -static int SkXmAutoNegDoneNat( +static int SkXmAutoNegDoneNat( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { /* todo: National */ - return (SK_AND_OK); -} /* SkXmAutoNegDoneNat*/ + return(SK_AND_OK); +} /* SkXmAutoNegDoneNat */ +#endif /* OTHER_PHY */ + + +/****************************************************************************** + * + * SkMacAutoNegDone() - Auto-negotiation handling + * + * Description: calls the auto-negotiation done routines dep. on board type + * + * Returns: + * SK_AND_OK o.k. + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened + */ +int SkMacAutoNegDone( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + int Rtv; + + pPrt = &pAC->GIni.GP[Port]; + + switch (pPrt->PhyType) { + case SK_PHY_XMAC: + Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); + break; + case SK_PHY_BCOM: + Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port); + break; + case SK_PHY_MARV_COPPER: + case SK_PHY_MARV_FIBER: + Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); + break; +#ifdef OTHER_PHY + case SK_PHY_LONE: + Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port); + break; + case SK_PHY_NAT: + Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port); + break; +#endif /* OTHER_PHY */ + default: + return(SK_AND_OTHER); + } + + if (Rtv != SK_AND_OK) { + return(Rtv); + } + + /* We checked everything and may now enable the link */ + pPrt->PAutoNegFail = SK_FALSE; + + SkMacRxTxEnable(pAC, IoC, Port); + + return(SK_AND_OK); +} /* SkMacAutoNegDone */ /****************************************************************************** * - * SkXmRxTxEnable() - Enable RxTx activity if port is up + * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC * * Description: + * sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg. + * enables Rx/Tx * - * Note: - * o The XMACs interrupt source register is NOT read here. + * Returns: N/A + */ +static void SkXmSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */ +{ + SK_U16 Word; + + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + + switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { + case SK_MAC_LOOPB_ON: + Word |= XM_MMU_MAC_LB; + break; + case SK_MAC_LOOPB_OFF: + Word &= ~XM_MMU_MAC_LB; + break; + } + + switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) { + case SK_PHY_LOOPB_ON: + Word |= XM_MMU_GMII_LOOP; + break; + case SK_PHY_LOOPB_OFF: + Word &= ~XM_MMU_GMII_LOOP; + break; + } + + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { + case SK_PHY_FULLD_ON: + Word |= XM_MMU_GMII_FD; + break; + case SK_PHY_FULLD_OFF: + Word &= ~XM_MMU_GMII_FD; + break; + } + + XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX); + + /* dummy read to ensure writing */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + +} /* SkXmSetRxTxEn */ + + +/****************************************************************************** + * + * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC + * + * Description: + * sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg. + * enables Rx/Tx + * + * Returns: N/A + */ +static void SkGmSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */ +{ + SK_U16 Ctrl; + + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); + + switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { + case SK_MAC_LOOPB_ON: + Ctrl |= GM_GPCR_LOOP_ENA; + break; + case SK_MAC_LOOPB_OFF: + Ctrl &= ~GM_GPCR_LOOP_ENA; + break; + } + + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { + case SK_PHY_FULLD_ON: + Ctrl |= GM_GPCR_DUP_FULL; + break; + case SK_PHY_FULLD_OFF: + Ctrl &= ~GM_GPCR_DUP_FULL; + break; + } + + GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + + /* dummy read to ensure writing */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); + +} /* SkGmSetRxTxEn */ + + +/****************************************************************************** + * + * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters + * + * Description: calls the Special Set Rx/Tx Enable routines dep. on board type + * + * Returns: N/A + */ +void SkMacSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) +{ + if (pAC->GIni.GIGenesis) { + + SkXmSetRxTxEn(pAC, IoC, Port, Para); + } + else { + + SkGmSetRxTxEn(pAC, IoC, Port, Para); + } + +} /* SkMacSetRxTxEn */ + + +/****************************************************************************** + * + * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up + * + * Description: enables Rx/Tx dep. on board type * * Returns: * 0 o.k. * != 0 Error happened */ -int SkXmRxTxEnable( +int SkMacRxTxEnable( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_U16 Reg; /* 16bit register value */ - SK_U16 IntMask; /* XMac interrupt mask */ + SK_U16 Reg; /* 16-bit register value */ + SK_U16 IntMask; /* MAC interrupt mask */ SK_U16 SWord; pPrt = &pAC->GIni.GP[Port]; if (!pPrt->PHWLinkUp) { /* The Hardware link is NOT up */ - return (0); + return(0); } if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF || pPrt->PLinkMode == SK_LMODE_AUTOFULL || pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && pPrt->PAutoNegFail) { - /* Autonegotiation is not done or failed */ - return (0); + /* Auto-negotiation is not done or failed */ + return(0); } - /* Set Dup Mode and Pause Mode */ - SkXmInitDupMd (pAC, IoC, Port); - SkXmInitPauseMd (pAC, IoC, Port); - - /* - * Initialize the Interrupt Mask Register. Default IRQs are... - * - Link Asynchronous Event - * - Link Partner requests config - * - Auto Negotiation Done - * - Rx Counter Event Overflow - * - Tx Counter Event Overflow - * - Transmit FIFO Underrun - */ - if (pPrt->PhyType == SK_PHY_XMAC) { + if (pAC->GIni.GIGenesis) { + /* set Duplex Mode and Pause Mode */ + SkXmInitDupMd(pAC, IoC, Port); + + SkXmInitPauseMd(pAC, IoC, Port); + + /* + * Initialize the Interrupt Mask Register. Default IRQs are... + * - Link Asynchronous Event + * - Link Partner requests config + * - Auto Negotiation Done + * - Rx Counter Event Overflow + * - Tx Counter Event Overflow + * - Transmit FIFO Underrun + */ IntMask = XM_DEF_MSK; + +#ifdef DEBUG + /* add IRQ for Receive FIFO Overflow */ + IntMask &= ~XM_IS_RXF_OV; +#endif /* DEBUG */ + + if (pPrt->PhyType != SK_PHY_XMAC) { + /* disable GP0 interrupt bit */ + IntMask |= XM_IS_INP_ASS; + } + XM_OUT16(IoC, Port, XM_IMSK, IntMask); + + /* get MMU Command Reg. */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); + + if (pPrt->PhyType != SK_PHY_XMAC && + (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { + /* set to Full Duplex */ + Reg |= XM_MMU_GMII_FD; + } + + switch (pPrt->PhyType) { + case SK_PHY_BCOM: + /* + * Workaround BCOM Errata (#10523) for all BCom Phys + * Enable Power Management after link up + */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, + (SK_U16)(SWord & ~PHY_B_AC_DIS_PM)); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); + break; +#ifdef OTHER_PHY + case SK_PHY_LONE: + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK); + break; + case SK_PHY_NAT: + /* todo National: + SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */ + /* no interrupts possible from National ??? */ + break; +#endif /* OTHER_PHY */ + } + + /* enable Rx/Tx */ + XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); } else { - /* disable GP0 interrupt bit */ - IntMask = XM_DEF_MSK | XM_IS_INP_ASS; + /* + * Initialize the Interrupt Mask Register. Default IRQs are... + * - Rx Counter Event Overflow + * - Tx Counter Event Overflow + * - Transmit FIFO Underrun + */ + IntMask = GMAC_DEF_MSK; + +#ifdef DEBUG + /* add IRQ for Receive FIFO Overrun */ + IntMask |= GM_IS_RX_FF_OR; +#endif /* DEBUG */ + + SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask); + + /* get General Purpose Control */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Reg); + + if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) { + /* set to Full Duplex */ + Reg |= GM_GPCR_DUP_FULL; + } + + /* enable Rx/Tx */ + GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + +#ifndef VCPU + /* Enable all PHY interrupts */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); +#endif /* VCPU */ } - XM_OUT16(IoC, Port, XM_IMSK, IntMask); + + return(0); + +} /* SkMacRxTxEnable */ + + +/****************************************************************************** + * + * SkMacRxTxDisable() - Disable Receiver and Transmitter + * + * Description: disables Rx/Tx dep. on board type + * + * Returns: N/A + */ +void SkMacRxTxDisable( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U16 Word; - /* RX/TX enable */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); - if (pPrt->PhyType != SK_PHY_XMAC && - (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { - Reg |= XM_MMU_GMII_FD; + if (pAC->GIni.GIGenesis) { + + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + + XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); + + /* dummy read to ensure writing */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); } - switch (pPrt->PhyType) { - case SK_PHY_BCOM: - /* Workaround BCOM Errata (#10523) for all BCom Phys */ - /* Enable Power Management after link up */ - PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, SWord & ~PHY_B_AC_DIS_PM); - PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); - break; - case SK_PHY_LONE: - PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK); - break; - case SK_PHY_NAT: - /* todo National: - PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, - PHY_N_DEF_MSK); */ - /* no interrupts possible from National ??? */ - break; + else { + + GM_IN16(IoC, Port, GM_GP_CTRL, &Word); + + GM_OUT16(IoC, Port, GM_GP_CTRL, Word & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); + + /* dummy read to ensure writing */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Word); + } +} /* SkMacRxTxDisable */ + + +/****************************************************************************** + * + * SkMacIrqDisable() - Disable IRQ from MAC + * + * Description: sets the IRQ-mask to disable IRQ dep. on board type + * + * Returns: N/A + */ +void SkMacIrqDisable( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + SK_U16 Word; + + pPrt = &pAC->GIni.GP[Port]; + + if (pAC->GIni.GIGenesis) { + + /* disable all XMAC IRQs */ + XM_OUT16(IoC, Port, XM_IMSK, 0xffff); + + /* Disable all PHY interrupts */ + switch (pPrt->PhyType) { + case SK_PHY_BCOM: + /* Make sure that PHY is initialized */ + if (pPrt->PState != SK_PRT_RESET) { + /* NOT allowed if BCOM is in RESET state */ + /* Workaround BCOM Errata (#10523) all BCom */ + /* Disable Power Management if link is down */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, + (SK_U16)(Word | PHY_B_AC_DIS_PM)); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff); + } + break; +#ifdef OTHER_PHY + case SK_PHY_LONE: + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0); + break; + case SK_PHY_NAT: + /* todo: National + SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */ + break; +#endif /* OTHER_PHY */ + } + } + else { + /* disable all GMAC IRQs */ + SK_OUT8(IoC, GMAC_IRQ_MSK, 0); + +#ifndef VCPU + /* Disable all PHY interrupts */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); +#endif /* VCPU */ + } +} /* SkMacIrqDisable */ + + +#ifdef SK_DIAG +/****************************************************************************** + * + * SkXmSendCont() - Enable / Disable Send Continuous Mode + * + * Description: enable / disable Send Continuous Mode on XMAC + * + * Returns: + * nothing + */ +void SkXmSendCont( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL Enable) /* Enable / Disable */ +{ + SK_U32 MdReg; + + XM_IN32(IoC, Port, XM_MODE, &MdReg); + + if (Enable) { + MdReg |= XM_MD_TX_CONT; + } + else { + MdReg &= ~XM_MD_TX_CONT; + } + /* setup Mode Register */ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + +} /* SkXmSendCont*/ + +/****************************************************************************** + * + * SkMacTimeStamp() - Enable / Disable Time Stamp + * + * Description: enable / disable Time Stamp generation for Rx packets + * + * Returns: + * nothing + */ +void SkMacTimeStamp( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL Enable) /* Enable / Disable */ +{ + SK_U32 MdReg; + SK_U8 TimeCtrl; + + if (pAC->GIni.GIGenesis) { + + XM_IN32(IoC, Port, XM_MODE, &MdReg); + + if (Enable) { + MdReg |= XM_MD_ATS; + } + else { + MdReg &= ~XM_MD_ATS; + } + /* setup Mode Register */ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + else { + if (Enable) { + TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ; + } + else { + TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ; + } + /* Start/Stop Time Stamp Timer */ + SK_OUT8(pAC, GMAC_TI_ST_CTRL, TimeCtrl); } - XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); - - return (0); -} /* SkXmRxTxEnable*/ +} /* SkMacTimeStamp*/ -#ifndef SK_DIAG +#else /* SK_DIAG */ /****************************************************************************** * - * SkXmIrq() - Interrupt service routine + * SkXmIrq() - Interrupt Service Routine * - * Description: - * Services an Interrupt of the XMAC II + * Description: services an Interrupt Request of the XMAC * * Note: - * The XMACs interrupt source register is NOT read here. - * With an external PHY, some interrupt bits are not meaningfull - * any more: + * With an external PHY, some interrupt bits are not meaningfull any more: * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC * - Page Received (bit #9) XM_IS_RX_PAGE @@ -2086,124 +3752,589 @@ void SkXmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus) /* Interrupt status read from the XMAC */ +int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; SK_EVPARA Para; + SK_U16 IStatus; /* Interrupt status read from the XMAC */ SK_U16 IStatus2; pPrt = &pAC->GIni.GP[Port]; - if (pPrt->PhyType != SK_PHY_XMAC) { + XM_IN16(IoC, Port, XM_ISRC, &IStatus); + + /* LinkPartner Auto-negable? */ + if (pPrt->PhyType == SK_PHY_XMAC) { + SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); + } + else { /* mask bits that are not used with ext. PHY */ IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_TX_PAGE | XM_IS_AND | XM_IS_INP_ASS); } - /* - * LinkPartner Autonegable? - */ - if (pPrt->PhyType == SK_PHY_XMAC) { - SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); - } - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("XmacIrq Port %d Isr %x\n", Port, IStatus)); + ("XmacIrq Port %d Isr 0x%04x\n", Port, IStatus)); if (!pPrt->PHWLinkUp) { /* Spurious XMAC interrupt */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("SkXmIrq: spurious interrupt on port %d\n", Port)); + ("SkXmIrq: spurious interrupt on Port %d\n", Port)); return; } - if (IStatus & XM_IS_INP_ASS) { + if ((IStatus & XM_IS_INP_ASS) != 0) { /* Reread ISR Register if link is not in sync */ XM_IN16(IoC, Port, XM_ISRC, &IStatus2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("SkXmIrq: Link async. Double check port %d %x %x\n", + ("SkXmIrq: Link async. Double check Port %d 0x%04x 0x%04x\n", Port, IStatus, IStatus2)); IStatus &= ~XM_IS_INP_ASS; IStatus |= IStatus2; - } - if (IStatus & XM_IS_LNK_AE) { - /* not used GP0 is used instead */ + if ((IStatus & XM_IS_LNK_AE) != 0) { + /* not used, GP0 is used instead */ } - if (IStatus & XM_IS_TX_ABORT) { + if ((IStatus & XM_IS_TX_ABORT) != 0) { /* not used */ } - if (IStatus & XM_IS_FRC_INT) { - /* not used. use ASIC IRQ instead if needed */ + if ((IStatus & XM_IS_FRC_INT) != 0) { + /* not used, use ASIC IRQ instead if needed */ } - if (IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) { + if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) { SkHWLinkDown(pAC, IoC, Port); /* Signal to RLMT */ - Para.Para32[0] = (SK_U32) Port; + Para.Para32[0] = (SK_U32)Port; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer, - SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para); + SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, + SKGE_HWAC, SK_HWEV_WATIM, Para); } - if (IStatus & XM_IS_RX_PAGE) { + if ((IStatus & XM_IS_RX_PAGE) != 0) { /* not used */ } - if (IStatus & XM_IS_TX_PAGE) { + if ((IStatus & XM_IS_TX_PAGE) != 0) { /* not used */ } - if (IStatus & XM_IS_AND) { - SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, - ("SkXmIrq: AND on link that is up port %d\n", Port)); + if ((IStatus & XM_IS_AND) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("SkXmIrq: AND on link that is up Port %d\n", Port)); } - if (IStatus & XM_IS_TSC_OV) { + if ((IStatus & XM_IS_TSC_OV) != 0) { /* not used */ } - if (IStatus & XM_IS_RXC_OV) { - Para.Para32[0] = (SK_U32) Port; - Para.Para32[1] = (SK_U32) IStatus; + /* Combined Tx & Rx Counter Overflow SIRQ Event */ + if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) { + Para.Para32[0] = (SK_U32)Port; + Para.Para32[1] = (SK_U32)IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); } - if (IStatus & XM_IS_TXC_OV) { - Para.Para32[0] = (SK_U32) Port; - Para.Para32[1] = (SK_U32) IStatus; + if ((IStatus & XM_IS_RXF_OV) != 0) { + /* normal situation -> no effect */ + pPrt->PRxOverCnt++; + } + + if ((IStatus & XM_IS_TXF_UR) != 0) { + /* may NOT happen -> error log */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); + } + + if ((IStatus & XM_IS_TX_COMP) != 0) { + /* not served here */ + } + + if ((IStatus & XM_IS_RX_COMP) != 0) { + /* not served here */ + } +} /* SkXmIrq */ + + +/****************************************************************************** + * + * SkGmIrq() - Interrupt Service Routine + * + * Description: services an Interrupt Request of the GMAC + * + * Note: + * + * Returns: + * nothing + */ +void SkGmIrq( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + SK_EVPARA Para; + SK_U8 IStatus; /* Interrupt status */ + + pPrt = &pAC->GIni.GP[Port]; + + SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus); + + /* LinkPartner Auto-negable? */ + SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("GmacIrq Port %d Isr 0x%04x\n", Port, IStatus)); + + /* Combined Tx & Rx Counter Overflow SIRQ Event */ + if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) { + /* these IRQs will be cleared by reading GMACs register */ + Para.Para32[0] = (SK_U32)Port; + Para.Para32[1] = (SK_U32)IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); } - if (IStatus & XM_IS_RXF_OV) { - /* normal situation -> no effect */ + if (IStatus & GM_IS_RX_FF_OR) { + /* clear GMAC Rx FIFO Overrun IRQ */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO); + + pPrt->PRxOverCnt++; } - if (IStatus & XM_IS_TXF_UR) { + if (IStatus & GM_IS_TX_FF_UR) { + /* clear GMAC Tx FIFO Underrun IRQ */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU); /* may NOT happen -> error log */ - SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E020, - SKERR_SIRQ_E020MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); } - if (IStatus & XM_IS_TX_COMP) { + if (IStatus & GM_IS_TX_COMPL) { /* not served here */ } - if (IStatus & XM_IS_RX_COMP) { + if (IStatus & GM_IS_RX_COMPL) { /* not served here */ } +} /* SkGmIrq */ + +/****************************************************************************** + * + * SkMacIrq() - Interrupt Service Routine for MAC + * + * Description: calls the Interrupt Service Routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacIrq( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ -} /* SkXmIrq*/ + if (pAC->GIni.GIGenesis) { + /* IRQ from XMAC */ + SkXmIrq(pAC, IoC, Port); + } + else { + /* IRQ from GMAC */ + SkGmIrq(pAC, IoC, Port); + } +} /* SkMacIrq */ #endif /* !SK_DIAG */ +/****************************************************************************** + * + * SkXmUpdateStats() - Force the XMAC to output the current statistic + * + * Description: + * The XMAC holds its statistic internally. To obtain the current + * values a command must be sent so that the statistic data will + * be written to a predefined memory area on the adapter. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkXmUpdateStats( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port) /* Port Index (MAC_1 + n) */ +{ + SK_GEPORT *pPrt; + SK_U16 StatReg; + int WaitIndex; + + pPrt = &pAC->GIni.GP[Port]; + WaitIndex = 0; + + /* Send an update command to XMAC specified */ + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); + + /* + * It is an auto-clearing register. If the command bits + * went to zero again, the statistics are transferred. + * Normally the command should be executed immediately. + * But just to be sure we execute a loop. + */ + do { + + XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg); + + if (++WaitIndex > 10) { + + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG); + + return(1); + } + } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0); + + return(0); +} /* SkXmUpdateStats */ + +/****************************************************************************** + * + * SkGmUpdateStats() - Force the GMAC to output the current statistic + * + * Description: + * Empty function for GMAC. Statistic data is accessible in direct way. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkGmUpdateStats( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port) /* Port Index (MAC_1 + n) */ +{ + return(0); +} + +/****************************************************************************** + * + * SkXmMacStatistic() - Get XMAC counter value + * + * Description: + * Gets the 32bit counter value. Except for the octet counters + * the lower 32bit are counted in hardware and the upper 32bit + * must be counted in software by monitoring counter overflow interrupts. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkXmMacStatistic( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 StatAddr, /* MIB counter base address */ +SK_U32 *pVal) /* ptr to return statistic value */ +{ + if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); + + return(1); + } + + XM_IN32(IoC, Port, StatAddr, pVal); + + return(0); +} /* SkXmMacStatistic */ + +/****************************************************************************** + * + * SkGmMacStatistic() - Get GMAC counter value + * + * Description: + * Gets the 32bit counter value. Except for the octet counters + * the lower 32bit are counted in hardware and the upper 32bit + * must be counted in software by monitoring counter overflow interrupts. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkGmMacStatistic( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 StatAddr, /* MIB counter base address */ +SK_U32 *pVal) /* ptr to return statistic value */ +{ + + if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); + return(1); + } + + GM_IN32(IoC, Port, StatAddr, pVal); + + return(0); +} /* SkGmMacStatistic */ + +/****************************************************************************** + * + * SkXmResetCounter() - Clear MAC statistic counter + * + * Description: + * Force the XMAC to clear its statistic counter. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkXmResetCounter( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port) /* Port Index (MAC_1 + n) */ +{ + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); + /* Clear two times according to Errata #3 */ + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); + + return(0); +} /* SkXmResetCounter */ + +/****************************************************************************** + * + * SkGmResetCounter() - Clear MAC statistic counter + * + * Description: + * Force GMAC to clear its statistic counter. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkGmResetCounter( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U16 Reg; /* Phy Address Register */ + SK_U16 Word; + int i; + + GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg); + +#ifndef VCPU + /* set MIB Clear Counter Mode */ + GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR); + + /* read all MIB Counters with Clear Mode set */ + for (i = 0; i < GM_MIB_CNT_SIZE; i++) { + /* the reset is performed only when the lower 16 bits are read */ + GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word); + } + + /* clear MIB Clear Counter Mode */ + GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg); +#endif /* !VCPU */ + + return(0); +} /* SkGmResetCounter */ + +/****************************************************************************** + * + * SkXmOverflowStatus() - Gets the status of counter overflow interrupt + * + * Description: + * Checks the source causing an counter overflow interrupt. On success the + * resulting counter overflow status is written to , whereas the + * upper dword stores the XMAC ReceiveCounterEvent register and the lower + * dword the XMAC TransmitCounterEvent register. + * + * Note: + * For XMAC the interrupt source is a self-clearing register, so the source + * must be checked only once. SIRQ module does another check to be sure + * that no interrupt get lost during process time. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkXmOverflowStatus( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 IStatus, /* Interupt Status from MAC */ +SK_U64 *pStatus) /* ptr for return overflow status value */ +{ + SK_U64 Status; /* Overflow status */ + SK_U32 RegVal; + + Status = 0; + + if ((IStatus & XM_IS_RXC_OV) != 0) { + + XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); + Status |= (SK_U64)RegVal << 32; + } + + if ((IStatus & XM_IS_TXC_OV) != 0) { + + XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); + Status |= (SK_U64)RegVal; + } + + *pStatus = Status; + + return(0); +} /* SkXmOverflowStatus */ + + +/****************************************************************************** + * + * SkGmOverflowStatus() - Gets the status of counter overflow interrupt + * + * Description: + * Checks the source causing an counter overflow interrupt. On success the + * resulting counter overflow status is written to , whereas the + * the following bit coding is used: + * 63:56 - unused + * 55:48 - TxRx interrupt register bit7:0 + * 32:47 - Rx interrupt register + * 31:24 - unused + * 23:16 - TxRx interrupt register bit15:8 + * 15:0 - Tx interrupt register + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkGmOverflowStatus( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 IStatus, /* Interupt Status from MAC */ +SK_U64 *pStatus) /* ptr for return overflow status value */ +{ + SK_U64 Status; /* Overflow status */ + SK_U16 RegVal; + + Status = 0; + + if ((IStatus & GM_IS_RX_CO_OV) != 0) { + /* this register is self-clearing after read */ + GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal); + Status |= (SK_U64)RegVal << 32; + } + + if ((IStatus & GM_IS_TX_CO_OV) != 0) { + /* this register is self-clearing after read */ + GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal); + Status |= (SK_U64)RegVal; + } + + /* this register is self-clearing after read */ + GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal); + /* Rx overflow interrupt register bits (LoByte)*/ + Status |= (SK_U64)((SK_U8)RegVal) << 48; + /* Tx overflow interrupt register bits (HiByte)*/ + Status |= (SK_U64)(RegVal >> 8) << 16; + + *pStatus = Status; + + return(0); +} /* SkGmOverflowStatus */ + +/****************************************************************************** + * + * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test + * + * Description: + * starts the cable diagnostic test if 'StartTest' is true + * gets the results if 'StartTest' is true + * + * NOTE: this test is meaningful only when link is down + * + * Returns: + * 0: success + * 1: no YUKON copper + * 2: test in progress + */ +int SkGmCableDiagStatus( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL StartTest) /* flag for start / get result */ +{ + int i; + SK_U16 RegVal; + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PhyType != SK_PHY_MARV_COPPER) { + + return(1); + } + + if (StartTest) { + /* only start the cable test */ + if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) { + /* apply TDR workaround from Marvell */ + SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e); + + SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100); + } + + /* set address to 0 for MDI[0] */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); + + /* Read Cable Diagnostic Reg */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); + + /* start Cable Diagnostic Test */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, + RegVal | PHY_M_CABD_ENA_TEST); + + return(0); + } + + /* Read Cable Diagnostic Reg */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("PHY Cable Diag.=0x%04X\n", RegVal)); + + if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) { + /* test is running */ + return(2); + } + + /* get the test results */ + for (i = 0; i < 4; i++) { + /* set address to i for MDI[i] */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); + + /* get Cable Diagnostic values */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); + + pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK); + + pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13); + } + + return(0); +} /* SkGmCableDiagStatus */ + /* End of file */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/smc9194.c linux.21pre4-ac6/drivers/net/smc9194.c --- linux.21pre4/drivers/net/smc9194.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/smc9194.c 2003-01-28 16:19:58.000000000 +0000 @@ -483,10 +483,20 @@ printk(CARDNAME": Bad Craziness - sent packet while busy.\n" ); return 1; } - lp->saved_skb = skb; - length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + length = skb->len; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + netif_wake_queue(dev); + return 0; + } + length = ETH_ZLEN; + } + lp->saved_skb = skb; /* ** The MMU wants the number of pages to be the number of 256 bytes diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/starfire.c linux.21pre4-ac6/drivers/net/starfire.c --- linux.21pre4/drivers/net/starfire.c 2003-01-29 17:07:45.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/starfire.c 2003-02-04 15:02:26.000000000 +0000 @@ -101,15 +101,33 @@ - Better stats and error handling (Ion Badulescu) - Use new pci_set_mwi() PCI API function (jgarzik) -TODO: - - implement tx_timeout() properly + LK1.3.7 (Ion Badulescu) + - minimal implementation of tx_timeout() + - correctly shutdown the Rx/Tx engines in netdev_close() + - added calls to netif_carrier_on/off + (patch from Stefan Rompf ) - VLAN support + + LK1.3.8 (Ion Badulescu) + - adjust DMA burst size on sparc64 + - 64-bit support + - reworked zerocopy support for 64-bit buffers + - working and usable interrupt mitigation/latency + - reduced Tx interrupt frequency for lower interrupt overhead + + LK1.3.9 (Ion Badulescu) + - bugfix for mcast filter + - enable the right kind of Tx interrupts (TxDMADone, not TxDone) + +TODO: + - full NAPI support */ #define DRV_NAME "starfire" -#define DRV_VERSION "1.03+LK1.3.6" -#define DRV_RELDATE "March 7, 2002" +#define DRV_VERSION "1.03+LK1.3.9" +#define DRV_RELDATE "December 13, 2002" +#include #include #include #include @@ -118,7 +136,6 @@ #include #include #include -#include #include /* Processor type for cache alignment. */ #include #include @@ -154,11 +171,16 @@ #include "starfire_firmware.h" #endif /* HAS_FIRMWARE */ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#define VLAN_SUPPORT +#endif + /* The user-configurable values. These may be modified when a driver module is loaded.*/ /* Used for tuning interrupt latency vs. overhead. */ -static int interrupt_mitigation; +static int intr_latency; +static int small_frames; static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ static int max_interrupt_work = 20; @@ -166,6 +188,12 @@ /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). The Starfire has a 512 element hash table based on the Ethernet CRC. */ static int multicast_filter_limit = 512; +/* Whether to do TCP/UDP checksums in hardware */ +#ifdef HAS_FIRMWARE +static int enable_hw_cksum = 1; +#else +static int enable_hw_cksum = 0; +#endif #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ /* @@ -178,7 +206,9 @@ * packets as the starfire doesn't allow for misaligned DMAs ;-( * 23/10/2000 - Jes * - * The Alpha and the Sparc don't allow unaligned loads, either. -Ion + * The Alpha and the Sparc don't like unaligned loads, either. On Sparc64, + * at least, having unaligned frames leads to a rather serious performance + * penalty. -Ion */ #if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) static int rx_copybreak = PKT_BUF_SZ; @@ -186,9 +216,17 @@ static int rx_copybreak /* = 0 */; #endif +/* PCI DMA burst size -- on sparc64 we want to force it to 64 bytes, on the others the default of 128 is fine. */ +#ifdef __sparc__ +#define DMA_BURST_SIZE 64 +#else +#define DMA_BURST_SIZE 128 +#endif + /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' exist for driver interoperability. The media type is usually passed in 'options[]'. + These variables are deprecated, use ethtool instead. -Ion */ #define MAX_UNITS 8 /* More are supported, limit only on options */ static int options[MAX_UNITS] = {0, }; @@ -198,33 +236,55 @@ /* The "native" ring sizes are either 256 or 2048. However in some modes a descriptor may be marked to wrap the ring earlier. - The driver allocates a single page for each descriptor ring, constraining - the maximum size in an architecture-dependent way. */ #define RX_RING_SIZE 256 #define TX_RING_SIZE 32 /* The completion queues are fixed at 1024 entries i.e. 4K or 8KB. */ #define DONE_Q_SIZE 1024 +/* All queues must be aligned on a 256-byte boundary */ +#define QUEUE_ALIGN 256 + +#if RX_RING_SIZE > 256 +#define RX_Q_ENTRIES Rx2048QEntries +#else +#define RX_Q_ENTRIES Rx256QEntries +#endif /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (2 * HZ) -#ifdef ZEROCOPY -#if MAX_SKB_FRAGS <= 6 -#define MAX_STARFIRE_FRAGS 6 -#else /* MAX_STARFIRE_FRAGS > 6 */ -#warning This driver will not work with more than 6 skb fragments. -#warning Turning off zerocopy support. -#undef ZEROCOPY -#endif /* MAX_STARFIRE_FRAGS > 6 */ -#endif /* ZEROCOPY */ +/* + * This SUCKS. + * We need a much better method to determine if dma_addr_t is 64-bit. + */ +#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) +/* 64-bit dma_addr_t */ +#define ADDR_64BITS /* This chip uses 64 bit addresses. */ +#define cpu_to_dma(x) cpu_to_le64(x) +#define dma_to_cpu(x) le64_to_cpu(x) +#define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit +#define TX_DESC_Q_ADDR_SIZE TxDescQAddr64bit +#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr64bit +#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit +#define RX_DESC_ADDR_SIZE RxDescAddr64bit +#else /* 32-bit dma_addr_t */ +#define cpu_to_dma(x) cpu_to_le32(x) +#define dma_to_cpu(x) le32_to_cpu(x) +#define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit +#define TX_DESC_Q_ADDR_SIZE TxDescQAddr32bit +#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr32bit +#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr32bit +#define RX_DESC_ADDR_SIZE RxDescAddr32bit +#endif -#ifdef ZEROCOPY +#ifdef MAX_SKB_FRAGS #define skb_first_frag_len(skb) skb_headlen(skb) -#else /* not ZEROCOPY */ +#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1) +#else /* not MAX_SKB_FRAGS */ #define skb_first_frag_len(skb) (skb->len) -#endif /* not ZEROCOPY */ +#define skb_num_frags(skb) 1 +#endif /* not MAX_SKB_FRAGS */ /* 2.2.x compatibility code */ #if LINUX_VERSION_CODE < 0x20300 @@ -233,9 +293,12 @@ #else /* LINUX_VERSION_CODE > 0x20300 */ +#include #include #include +#include + #define COMPAT_MOD_INC_USE_COUNT #define COMPAT_MOD_DEC_USE_COUNT @@ -266,15 +329,20 @@ MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(interrupt_mitigation, "i"); +MODULE_PARM(intr_latency, "i"); +MODULE_PARM(small_frames, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM_DESC(max_interrupt_work, "Starfire maximum events handled per interrupt"); -MODULE_PARM_DESC(mtu, "Starfire MTU (all boards)"); -MODULE_PARM_DESC(debug, "Starfire debug level (0-6)"); -MODULE_PARM_DESC(rx_copybreak, "Starfire copy breakpoint for copy-only-tiny-frames"); -MODULE_PARM_DESC(options, "Starfire: Bits 0-3: media type, bit 17: full duplex"); -MODULE_PARM_DESC(full_duplex, "Starfire full duplex setting(s) (1)"); +MODULE_PARM(enable_hw_cksum, "i"); +MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt"); +MODULE_PARM_DESC(mtu, "MTU (all boards)"); +MODULE_PARM_DESC(debug, "Debug level (0-6)"); +MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); +MODULE_PARM_DESC(intr_latency, "Maximum interrupt latency, in microseconds"); +MODULE_PARM_DESC(small_frames, "Maximum size of receive frames that bypass interrupt latency (0,64,128,256,512)"); +MODULE_PARM_DESC(options, "Deprecated: Bits 0-3: media type, bit 17: full duplex"); +MODULE_PARM_DESC(full_duplex, "Deprecated: Forced full-duplex setting (0/1)"); +MODULE_PARM_DESC(enable_hw_cksum, "Enable/disable hardware cksum support (0/1)"); /* Theory of Operation @@ -303,14 +371,14 @@ IIIb/c. Transmit/Receive Structure See the Adaptec manual for the many possible structures, and options for -each structure. There are far too many to document here. +each structure. There are far too many to document all of them here. For transmit this driver uses type 0/1 transmit descriptors (depending -on the presence of the zerocopy infrastructure), and relies on automatic +on the 32/64 bitness of the architecture), and relies on automatic minimum-length padding. It does not use the completion queue consumer index, but instead checks for non-zero status entries. -For receive this driver uses type 0 receive descriptors. The driver +For receive this driver uses type 0/1/2/3 receive descriptors. The driver allocates full frame size skbuffs for the Rx ring buffers, so all frames should fit in a single descriptor. The driver does not use the completion queue consumer index, but instead checks for non-zero status entries. @@ -335,15 +403,15 @@ dev->tbusy flag. The other thread is the interrupt handler, which is single threaded by the hardware and interrupt handling software. -The send packet thread has partial control over the Tx ring and 'dev->tbusy' -flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next -queue slot is empty, it clears the tbusy flag when finished otherwise it sets -the 'lp->tx_full' flag. +The send packet thread has partial control over the Tx ring and the netif_queue +status. If the number of free Tx slots in the ring falls below a certain number +(currently hardcoded to 4), it signals the upper layer to stop the queue. The interrupt handler has exclusive control over the Rx ring and records stats from the Tx ring. After reaping the stats, it marks the Tx queue entry as -empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it -clears both the tx_full and tbusy flags. +empty by incrementing the dirty_tx mark. Iff the netif_queue is stopped and the +number of free Tx slow is above the threshold, it signals the upper layer to +restart the queue. IV. Notes @@ -355,18 +423,15 @@ IVc. Errata +- StopOnPerr is broken, don't enable +- Hardware ethernet padding exposes random data, perform software padding + instead (unverified -- works correctly for all the hardware I have) + */ enum chip_capability_flags {CanHaveMII=1, }; -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR0) - -#if 0 -#define ADDR_64BITS 1 /* This chip uses 64 bit addresses. */ -#endif - -#define HAS_IP_COPYSUM 1 enum chipset { CH_6915 = 0, @@ -398,7 +463,7 @@ enum register_offsets { PCIDeviceConfig=0x50040, GenCtrl=0x50070, IntrTimerCtrl=0x50074, IntrClear=0x50080, IntrStatus=0x50084, IntrEnable=0x50088, - MIICtrl=0x52000, StationAddr=0x50120, EEPROMCtrl=0x51000, + MIICtrl=0x52000, TxStationAddr=0x50120, EEPROMCtrl=0x51000, GPIOCtrl=0x5008C, TxDescCtrl=0x50090, TxRingPtr=0x50098, HiPriTxRingPtr=0x50094, /* Low and High priority. */ TxRingHiAddr=0x5009C, /* 64 bit address extension. */ @@ -409,11 +474,16 @@ CompletionQConsumerIdx=0x500C4, RxDMACtrl=0x500D0, RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0, RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4, - TxMode=0x55000, PerfFilterTable=0x56000, HashTable=0x56100, + TxMode=0x55000, VlanType=0x55064, + PerfFilterTable=0x56000, HashTable=0x56100, TxGfpMem=0x58000, RxGfpMem=0x5a000, }; -/* Bits in the interrupt status/mask registers. */ +/* + * Bits in the interrupt status/mask registers. + * Warning: setting Intr[Ab]NormalSummary in the IntrEnable register + * enables all the interrupt sources that are or'ed into those status bits. + */ enum intr_status_bits { IntrLinkChange=0xf0000000, IntrStatsMax=0x08000000, IntrAbnormalSummary=0x02000000, IntrGeneralTimer=0x01000000, @@ -438,7 +508,16 @@ /* Bits in the RxFilterMode register. */ enum rx_mode_bits { AcceptBroadcast=0x04, AcceptAllMulticast=0x02, AcceptAll=0x01, - AcceptMulticast=0x10, AcceptMyPhys=0xE040, + AcceptMulticast=0x10, PerfectFilter=0x40, HashFilter=0x30, + PerfectFilterVlan=0x80, MinVLANPrio=0xE000, VlanMode=0x0200, + WakeupOnGFP=0x0800, +}; + +/* Bits in the TxMode register */ +enum tx_mode_bits { + MiiSoftReset=0x8000, MIILoopback=0x4000, + TxFlowEnable=0x0800, RxFlowEnable=0x0400, + PadEnable=0x04, FullDuplex=0x02, HugeFrame=0x01, }; /* Bits in the TxDescCtrl register. */ @@ -447,7 +526,8 @@ TxDescSpace128=0x30, TxDescSpace256=0x40, TxDescType0=0x00, TxDescType1=0x01, TxDescType2=0x02, TxDescType3=0x03, TxDescType4=0x04, - TxNoDMACompletion=0x08, TxDescQ64bit=0x80, + TxNoDMACompletion=0x08, + TxDescQAddr64bit=0x80, TxDescQAddr32bit=0, TxHiPriFIFOThreshShift=24, TxPadLenShift=16, TxDMABurstSizeShift=8, }; @@ -455,81 +535,144 @@ /* Bits in the RxDescQCtrl register. */ enum rx_ctrl_bits { RxBufferLenShift=16, RxMinDescrThreshShift=0, - RxPrefetchMode=0x8000, Rx2048QEntries=0x4000, - RxVariableQ=0x2000, RxDesc64bit=0x1000, - RxDescQAddr64bit=0x0100, + RxPrefetchMode=0x8000, RxVariableQ=0x2000, + Rx2048QEntries=0x4000, Rx256QEntries=0, + RxDescAddr64bit=0x1000, RxDescAddr32bit=0, + RxDescQAddr64bit=0x0100, RxDescQAddr32bit=0, RxDescSpace4=0x000, RxDescSpace8=0x100, RxDescSpace16=0x200, RxDescSpace32=0x300, RxDescSpace64=0x400, RxDescSpace128=0x500, RxConsumerWrEn=0x80, }; +/* Bits in the RxDMACtrl register. */ +enum rx_dmactrl_bits { + RxReportBadFrames=0x80000000, RxDMAShortFrames=0x40000000, + RxDMABadFrames=0x20000000, RxDMACrcErrorFrames=0x10000000, + RxDMAControlFrame=0x08000000, RxDMAPauseFrame=0x04000000, + RxChecksumIgnore=0, RxChecksumRejectTCPUDP=0x02000000, + RxChecksumRejectTCPOnly=0x01000000, + RxCompletionQ2Enable=0x800000, + RxDMAQ2Disable=0, RxDMAQ2FPOnly=0x100000, + RxDMAQ2SmallPkt=0x200000, RxDMAQ2HighPrio=0x300000, + RxDMAQ2NonIP=0x400000, + RxUseBackupQueue=0x080000, RxDMACRC=0x040000, + RxEarlyIntThreshShift=12, RxHighPrioThreshShift=8, + RxBurstSizeShift=0, +}; + /* Bits in the RxCompletionAddr register */ enum rx_compl_bits { - RxComplQAddr64bit=0x80, TxComplProducerWrEn=0x40, + RxComplQAddr64bit=0x80, RxComplQAddr32bit=0, + RxComplProducerWrEn=0x40, RxComplType0=0x00, RxComplType1=0x10, RxComplType2=0x20, RxComplType3=0x30, RxComplThreshShift=0, }; +/* Bits in the TxCompletionAddr register */ +enum tx_compl_bits { + TxComplQAddr64bit=0x80, TxComplQAddr32bit=0, + TxComplProducerWrEn=0x40, + TxComplIntrStatus=0x20, + CommonQueueMode=0x10, + TxComplThreshShift=0, +}; + +/* Bits in the GenCtrl register */ +enum gen_ctrl_bits { + RxEnable=0x05, TxEnable=0x0a, + RxGFPEnable=0x10, TxGFPEnable=0x20, +}; + +/* Bits in the IntrTimerCtrl register */ +enum intr_ctrl_bits { + Timer10X=0x800, EnableIntrMasking=0x60, SmallFrameBypass=0x100, + SmallFrame64=0, SmallFrame128=0x200, SmallFrame256=0x400, SmallFrame512=0x600, + IntrLatencyMask=0x1f, +}; + /* The Rx and Tx buffer descriptors. */ struct starfire_rx_desc { - u32 rxaddr; /* Optionally 64 bits. */ + dma_addr_t rxaddr; }; enum rx_desc_bits { RxDescValid=1, RxDescEndRing=2, }; -/* Completion queue entry. - You must update the page allocation, init_ring and the shift count in rx() - if using a larger format. */ -#ifdef HAS_FIRMWARE -#define csum_rx_status -#endif /* HAS_FIRMWARE */ -struct rx_done_desc { +/* Completion queue entry. */ +struct short_rx_done_desc { + u32 status; /* Low 16 bits is length. */ +}; +struct basic_rx_done_desc { u32 status; /* Low 16 bits is length. */ -#ifdef csum_rx_status - u32 status2; /* Low 16 bits is csum */ -#endif /* csum_rx_status */ -#ifdef full_rx_status - u32 status2; + u16 vlanid; + u16 status2; +}; +struct csum_rx_done_desc { + u32 status; /* Low 16 bits is length. */ + u16 csum; /* Partial checksum */ + u16 status2; +}; +struct full_rx_done_desc { + u32 status; /* Low 16 bits is length. */ + u16 status3; + u16 status2; u16 vlanid; u16 csum; /* partial checksum */ u32 timestamp; -#endif /* full_rx_status */ }; +/* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */ +#ifdef HAS_FIRMWARE +#ifdef VLAN_SUPPORT +typedef struct full_rx_done_desc rx_done_desc; +#define RxComplType RxComplType3 +#else /* not VLAN_SUPPORT */ +typedef struct csum_rx_done_desc rx_done_desc; +#define RxComplType RxComplType2 +#endif /* not VLAN_SUPPORT */ +#else /* not HAS_FIRMWARE */ +#ifdef VLAN_SUPPORT +typedef struct basic_rx_done_desc rx_done_desc; +#define RxComplType RxComplType1 +#else /* not VLAN_SUPPORT */ +typedef struct short_rx_done_desc rx_done_desc; +#define RxComplType RxComplType0 +#endif /* not VLAN_SUPPORT */ +#endif /* not HAS_FIRMWARE */ + enum rx_done_bits { RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000, }; -#ifdef ZEROCOPY -/* Type 0 Tx descriptor. */ -/* If more fragments are needed, don't forget to change the - descriptor spacing as well! */ -struct starfire_tx_desc { - u32 status; - u32 nbufs; - u32 first_addr; - u16 first_len; - u16 total_len; - struct { - u32 addr; - u32 len; - } frag[MAX_STARFIRE_FRAGS]; -}; -#else /* not ZEROCOPY */ /* Type 1 Tx descriptor. */ -struct starfire_tx_desc { +struct starfire_tx_desc_1 { + u32 status; /* Upper bits are status, lower 16 length. */ + u32 addr; +}; + +/* Type 2 Tx descriptor. */ +struct starfire_tx_desc_2 { u32 status; /* Upper bits are status, lower 16 length. */ - u32 first_addr; + u32 reserved; + u64 addr; }; -#endif /* not ZEROCOPY */ + +#ifdef ADDR_64BITS +typedef struct starfire_tx_desc_2 starfire_tx_desc; +#define TX_DESC_TYPE TxDescType2 +#else /* not ADDR_64BITS */ +typedef struct starfire_tx_desc_1 starfire_tx_desc; +#define TX_DESC_TYPE TxDescType1 +#endif /* not ADDR_64BITS */ +#define TX_DESC_SPACING TxDescSpaceUnlim + enum tx_desc_bits { TxDescID=0xB0000000, TxCRCEn=0x01000000, TxDescIntr=0x08000000, TxRingWrap=0x04000000, TxCalTCP=0x02000000, }; -struct tx_done_report { +struct tx_done_desc { u32 status; /* timestamp, index. */ #if 0 u32 intrstatus; /* interrupt status */ @@ -542,41 +685,45 @@ }; struct tx_ring_info { struct sk_buff *skb; - dma_addr_t first_mapping; -#ifdef ZEROCOPY - dma_addr_t frag_mapping[MAX_STARFIRE_FRAGS]; -#endif /* ZEROCOPY */ + dma_addr_t mapping; + unsigned int used_slots; }; #define PHY_CNT 2 struct netdev_private { /* Descriptor rings first for alignment. */ struct starfire_rx_desc *rx_ring; - struct starfire_tx_desc *tx_ring; + starfire_tx_desc *tx_ring; dma_addr_t rx_ring_dma; dma_addr_t tx_ring_dma; /* The addresses of rx/tx-in-place skbuffs. */ struct rx_ring_info rx_info[RX_RING_SIZE]; struct tx_ring_info tx_info[TX_RING_SIZE]; /* Pointers to completion queues (full pages). */ - struct rx_done_desc *rx_done_q; + rx_done_desc *rx_done_q; dma_addr_t rx_done_q_dma; unsigned int rx_done; - struct tx_done_report *tx_done_q; + struct tx_done_desc *tx_done_q; dma_addr_t tx_done_q_dma; unsigned int tx_done; struct net_device_stats stats; struct pci_dev *pci_dev; +#ifdef VLAN_SUPPORT + struct vlan_group *vlgrp; +#endif + void *queue_mem; + dma_addr_t queue_mem_dma; + size_t queue_mem_size; + /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ - unsigned int cur_tx, dirty_tx; + unsigned int cur_tx, dirty_tx, reap_tx; unsigned int rx_buf_sz; /* Based on MTU+slack. */ - unsigned int tx_full:1, /* The Tx queue is full. */ /* These values keep track of the transceiver/media in use. */ - speed100:1; /* Set if speed == 100MBit. */ - unsigned int intr_mitigation; + int speed100; /* Set if speed == 100MBit. */ u32 tx_mode; + u32 intr_timer_ctrl; u8 tx_threshold; /* MII transceiver section. */ struct mii_if_info mii_if; /* MII lib hooks/info */ @@ -603,6 +750,44 @@ static void netdev_media_change(struct net_device *dev); +#ifdef VLAN_SUPPORT +static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +{ + struct netdev_private *np = dev->priv; + + spin_lock(&np->lock); + if (debug > 2) + printk("%s: Setting vlgrp to %p\n", dev->name, grp); + np->vlgrp = grp; + set_rx_mode(dev); + spin_unlock(&np->lock); +} + +static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) +{ + struct netdev_private *np = dev->priv; + + spin_lock(&np->lock); + if (debug > 1) + printk("%s: Adding vlanid %d to vlan filter\n", dev->name, vid); + set_rx_mode(dev); + spin_unlock(&np->lock); +} + +static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + struct netdev_private *np = dev->priv; + + spin_lock(&np->lock); + if (debug > 1) + printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid); + if (np->vlgrp) + np->vlgrp->vlan_devices[vid] = NULL; + set_rx_mode(dev); + spin_unlock(&np->lock); +} +#endif /* VLAN_SUPPORT */ + static int __devinit starfire_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -614,10 +799,6 @@ long ioaddr; int drv_flags, io_size; int boguscnt; -#ifndef HAVE_PCI_SET_MWI - u16 cmd; - u8 cache; -#endif /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -634,13 +815,13 @@ ioaddr = pci_resource_start(pdev, 0); io_size = pci_resource_len(pdev, 0); if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_MEM) == 0)) { - printk (KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx); + printk(KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx); return -ENODEV; } dev = alloc_etherdev(sizeof(*np)); if (!dev) { - printk (KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); + printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); return -ENOMEM; } SET_MODULE_OWNER(dev); @@ -648,7 +829,7 @@ irq = pdev->irq; if (pci_request_regions (pdev, dev->name)) { - printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx); + printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx); goto err_out_free_netdev; } @@ -656,7 +837,7 @@ #if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300 ioaddr = (long) ioremap(ioaddr, io_size); if (!ioaddr) { - printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n", + printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n", card_idx, io_size, ioaddr); goto err_out_free_res; } @@ -664,29 +845,26 @@ pci_set_master(pdev); -#ifdef HAVE_PCI_SET_MWI - pci_set_mwi(pdev); -#else /* enable MWI -- it vastly improves Rx performance on sparc64 */ - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_INVALIDATE; - pci_write_config_word(pdev, PCI_COMMAND, cmd); - - /* set PCI cache size */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache); - if ((cache << 2) != SMP_CACHE_BYTES) { - printk(KERN_INFO " PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, correcting to %i\n", - (cache << 2), SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } -#endif + pci_set_mwi(pdev); +#ifdef MAX_SKB_FRAGS + dev->features |= NETIF_F_SG; +#endif /* MAX_SKB_FRAGS */ #ifdef ZEROCOPY - /* Starfire can do SG and TCP/UDP checksumming */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + /* Starfire can do TCP/UDP checksumming */ + if (enable_hw_cksum) + dev->features |= NETIF_F_IP_CSUM; #endif /* ZEROCOPY */ +#ifdef VLAN_SUPPORT + dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; + dev->vlan_rx_register = netdev_vlan_rx_register; + dev->vlan_rx_add_vid = netdev_vlan_rx_add_vid; + dev->vlan_rx_kill_vid = netdev_vlan_rx_kill_vid; +#endif /* VLAN_RX_KILL_VID */ +#ifdef ADDR_64BITS + dev->features |= NETIF_F_HIGHDMA; +#endif /* ADDR_64BITS */ /* Serial EEPROM reads are hidden by the hardware. */ for (i = 0; i < 6; i++) @@ -701,7 +879,7 @@ #endif /* Issue soft reset */ - writel(0x8000, ioaddr + TxMode); + writel(MiiSoftReset, ioaddr + TxMode); udelay(1000); writel(0, ioaddr + TxMode); @@ -747,11 +925,35 @@ np->mii_if.full_duplex = 1; if (np->mii_if.full_duplex) - np->mii_if.force_media = 0; - else np->mii_if.force_media = 1; + else + np->mii_if.force_media = 0; np->speed100 = 1; + /* timer resolution is 128 * 0.8us */ + np->intr_timer_ctrl = (((intr_latency * 10) / 1024) & IntrLatencyMask) | + Timer10X | EnableIntrMasking; + + if (small_frames > 0) { + np->intr_timer_ctrl |= SmallFrameBypass; + switch (small_frames) { + case 1 ... 64: + np->intr_timer_ctrl |= SmallFrame64; + break; + case 65 ... 128: + np->intr_timer_ctrl |= SmallFrame128; + break; + case 129 ... 256: + np->intr_timer_ctrl |= SmallFrame256; + break; + default: + np->intr_timer_ctrl |= SmallFrame512; + if (small_frames > 512) + printk("Adjusting small_frames down to 512\n"); + break; + } + } + /* The chip-specific entries in the device structure. */ dev->open = &netdev_open; dev->hard_start_xmit = &start_tx; @@ -764,11 +966,10 @@ if (mtu) dev->mtu = mtu; - i = register_netdev(dev); - if (i) + if (register_netdev(dev)) goto err_out_cleardev; - printk(KERN_INFO "%s: %s at 0x%lx, ", + printk(KERN_INFO "%s: %s at %#lx, ", dev->name, netdrv_tbl[chip_idx].name, ioaddr); for (i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); @@ -793,7 +994,7 @@ np->phys[phy_idx++] = phy; np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE); printk(KERN_INFO "%s: MII PHY found at address %d, status " - "0x%4.4x advertising %4.4x.\n", + "%#4.4x advertising %#4.4x.\n", dev->name, phy, mii_status, np->mii_if.advertising); /* there can be only one PHY on-board */ break; @@ -806,14 +1007,8 @@ memset(&np->mii_if, 0, sizeof(np->mii_if)); } -#ifdef ZEROCOPY - printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n", - dev->name); -#else /* not ZEROCOPY */ - printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n", - dev->name); -#endif /* not ZEROCOPY */ - + printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming %s.\n", + dev->name, enable_hw_cksum ? "enabled" : "disabled"); return 0; err_out_cleardev: @@ -822,7 +1017,6 @@ err_out_free_res: pci_release_regions (pdev); err_out_free_netdev: - unregister_netdev(dev); kfree(dev); return -ENODEV; } @@ -858,6 +1052,7 @@ struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; int i, retval; + size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size; /* Do we ever need to reset the chip??? */ @@ -875,62 +1070,61 @@ if (debug > 1) printk(KERN_DEBUG "%s: netdev_open() irq %d.\n", dev->name, dev->irq); - /* Allocate the various queues, failing gracefully. */ - if (np->tx_done_q == 0) - np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma); - if (np->rx_done_q == 0) - np->rx_done_q = pci_alloc_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, &np->rx_done_q_dma); - if (np->tx_ring == 0) - np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma); - if (np->rx_ring == 0) - np->rx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_ring_dma); - if (np->tx_done_q == 0 || np->rx_done_q == 0 - || np->rx_ring == 0 || np->tx_ring == 0) { - if (np->tx_done_q) - pci_free_consistent(np->pci_dev, PAGE_SIZE, - np->tx_done_q, np->tx_done_q_dma); - if (np->rx_done_q) - pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, - np->rx_done_q, np->rx_done_q_dma); - if (np->tx_ring) - pci_free_consistent(np->pci_dev, PAGE_SIZE, - np->tx_ring, np->tx_ring_dma); - if (np->rx_ring) - pci_free_consistent(np->pci_dev, PAGE_SIZE, - np->rx_ring, np->rx_ring_dma); - COMPAT_MOD_DEC_USE_COUNT; - return -ENOMEM; + + /* Allocate the various queues. */ + if (np->queue_mem == 0) { + tx_done_q_size = ((sizeof(struct tx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN; + rx_done_q_size = ((sizeof(rx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN; + tx_ring_size = ((sizeof(starfire_tx_desc) * TX_RING_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN; + rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE; + np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size; + np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma); + if (np->queue_mem == 0) { + COMPAT_MOD_DEC_USE_COUNT; + return -ENOMEM; + } + + np->tx_done_q = np->queue_mem; + np->tx_done_q_dma = np->queue_mem_dma; + np->rx_done_q = (void *) np->tx_done_q + tx_done_q_size; + np->rx_done_q_dma = np->tx_done_q_dma + tx_done_q_size; + np->tx_ring = (void *) np->rx_done_q + rx_done_q_size; + np->tx_ring_dma = np->rx_done_q_dma + rx_done_q_size; + np->rx_ring = (void *) np->tx_ring + tx_ring_size; + np->rx_ring_dma = np->tx_ring_dma + tx_ring_size; } + /* Start with no carrier, it gets adjusted later */ netif_carrier_off(dev); init_ring(dev); /* Set the size of the Rx buffers. */ writel((np->rx_buf_sz << RxBufferLenShift) | (0 << RxMinDescrThreshShift) | RxPrefetchMode | RxVariableQ | + RX_Q_ENTRIES | + RX_DESC_Q_ADDR_SIZE | RX_DESC_ADDR_SIZE | RxDescSpace4, ioaddr + RxDescQCtrl); -#ifdef ZEROCOPY - /* Set Tx descriptor to type 0 and spacing to 64 bytes. */ - writel((2 << TxHiPriFIFOThreshShift) | - (0 << TxPadLenShift) | - (4 << TxDMABurstSizeShift) | - TxDescSpace64 | TxDescType0, - ioaddr + TxDescCtrl); -#else /* not ZEROCOPY */ - /* Set Tx descriptor to type 1 and padding to 0 bytes. */ + /* Set up the Rx DMA controller. */ + writel(RxChecksumIgnore | + (0 << RxEarlyIntThreshShift) | + (6 << RxHighPrioThreshShift) | + ((DMA_BURST_SIZE / 32) << RxBurstSizeShift), + ioaddr + RxDMACtrl); + + /* Set Tx descriptor */ writel((2 << TxHiPriFIFOThreshShift) | (0 << TxPadLenShift) | - (4 << TxDMABurstSizeShift) | - TxDescSpaceUnlim | TxDescType1, + ((DMA_BURST_SIZE / 32) << TxDMABurstSizeShift) | + TX_DESC_Q_ADDR_SIZE | + TX_DESC_SPACING | TX_DESC_TYPE, ioaddr + TxDescCtrl); -#endif /* not ZEROCOPY */ -#if defined(ADDR_64BITS) && defined(__alpha__) - /* XXX We really need a 64-bit PCI dma interfaces too... -DaveM */ - writel(np->rx_ring_dma >> 32, ioaddr + RxDescQHiAddr); - writel(np->tx_ring_dma >> 32, ioaddr + TxRingHiAddr); +#if defined(ADDR_64BITS) + writel(np->queue_mem_dma >> 32, ioaddr + RxDescQHiAddr); + writel(np->queue_mem_dma >> 32, ioaddr + TxRingHiAddr); + writel(np->queue_mem_dma >> 32, ioaddr + CompletionHiAddr); #else writel(0, ioaddr + RxDescQHiAddr); writel(0, ioaddr + TxRingHiAddr); @@ -940,32 +1134,23 @@ writel(np->tx_ring_dma, ioaddr + TxRingPtr); writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr); -#ifdef full_rx_status writel(np->rx_done_q_dma | - RxComplType3 | + RxComplType | (0 << RxComplThreshShift), ioaddr + RxCompletionAddr); -#else /* not full_rx_status */ -#ifdef csum_rx_status - writel(np->rx_done_q_dma | - RxComplType2 | - (0 << RxComplThreshShift), - ioaddr + RxCompletionAddr); -#else /* not csum_rx_status */ - writel(np->rx_done_q_dma | - RxComplType0 | - (0 << RxComplThreshShift), - ioaddr + RxCompletionAddr); -#endif /* not csum_rx_status */ -#endif /* not full_rx_status */ if (debug > 1) printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name); - /* Fill both the unused Tx SA register and the Rx perfect filter. */ + /* Fill both the Tx SA register and the Rx perfect filter. */ for (i = 0; i < 6; i++) - writeb(dev->dev_addr[i], ioaddr + StationAddr + 5 - i); - for (i = 0; i < 16; i++) { + writeb(dev->dev_addr[i], ioaddr + TxStationAddr + 5 - i); + /* The first entry is special because it bypasses the VLAN filter. + Don't use it. */ + writew(0, ioaddr + PerfFilterTable); + writew(0, ioaddr + PerfFilterTable + 4); + writew(0, ioaddr + PerfFilterTable + 8); + for (i = 1; i < 16; i++) { u16 *eaddrs = (u16 *)dev->dev_addr; long setup_frm = ioaddr + PerfFilterTable + i * 16; writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4; @@ -975,16 +1160,14 @@ /* Initialize other registers. */ /* Configure the PCI bus bursts and FIFO thresholds. */ - np->tx_mode = 0x0C04; /* modified when link is up. */ - writel(0x8000 | np->tx_mode, ioaddr + TxMode); + np->tx_mode = TxFlowEnable|RxFlowEnable|PadEnable; /* modified when link is up. */ + writel(MiiSoftReset | np->tx_mode, ioaddr + TxMode); udelay(1000); writel(np->tx_mode, ioaddr + TxMode); np->tx_threshold = 4; writel(np->tx_threshold, ioaddr + TxThreshold); - interrupt_mitigation &= 0x1f; - np->intr_mitigation = interrupt_mitigation; - writel(np->intr_mitigation, ioaddr + IntrTimerCtrl); + writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl); netif_start_if(dev); netif_start_queue(dev); @@ -999,29 +1182,35 @@ /* Enable GPIO interrupts on link change */ writel(0x0f00ff00, ioaddr + GPIOCtrl); - /* Set the interrupt mask and enable PCI interrupts. */ + /* Set the interrupt mask */ writel(IntrRxDone | IntrRxEmpty | IntrDMAErr | - IntrTxDone | IntrStatsMax | IntrLinkChange | - IntrNormalSummary | IntrAbnormalSummary | + IntrTxDMADone | IntrStatsMax | IntrLinkChange | IntrRxGFPDead | IntrNoTxCsum | IntrTxBadID, ioaddr + IntrEnable); + /* Enable PCI interrupts. */ writel(0x00800000 | readl(ioaddr + PCIDeviceConfig), ioaddr + PCIDeviceConfig); +#ifdef VLAN_SUPPORT + /* Set VLAN type to 802.1q */ + writel(ETH_P_8021Q, ioaddr + VlanType); +#endif /* VLAN_SUPPORT */ + #ifdef HAS_FIRMWARE /* Load Rx/Tx firmware into the frame processors */ for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++) writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4); for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++) writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4); - /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ - writel(0x003F, ioaddr + GenCtrl); -#else /* not HAS_FIRMWARE */ - /* Enable the Rx and Tx units only. */ - writel(0x000F, ioaddr + GenCtrl); -#endif /* not HAS_FIRMWARE */ +#endif /* HAS_FIRMWARE */ + if (enable_hw_cksum) + /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ + writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl); + else + /* Enable the Rx and Tx units only. */ + writel(TxEnable|RxEnable, ioaddr + GenCtrl); - if (debug > 2) + if (debug > 1) printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name); @@ -1033,11 +1222,17 @@ { struct netdev_private *np = dev->priv; u16 reg0; + int silly_count = 1000; mdio_write(dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising); mdio_write(dev, np->phys[0], MII_BMCR, BMCR_RESET); udelay(500); - while (mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET); + while (--silly_count && mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET) + /* do nothing */; + if (!silly_count) { + printk("%s: MII reset failed!\n", dev->name); + return; + } reg0 = mdio_read(dev, np->phys[0], MII_BMCR); @@ -1062,25 +1257,22 @@ { struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; + int old_debug; - printk(KERN_WARNING "%s: Transmit timed out, status %8.8x," - " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus)); - -#ifndef __alpha__ - { - int i; - printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); - for (i = 0; i < RX_RING_SIZE; i++) - printk(" %8.8x", (unsigned int)le32_to_cpu(np->rx_ring[i].rxaddr)); - printk("\n"KERN_DEBUG" Tx ring %p: ", np->tx_ring); - for (i = 0; i < TX_RING_SIZE; i++) - printk(" %4.4x", le32_to_cpu(np->tx_ring[i].status)); - printk("\n"); - } -#endif + printk(KERN_WARNING "%s: Transmit timed out, status %#8.8x, " + "resetting...\n", dev->name, (int) readl(ioaddr + IntrStatus)); /* Perhaps we should reinitialize the hardware here. */ - /* Stop and restart the chip's Tx processes . */ + + /* + * Stop and restart the interface. + * Cheat and increase the debug level temporarily. + */ + old_debug = debug; + debug = 2; + netdev_close(dev); + netdev_open(dev); + debug = old_debug; /* Trigger an immediate transmit demand. */ @@ -1096,9 +1288,8 @@ struct netdev_private *np = dev->priv; int i; - np->tx_full = 0; - np->cur_rx = np->cur_tx = 0; - np->dirty_rx = np->rx_done = np->dirty_tx = np->tx_done = 0; + np->cur_rx = np->cur_tx = np->reap_tx = 0; + np->dirty_rx = np->dirty_tx = np->rx_done = np->tx_done = 0; np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); @@ -1111,7 +1302,7 @@ np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ /* Grrr, we cannot offset to correctly align the IP header. */ - np->rx_ring[i].rxaddr = cpu_to_le32(np->rx_info[i].mapping | RxDescValid); + np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); } writew(i - 1, dev->base_addr + RxDescQIdx); np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1123,7 +1314,7 @@ np->rx_info[i].mapping = 0; } /* Mark the last entry as wrapping the ring. */ - np->rx_ring[i-1].rxaddr |= cpu_to_le32(RxDescEndRing); + np->rx_ring[RX_RING_SIZE - 1].rxaddr |= cpu_to_dma(RxDescEndRing); /* Clear the completion rings. */ for (i = 0; i < DONE_Q_SIZE; i++) { @@ -1131,18 +1322,9 @@ np->tx_done_q[i].status = 0; } - for (i = 0; i < TX_RING_SIZE; i++) { - np->tx_info[i].skb = NULL; - np->tx_info[i].first_mapping = 0; -#ifdef ZEROCOPY - { - int j; - for (j = 0; j < MAX_STARFIRE_FRAGS; j++) - np->tx_info[i].frag_mapping[j] = 0; - } -#endif /* ZEROCOPY */ - np->tx_ring[i].status = 0; - } + for (i = 0; i < TX_RING_SIZE; i++) + memset(&np->tx_info[i], 0, sizeof(np->tx_info[i])); + return; } @@ -1151,19 +1333,21 @@ { struct netdev_private *np = dev->priv; unsigned int entry; -#ifdef ZEROCOPY + u32 status; int i; -#endif kick_tx_timer(dev, tx_timeout, TX_TIMEOUT); - /* Caution: the write order is important here, set the field - with the "ownership" bits last. */ - - /* Calculate the next Tx descriptor entry. */ - entry = np->cur_tx % TX_RING_SIZE; + /* + * be cautious here, wrapping the queue has weird semantics + * and we may not have enough slots even when it seems we do. + */ + if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) { + netif_stop_queue(dev); + return 1; + } -#if defined(ZEROCOPY) && defined(HAS_FIRMWARE) && defined(HAS_BROKEN_FIRMWARE) +#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) { int has_bad_length = 0; @@ -1180,85 +1364,72 @@ if (has_bad_length) skb_checksum_help(skb); } -#endif /* ZEROCOPY && HAS_FIRMWARE && HAS_BROKEN_FIRMWARE */ +#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ - np->tx_info[entry].skb = skb; - np->tx_info[entry].first_mapping = - pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE); - - np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping); -#ifdef ZEROCOPY - np->tx_ring[entry].first_len = cpu_to_le16(skb_first_frag_len(skb)); - np->tx_ring[entry].total_len = cpu_to_le16(skb->len); - /* Add "| TxDescIntr" to generate Tx-done interrupts. */ - np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn); - np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1); -#else /* not ZEROCOPY */ - /* Add "| TxDescIntr" to generate Tx-done interrupts. */ - np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID | TxCRCEn | 1 << 16); -#endif /* not ZEROCOPY */ - - if (entry >= TX_RING_SIZE-1) /* Wrap ring */ - np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); - -#ifdef ZEROCOPY - if (skb->ip_summed == CHECKSUM_HW) { - np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP); - np->stats.tx_compressed++; - } -#endif /* ZEROCOPY */ - - if (debug > 5) { -#ifdef ZEROCOPY - printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x nbufs %d len %4.4x/%4.4x.\n", - dev->name, np->cur_tx, entry, - le32_to_cpu(np->tx_ring[entry].status), - le32_to_cpu(np->tx_ring[entry].nbufs), - le32_to_cpu(np->tx_ring[entry].first_len), - le32_to_cpu(np->tx_ring[entry].total_len)); -#else /* not ZEROCOPY */ - printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x.\n", - dev->name, np->cur_tx, entry, - le32_to_cpu(np->tx_ring[entry].status)); -#endif /* not ZEROCOPY */ - } - -#ifdef ZEROCOPY - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i]; + entry = np->cur_tx % TX_RING_SIZE; + for (i = 0; i < skb_num_frags(skb); i++) { + int wrap_ring = 0; + status = TxDescID; + + if (i == 0) { + np->tx_info[entry].skb = skb; + status |= TxCRCEn; + if (entry >= TX_RING_SIZE - skb_num_frags(skb)) { + status |= TxRingWrap; + wrap_ring = 1; + } + if (np->reap_tx) { + status |= TxDescIntr; + np->reap_tx = 0; + } + if (skb->ip_summed == CHECKSUM_HW) { + status |= TxCalTCP; + np->stats.tx_compressed++; + } + status |= skb_first_frag_len(skb) | (skb_num_frags(skb) << 16); - /* we already have the proper value in entry */ - np->tx_info[entry].frag_mapping[i] = - pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); - - np->tx_ring[entry].frag[i].addr = cpu_to_le32(np->tx_info[entry].frag_mapping[i]); - np->tx_ring[entry].frag[i].len = cpu_to_le32(this_frag->size); - if (debug > 5) { - printk(KERN_DEBUG "%s: Tx #%d frag %d len %4.4x.\n", - dev->name, np->cur_tx, i, - le32_to_cpu(np->tx_ring[entry].frag[i].len)); - } + np->tx_info[entry].mapping = + pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE); + } else { +#ifdef MAX_SKB_FRAGS + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1]; + status |= this_frag->size; + np->tx_info[entry].mapping = + pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); +#endif /* MAX_SKB_FRAGS */ + } + + np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping); + np->tx_ring[entry].status = cpu_to_le32(status); + if (debug > 3) + printk(KERN_DEBUG "%s: Tx #%d/#%d slot %d status %#8.8x.\n", + dev->name, np->cur_tx, np->dirty_tx, + entry, status); + if (wrap_ring) { + np->tx_info[entry].used_slots = TX_RING_SIZE - entry; + np->cur_tx += np->tx_info[entry].used_slots; + entry = 0; + } else { + np->tx_info[entry].used_slots = 1; + np->cur_tx += np->tx_info[entry].used_slots; + entry++; + } + /* scavenge the tx descriptors twice per TX_RING_SIZE */ + if (np->cur_tx % (TX_RING_SIZE / 2) == 0) + np->reap_tx = 1; } -#endif /* ZEROCOPY */ - - np->cur_tx++; - - if (entry >= TX_RING_SIZE-1) /* Wrap ring */ - entry = -1; - entry++; /* Non-x86: explicitly flush descriptor cache lines here. */ - /* Ensure everything is written back above before the transmit is + /* Ensure all descriptors are written back before the transmit is initiated. - Jes */ wmb(); /* Update the producer index. */ - writel(entry * (sizeof(struct starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx); + writel(entry * (sizeof(starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx); - if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) { - np->tx_full = 1; + /* 4 is arbitrary, but should be ok */ + if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE) netif_stop_queue(dev); - } dev->trans_start = jiffies; @@ -1270,20 +1441,13 @@ after the Tx thread. */ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { - struct net_device *dev = (struct net_device *)dev_instance; + struct net_device *dev = dev_instance; struct netdev_private *np; long ioaddr; int boguscnt = max_interrupt_work; int consumer; int tx_status; -#ifndef final_version /* Can never occur. */ - if (dev == NULL) { - printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown device.\n", irq); - return; - } -#endif - ioaddr = dev->base_addr; np = dev->priv; @@ -1291,83 +1455,69 @@ u32 intr_status = readl(ioaddr + IntrClear); if (debug > 4) - printk(KERN_DEBUG "%s: Interrupt status %4.4x.\n", + printk(KERN_DEBUG "%s: Interrupt status %#8.8x.\n", dev->name, intr_status); - if (intr_status == 0) + if (intr_status == 0 || intr_status == (u32) -1) break; - if (intr_status & IntrRxDone) + if (intr_status & (IntrRxDone | IntrRxEmpty)) netdev_rx(dev); /* Scavenge the skbuff list based on the Tx-done queue. There are redundant checks here that may be cleaned up after the driver has proven to be reliable. */ consumer = readl(ioaddr + TxConsumerIdx); - if (debug > 4) + if (debug > 3) printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n", dev->name, consumer); -#if 0 - if (np->tx_done >= 250 || np->tx_done == 0) - printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, %d is %8.8x.\n", - dev->name, np->tx_done, - le32_to_cpu(np->tx_done_q[np->tx_done].status), - (np->tx_done+1) & (DONE_Q_SIZE-1), - le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status)); -#endif while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status)) != 0) { - if (debug > 4) - printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n", - dev->name, np->tx_done, tx_status); + if (debug > 3) + printk(KERN_DEBUG "%s: Tx completion #%d entry %d is %#8.8x.\n", + dev->name, np->dirty_tx, np->tx_done, tx_status); if ((tx_status & 0xe0000000) == 0xa0000000) { np->stats.tx_packets++; } else if ((tx_status & 0xe0000000) == 0x80000000) { - struct sk_buff *skb; -#ifdef ZEROCOPY - int i; -#endif /* ZEROCOPY */ - u16 entry = tx_status; /* Implicit truncate */ - entry /= sizeof(struct starfire_tx_desc); - - skb = np->tx_info[entry].skb; + u16 entry = (tx_status & 0x7fff) / sizeof(starfire_tx_desc); + struct sk_buff *skb = np->tx_info[entry].skb; np->tx_info[entry].skb = NULL; pci_unmap_single(np->pci_dev, - np->tx_info[entry].first_mapping, + np->tx_info[entry].mapping, skb_first_frag_len(skb), PCI_DMA_TODEVICE); - np->tx_info[entry].first_mapping = 0; - -#ifdef ZEROCOPY - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - pci_unmap_single(np->pci_dev, - np->tx_info[entry].frag_mapping[i], - skb_shinfo(skb)->frags[i].size, - PCI_DMA_TODEVICE); - np->tx_info[entry].frag_mapping[i] = 0; + np->tx_info[entry].mapping = 0; + np->dirty_tx += np->tx_info[entry].used_slots; + entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE; +#ifdef MAX_SKB_FRAGS + { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pci_unmap_single(np->pci_dev, + np->tx_info[entry].mapping, + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + np->dirty_tx++; + entry++; + } } -#endif /* ZEROCOPY */ - - /* Scavenge the descriptor. */ +#endif /* MAX_SKB_FRAGS */ dev_kfree_skb_irq(skb); - - np->dirty_tx++; } np->tx_done_q[np->tx_done].status = 0; - np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1); + np->tx_done = (np->tx_done + 1) % DONE_Q_SIZE; } writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2); - if (np->tx_full && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) { + if (netif_queue_stopped(dev) && + (np->cur_tx - np->dirty_tx + 4 < TX_RING_SIZE)) { /* The ring is no longer full, wake the queue. */ - np->tx_full = 0; netif_wake_queue(dev); } /* Stats overflow */ - if (intr_status & IntrStatsMax) { + if (intr_status & IntrStatsMax) get_stats(dev); - } /* Media change interrupt. */ if (intr_status & IntrLinkChange) @@ -1378,28 +1528,17 @@ netdev_error(dev, intr_status); if (--boguscnt < 0) { - printk(KERN_WARNING "%s: Too much work at interrupt, " - "status=0x%4.4x.\n", - dev->name, intr_status); + if (debug > 1) + printk(KERN_WARNING "%s: Too much work at interrupt, " + "status=%#8.8x.\n", + dev->name, intr_status); break; } } while (1); if (debug > 4) - printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", - dev->name, (int)readl(ioaddr + IntrStatus)); - -#ifndef final_version - /* Code that should never be run! Remove after testing.. */ - { - static int stopit = 10; - if (!netif_running(dev) && --stopit < 0) { - printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n", - dev->name); - free_irq(irq, dev); - } - } -#endif + printk(KERN_DEBUG "%s: exiting interrupt, status=%#8.8x.\n", + dev->name, (int) readl(ioaddr + IntrStatus)); } @@ -1411,26 +1550,21 @@ int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx; u32 desc_status; - if (np->rx_done_q == 0) { - printk(KERN_ERR "%s: rx_done_q is NULL! rx_done is %d. %p.\n", - dev->name, np->rx_done, np->tx_done_q); - return 0; - } - /* If EOP is set on the next entry, it's a new packet. Send it up. */ while ((desc_status = le32_to_cpu(np->rx_done_q[np->rx_done].status)) != 0) { struct sk_buff *skb; u16 pkt_len; int entry; + rx_done_desc *desc = &np->rx_done_q[np->rx_done]; if (debug > 4) - printk(KERN_DEBUG " netdev_rx() status of %d was %8.8x.\n", np->rx_done, desc_status); + printk(KERN_DEBUG " netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status); if (--boguscnt < 0) break; - if ( ! (desc_status & RxOK)) { + if (!(desc_status & RxOK)) { /* There was a error. */ if (debug > 2) - printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n", desc_status); + printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status); np->stats.rx_errors++; if (desc_status & RxFIFOErr) np->stats.rx_fifo_errors++; @@ -1440,10 +1574,8 @@ pkt_len = desc_status; /* Implicitly Truncate */ entry = (desc_status >> 16) & 0x7ff; -#ifndef final_version if (debug > 4) printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d, bogus_cnt %d.\n", pkt_len, boguscnt); -#endif /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak @@ -1453,12 +1585,8 @@ pci_dma_sync_single(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); -#if HAS_IP_COPYSUM /* Call copy + cksum if available. */ eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail, pkt_len); -#endif } else { pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb = np->rx_info[entry].skb; @@ -1470,44 +1598,54 @@ /* You will want this info for the initial debug. */ if (debug > 5) printk(KERN_DEBUG " Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:" - "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x " - "%d.%d.%d.%d.\n", + "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x.\n", skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5], skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], - skb->data[11], skb->data[12], skb->data[13], - skb->data[14], skb->data[15], skb->data[16], - skb->data[17]); + skb->data[11], skb->data[12], skb->data[13]); #endif + skb->protocol = eth_type_trans(skb, dev); -#if defined(full_rx_status) || defined(csum_rx_status) - if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) { +#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT) + if (debug > 4) + printk(KERN_DEBUG " netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2)); +#endif +#ifdef HAS_FIRMWARE + if (le16_to_cpu(desc->status2) & 0x0100) { skb->ip_summed = CHECKSUM_UNNECESSARY; np->stats.rx_compressed++; } /* * This feature doesn't seem to be working, at least * with the two firmware versions I have. If the GFP sees - * a fragment, it either ignores it completely, or reports + * an IP fragment, it either ignores it completely, or reports * "bad checksum" on it. * * Maybe I missed something -- corrections are welcome. * Until then, the printk stays. :-) -Ion */ - else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) { + else if (le16_to_cpu(desc->status2) & 0x0040) { skb->ip_summed = CHECKSUM_HW; - skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff; - printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2); + skb->csum = le16_to_cpu(desc->csum); + printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); } -#endif - netif_rx(skb); +#endif /* HAS_FIRMWARE */ +#ifdef VLAN_SUPPORT + if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) { + if (debug > 4) + printk(KERN_DEBUG " netdev_rx() vlanid = %d\n", le16_to_cpu(desc->vlanid)); + /* vlan_hwaccel_rx expects a packet with the VLAN tag stripped out */ + vlan_hwaccel_rx(skb, np->vlgrp, le16_to_cpu(desc->vlanid) & VLAN_VID_MASK); + } else +#endif /* VLAN_SUPPORT */ + netif_rx(skb); dev->last_rx = jiffies; np->stats.rx_packets++; -next_rx: + next_rx: np->cur_rx++; - np->rx_done_q[np->rx_done].status = 0; - np->rx_done = (np->rx_done + 1) & (DONE_Q_SIZE-1); + desc->status = 0; + np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE; } writew(np->rx_done, dev->base_addr + CompletionQConsumerIdx); @@ -1524,16 +1662,16 @@ pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[entry].rxaddr = - cpu_to_le32(np->rx_info[entry].mapping | RxDescValid); + cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); } if (entry == RX_RING_SIZE - 1) - np->rx_ring[entry].rxaddr |= cpu_to_le32(RxDescEndRing); + np->rx_ring[entry].rxaddr |= cpu_to_dma(RxDescEndRing); /* We could defer this until later... */ writew(entry, dev->base_addr + RxDescQIdx); } if (debug > 5) - printk(KERN_DEBUG " exiting netdev_rx() status of %d was %8.8x.\n", + printk(KERN_DEBUG " exiting netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status); /* Restart Rx engine if stopped. */ @@ -1547,6 +1685,7 @@ long ioaddr = dev->base_addr; u16 reg0, reg1, reg4, reg5; u32 new_tx_mode; + u32 new_intr_timer_ctrl; /* reset status first */ mdio_read(dev, np->phys[0], MII_BMCR); @@ -1591,15 +1730,23 @@ np->speed100 ? "100" : "10", np->mii_if.full_duplex ? "full" : "half"); - new_tx_mode = np->tx_mode & ~0x2; /* duplex setting */ + new_tx_mode = np->tx_mode & ~FullDuplex; /* duplex setting */ if (np->mii_if.full_duplex) - new_tx_mode |= 2; + new_tx_mode |= FullDuplex; if (np->tx_mode != new_tx_mode) { np->tx_mode = new_tx_mode; - writel(np->tx_mode | 0x8000, ioaddr + TxMode); + writel(np->tx_mode | MiiSoftReset, ioaddr + TxMode); udelay(1000); writel(np->tx_mode, ioaddr + TxMode); } + + new_intr_timer_ctrl = np->intr_timer_ctrl & ~Timer10X; + if (np->speed100) + new_intr_timer_ctrl |= Timer10X; + if (np->intr_timer_ctrl != new_intr_timer_ctrl) { + np->intr_timer_ctrl = new_intr_timer_ctrl; + writel(new_intr_timer_ctrl, ioaddr + IntrTimerCtrl); + } } else { netif_carrier_off(dev); printk(KERN_DEBUG "%s: Link is down\n", dev->name); @@ -1613,9 +1760,12 @@ /* Came close to underrunning the Tx FIFO, increase threshold. */ if (intr_status & IntrTxDataLow) { - writel(++np->tx_threshold, dev->base_addr + TxThreshold); - printk(KERN_NOTICE "%s: Increasing Tx FIFO threshold to %d bytes\n", - dev->name, np->tx_threshold * 16); + if (np->tx_threshold <= PKT_BUF_SZ / 16) { + writel(++np->tx_threshold, dev->base_addr + TxThreshold); + printk(KERN_NOTICE "%s: PCI bus congestion, increasing Tx FIFO threshold to %d bytes\n", + dev->name, np->tx_threshold * 16); + } else + printk(KERN_WARNING "%s: PCI Tx underflow -- adapter is probably malfunctioning\n", dev->name); } if (intr_status & IntrRxGFPDead) { np->stats.rx_fifo_errors++; @@ -1626,7 +1776,7 @@ np->stats.tx_errors++; } if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrRxGFPDead | IntrNoTxCsum | IntrPCIPad)) && debug) - printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", + printk(KERN_ERR "%s: Something Wicked happened! %#8.8x.\n", dev->name, intr_status); } @@ -1661,39 +1811,67 @@ /* Chips may use the upper or lower CRC bits, and may reverse and/or invert them. Select the endian-ness that results in minimal calculations. */ - static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; - u32 rx_mode; + u32 rx_mode = MinVLANPrio; struct dev_mc_list *mclist; int i; +#ifdef VLAN_SUPPORT + struct netdev_private *np = dev->priv; + + rx_mode |= VlanMode; + if (np->vlgrp) { + int vlan_count = 0; + long filter_addr = ioaddr + HashTable + 8; + for (i = 0; i < VLAN_VID_MASK; i++) { + if (np->vlgrp->vlan_devices[i]) { + if (vlan_count >= 32) + break; + writew(cpu_to_be16(i), filter_addr); + filter_addr += 16; + vlan_count++; + } + } + if (i == VLAN_VID_MASK) { + rx_mode |= PerfectFilterVlan; + while (vlan_count < 32) { + writew(0, filter_addr); + filter_addr += 16; + vlan_count++; + } + } + } +#endif /* VLAN_SUPPORT */ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptAll|AcceptMyPhys; + rx_mode |= AcceptAll; } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { /* Too many to match, or accept all multicasts. */ - rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys; - } else if (dev->mc_count <= 15) { - /* Use the 16 element perfect filter, skip first entry. */ - long filter_addr = ioaddr + PerfFilterTable + 1 * 16; - for (i = 1, mclist = dev->mc_list; mclist && i <= dev->mc_count; + rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter; + } else if (dev->mc_count <= 14) { + /* Use the 16 element perfect filter, skip first two entries. */ + long filter_addr = ioaddr + PerfFilterTable + 2 * 16; + u16 *eaddrs; + for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2; i++, mclist = mclist->next) { - u16 *eaddrs = (u16 *)mclist->dmi_addr; + eaddrs = (u16 *)mclist->dmi_addr; writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 4; writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4; writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 8; } + eaddrs = (u16 *)dev->dev_addr; while (i++ < 16) { - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 8; + writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8; } - rx_mode = AcceptBroadcast | AcceptMyPhys; + rx_mode |= AcceptBroadcast|PerfectFilter; } else { /* Must use a multicast hash table. */ long filter_addr; + u16 *eaddrs; u16 mc_filter[32] __attribute__ ((aligned(sizeof(long)))); /* Multicast hash filter */ memset(mc_filter, 0, sizeof(mc_filter)); @@ -1704,16 +1882,17 @@ *fptr |= cpu_to_le32(1 << (bit_nr & 31)); } - /* Clear the perfect filter list, skip first entry. */ - filter_addr = ioaddr + PerfFilterTable + 1 * 16; - for (i = 1; i < 16; i++) { - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 8; + /* Clear the perfect filter list, skip first two entries. */ + filter_addr = ioaddr + PerfFilterTable + 2 * 16; + eaddrs = (u16 *)dev->dev_addr; + for (i = 2; i < 16; i++) { + writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8; } - for (filter_addr = ioaddr + HashTable, i=0; i < 32; filter_addr+= 16, i++) + for (filter_addr = ioaddr + HashTable, i = 0; i < 32; filter_addr+= 16, i++) writew(mc_filter[i], filter_addr); - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode |= AcceptBroadcast|PerfectFilter|HashFilter; } writel(rx_mode, ioaddr + RxFilterMode); } @@ -1760,6 +1939,7 @@ spin_lock_irq(&np->lock); r = mii_ethtool_sset(&np->mii_if, &ecmd); spin_unlock_irq(&np->lock); + check_duplex(dev); return r; } /* restart autonegotiation */ @@ -1813,7 +1993,7 @@ spin_lock_irq(&np->lock); rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); spin_unlock_irq(&np->lock); - + if ((cmd == SIOCSMIIREG) && (data->phy_id == np->phys[0])) check_duplex(dev); } @@ -1831,41 +2011,42 @@ netif_stop_if(dev); if (debug > 1) { - printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %4.4x.\n", - dev->name, (int)readl(ioaddr + IntrStatus)); - printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", - dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx); + printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n", + dev->name, (int) readl(ioaddr + IntrStatus)); + printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", + dev->name, np->cur_tx, np->dirty_tx, + np->cur_rx, np->dirty_rx); } /* Disable interrupts by clearing the interrupt mask. */ writel(0, ioaddr + IntrEnable); /* Stop the chip's Tx and Rx processes. */ + writel(0, ioaddr + GenCtrl); + readl(ioaddr + GenCtrl); -#ifdef __i386__ - if (debug > 2) { - printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", - np->tx_ring_dma); + if (debug > 5) { + printk(KERN_DEBUG" Tx ring at %#llx:\n", + (long long) np->tx_ring_dma); for (i = 0; i < 8 /* TX_RING_SIZE is huge! */; i++) - printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n", + printk(KERN_DEBUG " #%d desc. %#8.8x %#llx -> %#8.8x.\n", i, le32_to_cpu(np->tx_ring[i].status), - le32_to_cpu(np->tx_ring[i].first_addr), + (long long) dma_to_cpu(np->tx_ring[i].addr), le32_to_cpu(np->tx_done_q[i].status)); - printk(KERN_DEBUG " Rx ring at %8.8x -> %p:\n", - np->rx_ring_dma, np->rx_done_q); + printk(KERN_DEBUG " Rx ring at %#llx -> %p:\n", + (long long) np->rx_ring_dma, np->rx_done_q); if (np->rx_done_q) for (i = 0; i < 8 /* RX_RING_SIZE */; i++) { - printk(KERN_DEBUG " #%d desc. %8.8x -> %8.8x\n", - i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status)); + printk(KERN_DEBUG " #%d desc. %#llx -> %#8.8x\n", + i, (long long) dma_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status)); } } -#endif /* __i386__ debugging only */ free_irq(dev->irq, dev); /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { - np->rx_ring[i].rxaddr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ + np->rx_ring[i].rxaddr = cpu_to_dma(0xBADF00D0); /* An invalid address. */ if (np->rx_info[i].skb != NULL) { pci_unmap_single(np->pci_dev, np->rx_info[i].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE); dev_kfree_skb(np->rx_info[i].skb); @@ -1875,28 +2056,14 @@ } for (i = 0; i < TX_RING_SIZE; i++) { struct sk_buff *skb = np->tx_info[i].skb; -#ifdef ZEROCOPY - int j; -#endif /* ZEROCOPY */ if (skb == NULL) continue; pci_unmap_single(np->pci_dev, - np->tx_info[i].first_mapping, + np->tx_info[i].mapping, skb_first_frag_len(skb), PCI_DMA_TODEVICE); - np->tx_info[i].first_mapping = 0; + np->tx_info[i].mapping = 0; dev_kfree_skb(skb); np->tx_info[i].skb = NULL; -#ifdef ZEROCOPY - for (j = 0; j < MAX_STARFIRE_FRAGS; j++) - if (np->tx_info[i].frag_mapping[j]) { - pci_unmap_single(np->pci_dev, - np->tx_info[i].frag_mapping[j], - skb_shinfo(skb)->frags[j].size, - PCI_DMA_TODEVICE); - np->tx_info[i].frag_mapping[j] = 0; - } else - break; -#endif /* ZEROCOPY */ } COMPAT_MOD_DEC_USE_COUNT; @@ -1914,19 +2081,8 @@ BUG(); np = dev->priv; - if (np->tx_done_q) - pci_free_consistent(pdev, PAGE_SIZE, - np->tx_done_q, np->tx_done_q_dma); - if (np->rx_done_q) - pci_free_consistent(pdev, - sizeof(struct rx_done_desc) * DONE_Q_SIZE, - np->rx_done_q, np->rx_done_q_dma); - if (np->tx_ring) - pci_free_consistent(pdev, PAGE_SIZE, - np->tx_ring, np->tx_ring_dma); - if (np->rx_ring) - pci_free_consistent(pdev, PAGE_SIZE, - np->rx_ring, np->rx_ring_dma); + if (np->queue_mem) + pci_free_consistent(pdev, np->queue_mem_size, np->queue_mem, np->queue_mem_dma); unregister_netdev(dev); iounmap((char *)dev->base_addr); @@ -1951,6 +2107,17 @@ #ifdef MODULE printk(version); #endif +#ifndef ADDR_64BITS + /* we can do this test only at run-time... sigh */ + if (sizeof(dma_addr_t) == sizeof(u64)) { + printk("This driver has not been ported to this 64-bit architecture yet\n"); + return -ENODEV; + } +#endif /* not ADDR_64BITS */ +#ifndef HAS_FIRMWARE + /* unconditionally disable hw cksums if firmware is not present */ + enable_hw_cksum = 0; +#endif /* not HAS_FIRMWARE */ return pci_module_init (&starfire_driver); } @@ -1967,8 +2134,6 @@ /* * Local variables: - * compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O2 -c starfire.c" - * simple-compile-command: "gcc -DMODULE -O2 -c starfire.c" * c-basic-offset: 8 * tab-width: 8 * End: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/tokenring/smctr.c linux.21pre4-ac6/drivers/net/tokenring/smctr.c --- linux.21pre4/drivers/net/tokenring/smctr.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/tokenring/smctr.c 2003-02-06 22:35:54.000000000 +0000 @@ -3102,7 +3102,7 @@ __u8 r; /* Check if node address has been specified by user. (non-0) */ - for(i = 0; ((i < 6) && (dev->dev_addr[i] == 0)); i++); + for(i = 0; ((i < 6) && (dev->dev_addr[i] == 0)); i++) { if(i != 6) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/tun.c linux.21pre4-ac6/drivers/net/tun.c --- linux.21pre4/drivers/net/tun.c 2003-01-29 16:26:44.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/tun.c 2003-02-19 16:22:32.000000000 +0000 @@ -188,7 +188,7 @@ size_t len = count; if (!(tun->flags & TUN_NO_PI)) { - if ((len -= sizeof(pi)) < 0) + if ((len -= sizeof(pi)) > len) return -EINVAL; memcpy_fromiovec((void *)&pi, iv, sizeof(pi)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/typhoon.c linux.21pre4-ac6/drivers/net/typhoon.c --- linux.21pre4/drivers/net/typhoon.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/net/typhoon.c 2003-02-19 16:01:19.000000000 +0000 @@ -0,0 +1,2505 @@ +/* typhoon.c: A Linux Ethernet device driver for 3Com 3CR990 family of NICs */ +/* + Written 2002-2003 by David Dillow + Based on code written 1998-2000 by Donald Becker and + Linux 2.2.x driver by David P. McLean . + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. + + This software is available on a public web site. It may enable + cryptographic capabilities of the 3Com hardware, and may be + exported from the United States under License Exception "TSU" + pursuant to 15 C.F.R. Section 740.13(e). + + This work was funded by the National Library of Medicine under + the Department of Energy project number 0274DD06D1 and NLM project + number Y1-LM-2015-01. + + This driver is designed for the 3Com 3CR990 Family of cards with the + 3XP Processor. It has been tested on x86 and sparc64. + + KNOWN ISSUES: + *) The current firmware always strips the VLAN tag off, even if + we tell it not to. You should filter VLANs at the switch + as a workaround (good practice in any event) until we can + get this fixed. + *) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware + issue. Hopefully 3Com will fix it. + *) Waiting for a command response takes 8ms due to non-preemptable + polling. Only significant for getting stats and creating + SAs, but an ugly wart never the less. + *) I've not tested multicast. I think it works, but reports welcome. + *) Doesn't do IPSEC offloading. Yet. Keep yer pants on, it's coming. +*/ + +/* Set the copy breakpoint for the copy-only-tiny-frames scheme. + * Setting to > 1518 effectively disables this feature. + */ +static int rx_copybreak = 0; + +/* end user-configurable values */ + +/* Maximum number of multicast addresses to filter (vs. rx-all-multicast). + */ +static const int multicast_filter_limit = 32; + +/* Operational parameters that are set at compile time. */ + +/* Keep the ring sizes a power of two for compile efficiency. + * The compiler will convert '%'<2^N> into a bit mask. + * Making the Tx ring too large decreases the effectiveness of channel + * bonding and packet priority. + * There are no ill effects from too-large receive rings. + * + * We don't currently use the Hi Tx ring so, don't make it very big. + * + * Beware that if we start using the Hi Tx ring, we will need to change + * typhoon_num_free_tx() and typhoon_tx_complete() to account for that. + */ +#define TXHI_ENTRIES 2 +#define TXLO_ENTRIES 128 +#define RX_ENTRIES 32 +#define COMMAND_ENTRIES 16 +#define RESPONSE_ENTRIES 32 + +#define COMMAND_RING_SIZE (COMMAND_ENTRIES * sizeof(struct cmd_desc)) +#define RESPONSE_RING_SIZE (RESPONSE_ENTRIES * sizeof(struct resp_desc)) + +/* The 3XP will preload and remove 64 entries from the free buffer + * list, and we need one entry to keep the ring from wrapping, so + * to keep this a power of two, we use 128 entries. + */ +#define RXFREE_ENTRIES 128 +#define RXENT_ENTRIES (RXFREE_ENTRIES - 1) + +/* Operational parameters that usually are not changed. */ + +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (2*HZ) + +#define PKT_BUF_SZ 1536 + +#define DRV_MODULE_NAME "typhoon" +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "03/02/14" +#define PFX DRV_MODULE_NAME ": " +#define ERR_PFX KERN_ERR PFX + +#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) +#warning You must compile this file with the correct options! +#warning See the last lines of the source file. +#error You must compile this driver with "-O". +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "typhoon.h" +#include "typhoon-firmware.h" + +static char version[] __devinitdata = + "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + +MODULE_AUTHOR("David Dillow "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)"); +MODULE_PARM(rx_copybreak, "i"); + +#if defined(NETIF_F_TSO) && MAX_SKB_FRAGS > 32 +#warning Typhoon only supports 32 entries in its SG list for TSO, disabling TSO +#undef NETIF_F_TSO +#endif + +#if TXLO_ENTRIES <= (2 * MAX_SKB_FRAGS) +#error TX ring too small! +#endif + +struct typhoon_card_info { + char *name; + int capabilities; +}; + +#define TYPHOON_CRYPTO_NONE 0 +#define TYPHOON_CRYPTO_DES 1 +#define TYPHOON_CRYPTO_3DES 2 +#define TYPHOON_CRYPTO_VARIABLE 4 +#define TYPHOON_FIBER 5 + +enum typhoon_cards { + TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR, + TYPHOON_SVR95, TYPHOON_SVR97, TYPHOON_TXM, TYPHOON_BSVR, + TYPHOON_FX95, TYPHOON_FX97, TYPHOON_FX95SVR, TYPHOON_FX97SVR, +}; + +/* directly indexed by enum typhoon_cards, above */ +static struct typhoon_card_info typhoon_card_info[] __devinitdata = { + { "3Com Typhoon (3C990-TX)", + TYPHOON_CRYPTO_NONE}, + { "3Com Typhoon (3CR990-TX-95)", + TYPHOON_CRYPTO_DES}, + { "3Com Typhoon (3CR990-TX-97)", + TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES}, + { "3Com Typhoon (3C990SVR)", + TYPHOON_CRYPTO_NONE}, + { "3Com Typhoon (3CR990SVR95)", + TYPHOON_CRYPTO_DES}, + { "3Com Typhoon (3CR990SVR97)", + TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES}, + { "3Com Typhoon2 (3C990B-TX-M)", + TYPHOON_CRYPTO_VARIABLE}, + { "3Com Typhoon2 (3C990BSVR)", + TYPHOON_CRYPTO_VARIABLE}, + { "3Com Typhoon (3CR990-FX-95)", + TYPHOON_CRYPTO_DES | TYPHOON_FIBER}, + { "3Com Typhoon (3CR990-FX-97)", + TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER}, + { "3Com Typhoon (3CR990-FX-95 Server)", + TYPHOON_CRYPTO_DES | TYPHOON_FIBER}, + { "3Com Typhoon (3CR990-FX-97 Server)", + TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER}, +}; + +/* Notes on the new subsystem numbering scheme: + * bits 0-1 indicate crypto capabilites: (0) variable, (1) DES, or (2) 3DES + * bit 4 indicates if this card has secured firmware (we don't support it) + * bit 8 indicates if this is a (0) copper or (1) fiber card + * bits 12-16 indicate card type: (0) client and (1) server + */ +static struct pci_device_id typhoon_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990, + PCI_ANY_ID, PCI_ANY_ID, 0, 0,TYPHOON_TX }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_95, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_TX95 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_97, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_TX97 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B, + PCI_ANY_ID, 0x1000, 0, 0, TYPHOON_TXM }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B, + PCI_ANY_ID, 0x2000, 0, 0, TYPHOON_BSVR }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX, + PCI_ANY_ID, 0x1101, 0, 0, TYPHOON_FX95 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX, + PCI_ANY_ID, 0x1102, 0, 0, TYPHOON_FX97 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX, + PCI_ANY_ID, 0x2101, 0, 0, TYPHOON_FX95SVR }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX, + PCI_ANY_ID, 0x2102, 0, 0, TYPHOON_FX97SVR }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR95, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR95 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR97, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR97 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, typhoon_pci_tbl); + +/* Define the shared memory area + * Align everything the 3XP will normally be using. + * We'll need to move/align txHi if we start using that ring. + */ +#define __3xp_aligned ____cacheline_aligned +struct typhoon_shared { + struct typhoon_interface iface; + struct typhoon_indexes indexes __3xp_aligned; + struct tx_desc txLo[TXLO_ENTRIES] __3xp_aligned; + struct rx_desc rxLo[RX_ENTRIES] __3xp_aligned; + struct rx_desc rxHi[RX_ENTRIES] __3xp_aligned; + struct cmd_desc cmd[COMMAND_ENTRIES] __3xp_aligned; + struct resp_desc resp[RESPONSE_ENTRIES] __3xp_aligned; + struct rx_free rxBuff[RXFREE_ENTRIES] __3xp_aligned; + u32 zeroWord; + struct tx_desc txHi[TXHI_ENTRIES]; +} __attribute__ ((packed)); + +struct rxbuff_ent { + struct sk_buff *skb; + dma_addr_t dma_addr; +}; + +struct typhoon { + /* Tx cache line section */ + struct transmit_ring txLoRing ____cacheline_aligned; + struct pci_dev * tx_pdev; + unsigned long tx_ioaddr; + u32 txlo_dma_addr; + + /* Irq/Rx cache line section */ + unsigned long ioaddr ____cacheline_aligned; + struct typhoon_indexes *indexes; + u8 awaiting_resp; + u8 duplex; + u8 speed; + u8 card_state; + struct basic_ring rxLoRing; + struct pci_dev * pdev; + struct net_device * dev; + spinlock_t state_lock; + struct vlan_group * vlgrp; + struct basic_ring rxHiRing; + struct basic_ring rxBuffRing; + struct rxbuff_ent rxbuffers[RXENT_ENTRIES]; + + /* general section */ + spinlock_t command_lock ____cacheline_aligned; + struct basic_ring cmdRing; + struct basic_ring respRing; + struct net_device_stats stats; + struct net_device_stats stats_saved; + const char * name; + struct typhoon_shared * shared; + dma_addr_t shared_dma; + u16 xcvr_select; + u16 wol_events; + u32 offload; + u32 pci_state[16]; + + /* unused stuff (future use) */ + int capabilities; + struct transmit_ring txHiRing; +}; + +enum completion_wait_values { + NoWait = 0, WaitNoSleep, WaitSleep, +}; + +/* These are the values for the typhoon.card_state variable. + * These determine where the statistics will come from in get_stats(). + * The sleep image does not support the statistics we need. + */ +enum state_values { + Sleeping = 0, Running, +}; + +/* PCI writes are not guaranteed to be posted in order, but outstanding writes + * cannot pass a read, so this forces current writes to post. + */ +#define typhoon_post_pci_writes(x) \ + do { readl(x + TYPHOON_REG_HEARTBEAT); } while(0) + +/* We'll wait up to six seconds for a reset, and half a second normally. + */ +#define TYPHOON_UDELAY 50 +#define TYPHOON_RESET_TIMEOUT (6 * HZ) +#define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28) +#define typhoon_synchronize_irq(x) synchronize_irq() +#else +#define typhoon_synchronize_irq(x) synchronize_irq(x) +#endif + +#if defined(NETIF_F_TSO) +#define skb_tso_size(x) (skb_shinfo(x)->tso_size) +#define TSO_NUM_DESCRIPTORS 2 +#define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT +#else +#define NETIF_F_TSO 0 +#define skb_tso_size(x) 0 +#define TSO_NUM_DESCRIPTORS 0 +#define TSO_OFFLOAD_ON 0 +#endif + +static inline void +typhoon_inc_index(u32 *index, const int count, const int num_entries) +{ + /* Increment a ring index -- we can use this for all rings execept + * the Rx rings, as they use different size descriptors + * otherwise, everything is the same size as a cmd_desc + */ + *index += count * sizeof(struct cmd_desc); + *index %= num_entries * sizeof(struct cmd_desc); +} + +static inline void +typhoon_inc_cmd_index(u32 *index, const int count) +{ + typhoon_inc_index(index, count, COMMAND_ENTRIES); +} + +static inline void +typhoon_inc_resp_index(u32 *index, const int count) +{ + typhoon_inc_index(index, count, RESPONSE_ENTRIES); +} + +static inline void +typhoon_inc_rxfree_index(u32 *index, const int count) +{ + typhoon_inc_index(index, count, RXFREE_ENTRIES); +} + +static inline void +typhoon_inc_tx_index(u32 *index, const int count) +{ + /* if we start using the Hi Tx ring, this needs updateing */ + typhoon_inc_index(index, count, TXLO_ENTRIES); +} + +static inline void +typhoon_inc_rx_index(u32 *index, const int count) +{ + /* sizeof(struct rx_desc) != sizeof(struct cmd_desc) */ + *index += count * sizeof(struct rx_desc); + *index %= RX_ENTRIES * sizeof(struct rx_desc); +} + +static int +typhoon_reset(unsigned long ioaddr, int wait_type) +{ + int i, err = 0; + int timeout = TYPHOON_RESET_TIMEOUT; + + if(wait_type == WaitNoSleep) + timeout = (timeout * 1000000) / (HZ * TYPHOON_UDELAY); + + writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); + writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS); + + writel(TYPHOON_RESET_ALL, ioaddr + TYPHOON_REG_SOFT_RESET); + typhoon_post_pci_writes(ioaddr); + udelay(1); + writel(TYPHOON_RESET_NONE, ioaddr + TYPHOON_REG_SOFT_RESET); + + if(wait_type != NoWait) { + for(i = 0; i < timeout; i++) { + if(readl(ioaddr + TYPHOON_REG_STATUS) == + TYPHOON_STATUS_WAITING_FOR_HOST) + goto out; + + if(wait_type == WaitSleep) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } else + udelay(TYPHOON_UDELAY); + } + + err = -ETIMEDOUT; + } + +out: + writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); + writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS); + udelay(100); + return err; + + /* The 3XP seems to need a little extra time to complete the load + * of the sleep image before we can reliably boot it. Failure to + * do this occasionally results in a hung adapter after boot in + * typhoon_init_one() while trying to read the MAC address or + * putting the card to sleep. 3Com's driver waits 5ms, but + * that seems to be overkill -- with a 50usec delay, it survives + * 35000 typhoon_init_one() calls, where it only make it 25-100 + * without it. + * + * As it turns out, still occasionally getting a hung adapter, + * so I'm bumping it to 100us. + */ +} + +static int +typhoon_wait_status(unsigned long ioaddr, u32 wait_value) +{ + int i, err = 0; + + for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) { + if(readl(ioaddr + TYPHOON_REG_STATUS) == wait_value) + goto out; + udelay(TYPHOON_UDELAY); + } + + err = -ETIMEDOUT; + +out: + return err; +} + +static inline void +typhoon_media_status(struct net_device *dev, struct resp_desc *resp) +{ + if(resp->parm1 & TYPHOON_MEDIA_STAT_NO_LINK) + netif_carrier_off(dev); + else + netif_carrier_on(dev); +} + +static inline void +typhoon_hello(struct typhoon *tp) +{ + struct basic_ring *ring = &tp->cmdRing; + struct cmd_desc *cmd; + + /* We only get a hello request if we've not sent anything to the + * card in a long while. If the lock is held, then we're in the + * process of issuing a command, so we don't need to respond. + */ + if(spin_trylock(&tp->command_lock)) { + cmd = (struct cmd_desc *)(ring->ringBase + ring->lastWrite); + typhoon_inc_cmd_index(&ring->lastWrite, 1); + + INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP); + smp_wmb(); + writel(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); + spin_unlock(&tp->command_lock); + } +} + +static int +typhoon_process_response(struct typhoon *tp, int resp_size, + struct resp_desc *resp_save) +{ + struct typhoon_indexes *indexes = tp->indexes; + struct resp_desc *resp; + u8 *base = tp->respRing.ringBase; + int count, len, wrap_len; + u32 cleared; + u32 ready; + + cleared = le32_to_cpu(indexes->respCleared); + ready = le32_to_cpu(indexes->respReady); + while(cleared != ready) { + resp = (struct resp_desc *)(base + cleared); + count = resp->numDesc + 1; + if(resp_save && resp->seqNo) { + if(count > resp_size) { + resp_save->flags = TYPHOON_RESP_ERROR; + goto cleanup; + } + + wrap_len = 0; + len = count * sizeof(*resp); + if(unlikely(cleared + len > RESPONSE_RING_SIZE)) { + wrap_len = cleared + len - RESPONSE_RING_SIZE; + len = RESPONSE_RING_SIZE - cleared; + } + + memcpy(resp_save, resp, len); + if(unlikely(wrap_len)) { + resp_save += len / sizeof(*resp); + memcpy(resp_save, base, wrap_len); + } + + resp_save = NULL; + } else if(resp->cmd == TYPHOON_CMD_READ_MEDIA_STATUS) { + typhoon_media_status(tp->dev, resp); + } else if(resp->cmd == TYPHOON_CMD_HELLO_RESP) { + typhoon_hello(tp); + } else { + printk(KERN_ERR "%s: dumping unexpected response " + "0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n", + tp->name, le16_to_cpu(resp->cmd), + resp->numDesc, resp->flags, + le16_to_cpu(resp->parm1), + le32_to_cpu(resp->parm2), + le32_to_cpu(resp->parm3)); + } + +cleanup: + typhoon_inc_resp_index(&cleared, count); + } + + indexes->respCleared = cpu_to_le32(cleared); + wmb(); + return (resp_save == NULL); +} + +static inline int +typhoon_num_free(int lastWrite, int lastRead, int ringSize) +{ + /* this works for all descriptors but rx_desc, as they are a + * different size than the cmd_desc -- everyone else is the same + */ + lastWrite /= sizeof(struct cmd_desc); + lastRead /= sizeof(struct cmd_desc); + return (ringSize + lastRead - lastWrite - 1) % ringSize; +} + +static inline int +typhoon_num_free_cmd(struct typhoon *tp) +{ + int lastWrite = tp->cmdRing.lastWrite; + int cmdCleared = le32_to_cpu(tp->indexes->cmdCleared); + + return typhoon_num_free(lastWrite, cmdCleared, COMMAND_ENTRIES); +} + +static inline int +typhoon_num_free_resp(struct typhoon *tp) +{ + int respReady = le32_to_cpu(tp->indexes->respReady); + int respCleared = le32_to_cpu(tp->indexes->respCleared); + + return typhoon_num_free(respReady, respCleared, RESPONSE_ENTRIES); +} + +static inline int +typhoon_num_free_tx(struct transmit_ring *ring) +{ + /* if we start using the Hi Tx ring, this needs updating */ + return typhoon_num_free(ring->lastWrite, ring->lastRead, TXLO_ENTRIES); +} + +static int +typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd, + int num_resp, struct resp_desc *resp) +{ + struct typhoon_indexes *indexes = tp->indexes; + struct basic_ring *ring = &tp->cmdRing; + struct resp_desc local_resp; + int i, err = 0; + int got_resp; + int freeCmd, freeResp; + int len, wrap_len; + + spin_lock(&tp->command_lock); + + freeCmd = typhoon_num_free_cmd(tp); + freeResp = typhoon_num_free_resp(tp); + + if(freeCmd < num_cmd || freeResp < num_resp) { + printk("%s: no descs for cmd, had (needed) %d (%d) cmd, " + "%d (%d) resp\n", tp->name, freeCmd, num_cmd, + freeResp, num_resp); + err = -ENOMEM; + goto out; + } + + if(cmd->flags & TYPHOON_CMD_RESPOND) { + /* If we're expecting a response, but the caller hasn't given + * us a place to put it, we'll provide one. + */ + tp->awaiting_resp = 1; + if(resp == NULL) { + resp = &local_resp; + num_resp = 1; + } + } + + wrap_len = 0; + len = num_cmd * sizeof(*cmd); + if(unlikely(ring->lastWrite + len > COMMAND_RING_SIZE)) { + wrap_len = ring->lastWrite + len - COMMAND_RING_SIZE; + len = COMMAND_RING_SIZE - ring->lastWrite; + } + + memcpy(ring->ringBase + ring->lastWrite, cmd, len); + if(unlikely(wrap_len)) { + struct cmd_desc *wrap_ptr = cmd; + wrap_ptr += len / sizeof(*cmd); + memcpy(ring->ringBase, wrap_ptr, wrap_len); + } + + typhoon_inc_cmd_index(&ring->lastWrite, num_cmd); + + /* "I feel a presence... another warrior is on the the mesa." + */ + wmb(); + writel(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); + typhoon_post_pci_writes(tp->ioaddr); + + if((cmd->flags & TYPHOON_CMD_RESPOND) == 0) + goto out; + + /* Ugh. We'll be here about 8ms, spinning our thumbs, unable to + * preempt or do anything other than take interrupts. So, don't + * wait for a response unless you have to. + * + * I've thought about trying to sleep here, but we're called + * from many contexts that don't allow that. Also, given the way + * 3Com has implemented irq coalescing, we would likely timeout -- + * this has been observed in real life! + * + * The big killer is we have to wait to get stats from the card, + * though we could go to a periodic refresh of those if we don't + * mind them getting somewhat stale. The rest of the waiting + * commands occur during open/close/suspend/resume, so they aren't + * time critical. Creating SAs in the future will also have to + * wait here. + */ + got_resp = 0; + for(i = 0; i < TYPHOON_WAIT_TIMEOUT && !got_resp; i++) { + if(indexes->respCleared != indexes->respReady) + got_resp = typhoon_process_response(tp, num_resp, + resp); + udelay(TYPHOON_UDELAY); + } + + if(!got_resp) { + err = -ETIMEDOUT; + goto out; + } + + /* Collect the error response even if we don't care about the + * rest of the response + */ + if(resp->flags & TYPHOON_RESP_ERROR) + err = -EIO; + +out: + if(tp->awaiting_resp) { + tp->awaiting_resp = 0; + smp_wmb(); + + /* Ugh. If a response was added to the ring between + * the call to typhoon_process_response() and the clearing + * of tp->awaiting_resp, we could have missed the interrupt + * and it could hang in the ring an indeterminate amount of + * time. So, check for it, and interrupt ourselves if this + * is the case. + */ + if(indexes->respCleared != indexes->respReady) + writel(1, tp->ioaddr + TYPHOON_REG_SELF_INTERRUPT); + } + + spin_unlock(&tp->command_lock); + return err; +} + +static void +typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + struct cmd_desc xp_cmd; + int err; + + spin_lock_bh(&tp->state_lock); + if(!tp->vlgrp != !grp) { + /* We've either been turned on for the first time, or we've + * been turned off. Update the 3XP. + */ + if(grp) + tp->offload |= TYPHOON_OFFLOAD_VLAN; + else + tp->offload &= ~TYPHOON_OFFLOAD_VLAN; + + /* If the interface is up, the runtime is running -- and we + * must be up for the vlan core to call us. + * + * Do the command outside of the spin lock, as it is slow. + */ + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, + TYPHOON_CMD_SET_OFFLOAD_TASKS); + xp_cmd.parm2 = tp->offload; + xp_cmd.parm3 = tp->offload; + spin_unlock_bh(&tp->state_lock); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + printk("%s: vlan offload error %d\n", tp->name, -err); + spin_lock_bh(&tp->state_lock); + } + + /* now make the change visible */ + tp->vlgrp = grp; + spin_unlock_bh(&tp->state_lock); +} + +static void +typhoon_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + spin_lock_bh(&tp->state_lock); + if(tp->vlgrp) + tp->vlgrp->vlan_devices[vid] = NULL; + spin_unlock_bh(&tp->state_lock); +} + +static inline void +typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing, + u32 ring_dma) +{ + struct tcpopt_desc *tcpd; + u32 tcpd_offset = ring_dma; + + tcpd = (struct tcpopt_desc *) (txRing->ringBase + txRing->lastWrite); + tcpd_offset += txRing->lastWrite; + tcpd_offset += offsetof(struct tcpopt_desc, bytesTx); + typhoon_inc_tx_index(&txRing->lastWrite, 1); + + tcpd->flags = TYPHOON_OPT_DESC | TYPHOON_OPT_TCP_SEG; + tcpd->numDesc = 1; + tcpd->mss_flags = cpu_to_le16(skb_tso_size(skb)); + tcpd->mss_flags |= TYPHOON_TSO_FIRST | TYPHOON_TSO_LAST; + tcpd->respAddrLo = cpu_to_le32(tcpd_offset); + tcpd->bytesTx = cpu_to_le32(skb->len); + tcpd->status = 0; +} + +static int +typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + struct transmit_ring *txRing; + struct tx_desc *txd, *first_txd; + dma_addr_t skb_dma; + int numDesc; + + /* we have two rings to choose from, but we only use txLo for now + * If we start using the Hi ring as well, we'll need to update + * typhoon_stop_runtime(), typhoon_interrupt(), typhoon_num_free_tx(), + * and TXHI_ENTIRES to match, as well as update the TSO code below + * to get the right DMA address + */ + txRing = &tp->txLoRing; + + /* We need one descriptor for each fragment of the sk_buff, plus the + * one for the ->data area of it. + * + * The docs say a maximum of 16 fragment descriptors per TCP option + * descriptor, then make a new packet descriptor and option descriptor + * for the next 16 fragments. The engineers say just an option + * descriptor is needed. I've tested up to 26 fragments with a single + * packet descriptor/option descriptor combo, so I use that for now. + * + * If problems develop with TSO, check this first. + */ + numDesc = skb_shinfo(skb)->nr_frags + 1; + if(skb_tso_size(skb)) + numDesc++; + + /* When checking for free space in the ring, we need to also + * account for the initial Tx descriptor, and we always must leave + * at least one descriptor unused in the ring so that it doesn't + * wrap and look empty. + * + * The only time we should loop here is when we hit the race + * between marking the queue awake and updating the cleared index. + * Just loop and it will appear. This comes from the acenic driver. + */ + while(unlikely(typhoon_num_free_tx(txRing) < (numDesc + 2))) + smp_rmb(); + + first_txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); + typhoon_inc_tx_index(&txRing->lastWrite, 1); + + first_txd->flags = TYPHOON_TX_DESC | TYPHOON_DESC_VALID; + first_txd->numDesc = 0; + first_txd->len = 0; + first_txd->addr = (u64)((unsigned long) skb) & 0xffffffff; + first_txd->addrHi = (u64)((unsigned long) skb) >> 32; + first_txd->processFlags = 0; + + if(skb->ip_summed == CHECKSUM_HW) { + /* The 3XP will figure out if this is UDP/TCP */ + first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM; + first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM; + first_txd->processFlags |= TYPHOON_TX_PF_IP_CHKSUM; + } + + if(vlan_tx_tag_present(skb)) { + first_txd->processFlags |= + TYPHOON_TX_PF_INSERT_VLAN | TYPHOON_TX_PF_VLAN_PRIORITY; + first_txd->processFlags |= + cpu_to_le32(htons(vlan_tx_tag_get(skb)) << + TYPHOON_TX_PF_VLAN_TAG_SHIFT); + } + + if(skb_tso_size(skb)) { + first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT; + first_txd->numDesc++; + + typhoon_tso_fill(skb, txRing, tp->txlo_dma_addr); + } + + txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); + typhoon_inc_tx_index(&txRing->lastWrite, 1); + + /* No need to worry about padding packet -- the firmware pads + * it with zeros to ETH_ZLEN for us. + */ + if(skb_shinfo(skb)->nr_frags == 0) { + skb_dma = pci_map_single(tp->tx_pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; + txd->len = cpu_to_le16(skb->len); + txd->addr = cpu_to_le32(skb_dma); + txd->addrHi = 0; + first_txd->numDesc++; + } else { + int i, len; + + len = skb->len - skb->data_len; + skb_dma = pci_map_single(tp->tx_pdev, skb->data, len, + PCI_DMA_TODEVICE); + txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; + txd->len = cpu_to_le16(len); + txd->addr = cpu_to_le32(skb_dma); + txd->addrHi = 0; + first_txd->numDesc++; + + for(i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + void *frag_addr; + + txd = (struct tx_desc *) (txRing->ringBase + + txRing->lastWrite); + typhoon_inc_tx_index(&txRing->lastWrite, 1); + + len = frag->size; + frag_addr = (void *) page_address(frag->page) + + frag->page_offset; + skb_dma = pci_map_single(tp->tx_pdev, frag_addr, len, + PCI_DMA_TODEVICE); + txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; + txd->len = cpu_to_le16(len); + txd->addr = cpu_to_le32(skb_dma); + txd->addrHi = 0; + first_txd->numDesc++; + } + } + + /* Kick the 3XP + */ + wmb(); + writel(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister); + + dev->trans_start = jiffies; + + /* If we don't have room to put the worst case packet on the + * queue, then we must stop the queue. We need 2 extra + * descriptors -- one to prevent ring wrap, and one for the + * Tx header. + */ + numDesc = MAX_SKB_FRAGS + TSO_NUM_DESCRIPTORS + 1; + + if(typhoon_num_free_tx(txRing) < (numDesc + 2)) { + netif_stop_queue(dev); + + /* A Tx complete IRQ could have gotten inbetween, making + * the ring free again. Only need to recheck here, since + * Tx is serialized. + */ + if(typhoon_num_free_tx(txRing) >= (numDesc + 2)) + netif_wake_queue(dev); + } + + return 0; +} + +static void +typhoon_set_rx_mode(struct net_device *dev) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + struct cmd_desc xp_cmd; + u32 mc_filter[2]; + u16 filter; + + filter = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST; + if(dev->flags & IFF_PROMISC) { + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", + dev->name); + filter |= TYPHOON_RX_FILTER_PROMISCOUS; + } else if((dev->mc_count > multicast_filter_limit) || + (dev->flags & IFF_ALLMULTI)) { + /* Too many to match, or accept all multicasts. */ + filter |= TYPHOON_RX_FILTER_ALL_MCAST; + } else if(dev->mc_count) { + struct dev_mc_list *mclist; + int i; + + memset(mc_filter, 0, sizeof(mc_filter)); + for(i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + int bit = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f; + mc_filter[bit >> 5] |= 1 << (bit & 0x1f); + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, + TYPHOON_CMD_SET_MULTICAST_HASH); + xp_cmd.parm1 = TYPHOON_MCAST_HASH_SET; + xp_cmd.parm2 = cpu_to_le32(mc_filter[0]); + xp_cmd.parm3 = cpu_to_le32(mc_filter[1]); + typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + + filter |= TYPHOON_RX_FILTER_MCAST_HASH; + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER); + xp_cmd.parm1 = filter; + typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); +} + +static int +typhoon_do_get_stats(struct typhoon *tp) +{ + struct net_device_stats *stats = &tp->stats; + struct net_device_stats *saved = &tp->stats_saved; + struct cmd_desc xp_cmd; + struct resp_desc xp_resp[7]; + struct stats_resp *s = (struct stats_resp *) xp_resp; + int err; + + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_STATS); + err = typhoon_issue_command(tp, 1, &xp_cmd, 7, xp_resp); + if(err < 0) + return err; + + /* 3Com's Linux driver uses txMultipleCollisions as it's + * collisions value, but there is some other collision info as well... + */ + stats->tx_packets = le32_to_cpu(s->txPackets); + stats->tx_bytes = le32_to_cpu(s->txBytes); + stats->tx_errors = le32_to_cpu(s->txCarrierLost); + stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost); + stats->collisions = le32_to_cpu(s->txMultipleCollisions); + stats->rx_packets = le32_to_cpu(s->rxPacketsGood); + stats->rx_bytes = le32_to_cpu(s->rxBytesGood); + stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns); + stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + + le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors); + stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors); + stats->rx_length_errors = le32_to_cpu(s->rxOversized); + tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? + SPEED_100 : SPEED_10; + tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? + DUPLEX_FULL : DUPLEX_HALF; + + /* add in the saved statistics + */ + stats->tx_packets += saved->tx_packets; + stats->tx_bytes += saved->tx_bytes; + stats->tx_errors += saved->tx_errors; + stats->collisions += saved->collisions; + stats->rx_packets += saved->rx_packets; + stats->rx_bytes += saved->rx_bytes; + stats->rx_fifo_errors += saved->rx_fifo_errors; + stats->rx_errors += saved->rx_errors; + stats->rx_crc_errors += saved->rx_crc_errors; + stats->rx_length_errors += saved->rx_length_errors; + + return 0; +} + +static struct net_device_stats * +typhoon_get_stats(struct net_device *dev) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + struct net_device_stats *stats = &tp->stats; + struct net_device_stats *saved = &tp->stats_saved; + + smp_rmb(); + if(tp->card_state == Sleeping) + return saved; + + if(typhoon_do_get_stats(tp) < 0) { + printk(KERN_ERR "%s: error getting stats\n", dev->name); + return saved; + } + + return stats; +} + +static int +typhoon_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *saddr = (struct sockaddr *) addr; + + if(netif_running(dev)) + return -EBUSY; + + memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len); + return 0; +} + +static inline void +typhoon_ethtool_gdrvinfo(struct typhoon *tp, struct ethtool_drvinfo *info) +{ + struct pci_dev *pci_dev = tp->pdev; + struct cmd_desc xp_cmd; + struct resp_desc xp_resp[3]; + + smp_rmb(); + if(tp->card_state == Sleeping) { + strcpy(info->fw_version, "Sleep image"); + } else { + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); + if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { + strcpy(info->fw_version, "Unknown runtime"); + } else { + strncpy(info->fw_version, (char *) &xp_resp[1], 32); + info->fw_version[31] = 0; + } + } + + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); + strcpy(info->bus_info, pci_dev->slot_name); +} + +static inline void +typhoon_ethtool_gset(struct typhoon *tp, struct ethtool_cmd *cmd) +{ + cmd->supported = SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg; + + switch (tp->xcvr_select) { + case TYPHOON_XCVR_10HALF: + cmd->advertising = ADVERTISED_10baseT_Half; + break; + case TYPHOON_XCVR_10FULL: + cmd->advertising = ADVERTISED_10baseT_Full; + break; + case TYPHOON_XCVR_100HALF: + cmd->advertising = ADVERTISED_100baseT_Half; + break; + case TYPHOON_XCVR_100FULL: + cmd->advertising = ADVERTISED_100baseT_Full; + break; + case TYPHOON_XCVR_AUTONEG: + cmd->advertising = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_Autoneg; + break; + } + + if(tp->capabilities & TYPHOON_FIBER) { + cmd->supported |= SUPPORTED_FIBRE; + cmd->advertising |= ADVERTISED_FIBRE; + cmd->port = PORT_FIBRE; + } else { + cmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_TP; + cmd->advertising |= ADVERTISED_TP; + cmd->port = PORT_TP; + } + + /* need to get stats to make these link speed/duplex valid */ + typhoon_do_get_stats(tp); + cmd->speed = tp->speed; + cmd->duplex = tp->duplex; + cmd->phy_address = 0; + cmd->transceiver = XCVR_INTERNAL; + if(tp->xcvr_select == TYPHOON_XCVR_AUTONEG) + cmd->autoneg = AUTONEG_ENABLE; + else + cmd->autoneg = AUTONEG_DISABLE; + cmd->maxtxpkt = 1; + cmd->maxrxpkt = 1; +} + +static inline int +typhoon_ethtool_sset(struct typhoon *tp, struct ethtool_cmd *cmd) +{ + struct cmd_desc xp_cmd; + int xcvr; + int err; + + if(cmd->autoneg == AUTONEG_ENABLE) { + xcvr = TYPHOON_XCVR_AUTONEG; + } else { + if(cmd->duplex == DUPLEX_HALF) { + if(cmd->speed == SPEED_10) + xcvr = TYPHOON_XCVR_10HALF; + else if(cmd->speed == SPEED_100) + xcvr = TYPHOON_XCVR_100HALF; + else + return -EINVAL; + } else if(cmd->duplex == DUPLEX_FULL) { + if(cmd->speed == SPEED_10) + xcvr = TYPHOON_XCVR_10FULL; + else if(cmd->speed == SPEED_100) + xcvr = TYPHOON_XCVR_100FULL; + else + return -EINVAL; + } else + return -EINVAL; + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT); + xp_cmd.parm1 = cpu_to_le16(xcvr); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + return err; + + tp->xcvr_select = xcvr; + if(cmd->autoneg == AUTONEG_ENABLE) { + tp->speed = 0xff; /* invalid */ + tp->duplex = 0xff; /* invalid */ + } else { + tp->speed = cmd->speed; + tp->duplex = cmd->duplex; + } + + return 0; +} + +static inline int +typhoon_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + u32 ethcmd; + + if(copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + + typhoon_ethtool_gdrvinfo(tp, &info); + if(copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; + } + case ETHTOOL_GSET: { + struct ethtool_cmd cmd = { ETHTOOL_GSET }; + + typhoon_ethtool_gset(tp, &cmd); + if(copy_to_user(useraddr, &cmd, sizeof(cmd))) + return -EFAULT; + return 0; + } + case ETHTOOL_SSET: { + struct ethtool_cmd cmd; + if(copy_from_user(&cmd, useraddr, sizeof(cmd))) + return -EFAULT; + + return typhoon_ethtool_sset(tp, &cmd); + } + case ETHTOOL_GLINK:{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + + edata.data = netif_carrier_ok(dev) ? 1 : 0; + if(copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_GWOL: { + struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; + + if(tp->wol_events & TYPHOON_WAKE_LINK_EVENT) + wol.wolopts |= WAKE_PHY; + if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) + wol.wolopts |= WAKE_MAGIC; + if(copy_to_user(useraddr, &wol, sizeof(wol))) + return -EFAULT; + return 0; + } + case ETHTOOL_SWOL: { + struct ethtool_wolinfo wol; + + if(copy_from_user(&wol, useraddr, sizeof(wol))) + return -EFAULT; + tp->wol_events = 0; + if(wol.wolopts & WAKE_PHY) + tp->wol_events |= TYPHOON_WAKE_LINK_EVENT; + if(wol.wolopts & WAKE_MAGIC) + tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT; + return 0; + } + default: + break; + } + + return -EOPNOTSUPP; +} + +static int +typhoon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + switch (cmd) { + case SIOCETHTOOL: + return typhoon_ethtool_ioctl(dev, (void *) ifr->ifr_data); + default: + break; + } + + return -EOPNOTSUPP; +} + +static int +typhoon_wait_interrupt(unsigned long ioaddr) +{ + int i, err = 0; + + for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) { + if(readl(ioaddr + TYPHOON_REG_INTR_STATUS) & + TYPHOON_INTR_BOOTCMD) + goto out; + udelay(TYPHOON_UDELAY); + } + + err = -ETIMEDOUT; + +out: + writel(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS); + return err; +} + +#define shared_offset(x) offsetof(struct typhoon_shared, x) + +static void +typhoon_init_interface(struct typhoon *tp) +{ + struct typhoon_interface *iface = &tp->shared->iface; + dma_addr_t shared_dma; + + memset(tp->shared, 0, sizeof(struct typhoon_shared)); + + /* The *Hi members of iface are all init'd to zero by the memset(). + */ + shared_dma = tp->shared_dma + shared_offset(indexes); + iface->ringIndex = cpu_to_le32(shared_dma); + + shared_dma = tp->shared_dma + shared_offset(txLo); + iface->txLoAddr = cpu_to_le32(shared_dma); + iface->txLoSize = cpu_to_le32(TXLO_ENTRIES * sizeof(struct tx_desc)); + + shared_dma = tp->shared_dma + shared_offset(txHi); + iface->txHiAddr = cpu_to_le32(shared_dma); + iface->txHiSize = cpu_to_le32(TXHI_ENTRIES * sizeof(struct tx_desc)); + + shared_dma = tp->shared_dma + shared_offset(rxBuff); + iface->rxBuffAddr = cpu_to_le32(shared_dma); + iface->rxBuffSize = cpu_to_le32(RXFREE_ENTRIES * + sizeof(struct rx_free)); + + shared_dma = tp->shared_dma + shared_offset(rxLo); + iface->rxLoAddr = cpu_to_le32(shared_dma); + iface->rxLoSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); + + shared_dma = tp->shared_dma + shared_offset(rxHi); + iface->rxHiAddr = cpu_to_le32(shared_dma); + iface->rxHiSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); + + shared_dma = tp->shared_dma + shared_offset(cmd); + iface->cmdAddr = cpu_to_le32(shared_dma); + iface->cmdSize = cpu_to_le32(COMMAND_RING_SIZE); + + shared_dma = tp->shared_dma + shared_offset(resp); + iface->respAddr = cpu_to_le32(shared_dma); + iface->respSize = cpu_to_le32(RESPONSE_RING_SIZE); + + shared_dma = tp->shared_dma + shared_offset(zeroWord); + iface->zeroAddr = cpu_to_le32(shared_dma); + + tp->indexes = &tp->shared->indexes; + tp->txLoRing.ringBase = (u8 *) tp->shared->txLo; + tp->txHiRing.ringBase = (u8 *) tp->shared->txHi; + tp->rxLoRing.ringBase = (u8 *) tp->shared->rxLo; + tp->rxHiRing.ringBase = (u8 *) tp->shared->rxHi; + tp->rxBuffRing.ringBase = (u8 *) tp->shared->rxBuff; + tp->cmdRing.ringBase = (u8 *) tp->shared->cmd; + tp->respRing.ringBase = (u8 *) tp->shared->resp;; + + tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY; + tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY; + + tp->txlo_dma_addr = iface->txLoAddr; + tp->card_state = Sleeping; + smp_wmb(); + + tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; + tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; + + spin_lock_init(&tp->command_lock); + spin_lock_init(&tp->state_lock); +} + +static void +typhoon_init_rings(struct typhoon *tp) +{ + memset(tp->indexes, 0, sizeof(struct typhoon_indexes)); + + tp->txLoRing.lastWrite = 0; + tp->txHiRing.lastWrite = 0; + tp->rxLoRing.lastWrite = 0; + tp->rxHiRing.lastWrite = 0; + tp->rxBuffRing.lastWrite = 0; + tp->cmdRing.lastWrite = 0; + tp->cmdRing.lastWrite = 0; + + tp->txLoRing.lastRead = 0; + tp->txHiRing.lastRead = 0; +} + +static int +typhoon_download_firmware(struct typhoon *tp) +{ + unsigned long ioaddr = tp->ioaddr; + struct pci_dev *pdev = tp->pdev; + struct typhoon_file_header *fHdr; + struct typhoon_section_header *sHdr; + u8 *image_data; + void *dpage; + dma_addr_t dpage_dma; + unsigned int csum; + u32 irqEnabled; + u32 irqMasked; + u32 numSections; + u32 section_len; + u32 len; + u32 load_addr; + int i; + int err; + + err = -EINVAL; + fHdr = (struct typhoon_file_header *) typhoon_firmware_image; + image_data = (u8 *) fHdr; + + if(memcmp(fHdr->tag, "TYPHOON", 8)) { + printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name); + goto err_out; + } + + /* Cannot just map the firmware image using pci_map_single() as + * the firmware is part of the kernel/module image, so we allocate + * some consistent memory to copy the sections into, as it is simpler, + * and short-lived. If we ever split out and require a userland + * firmware loader, then we can revisit this. + */ + err = -ENOMEM; + dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma); + if(!dpage) { + printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name); + goto err_out; + } + + irqEnabled = readl(ioaddr + TYPHOON_REG_INTR_ENABLE); + writel(irqEnabled | TYPHOON_INTR_BOOTCMD, + ioaddr + TYPHOON_REG_INTR_ENABLE); + irqMasked = readl(ioaddr + TYPHOON_REG_INTR_MASK); + writel(irqMasked | TYPHOON_INTR_BOOTCMD, + ioaddr + TYPHOON_REG_INTR_MASK); + + err = -ETIMEDOUT; + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { + printk(KERN_ERR "%s: card ready timeout\n", tp->name); + goto err_out_irq; + } + + numSections = le32_to_cpu(fHdr->numSections); + load_addr = le32_to_cpu(fHdr->startAddr); + + writel(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS); + writel(load_addr, ioaddr + TYPHOON_REG_DOWNLOAD_BOOT_ADDR); + typhoon_post_pci_writes(ioaddr); + writel(TYPHOON_BOOTCMD_RUNTIME_IMAGE, ioaddr + TYPHOON_REG_COMMAND); + + image_data += sizeof(struct typhoon_file_header); + + /* The readl() in typhoon_wait_interrupt() will force the + * last write to the command register to post, so + * we don't need a typhoon_post_pci_writes() after it. + */ + for(i = 0; i < numSections; i++) { + sHdr = (struct typhoon_section_header *) image_data; + image_data += sizeof(struct typhoon_section_header); + load_addr = le32_to_cpu(sHdr->startAddr); + section_len = le32_to_cpu(sHdr->len); + + while(section_len) { + len = min_t(u32, section_len, PAGE_SIZE); + + if(typhoon_wait_interrupt(ioaddr) < 0 || + readl(ioaddr + TYPHOON_REG_STATUS) != + TYPHOON_STATUS_WAITING_FOR_SEGMENT) { + printk(KERN_ERR "%s: segment ready timeout\n", + tp->name); + goto err_out_irq; + } + + /* Do an pseudo IPv4 checksum on the data -- first + * need to convert each u16 to cpu order before + * summing. Fortunately, due to the properties of + * the checksum, we can do this once, at the end. + */ + csum = csum_partial_copy_nocheck(image_data, dpage, + len, 0); + csum = csum_fold(csum); + csum = le16_to_cpu(csum); + + writel(len, ioaddr + TYPHOON_REG_BOOT_LENGTH); + writel(csum, ioaddr + TYPHOON_REG_BOOT_CHECKSUM); + writel(load_addr, ioaddr + TYPHOON_REG_BOOT_DEST_ADDR); + writel(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI); + writel(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO); + typhoon_post_pci_writes(ioaddr); + writel(TYPHOON_BOOTCMD_SEG_AVAILABLE, + ioaddr + TYPHOON_REG_COMMAND); + + image_data += len; + load_addr += len; + section_len -= len; + } + } + + if(typhoon_wait_interrupt(ioaddr) < 0 || + readl(ioaddr + TYPHOON_REG_STATUS) != + TYPHOON_STATUS_WAITING_FOR_SEGMENT) { + printk(KERN_ERR "%s: final segment ready timeout\n", tp->name); + goto err_out_irq; + } + + writel(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND); + + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) { + printk(KERN_ERR "%s: boot ready timeout, status 0x%0x\n", + tp->name, readl(ioaddr + TYPHOON_REG_STATUS)); + goto err_out_irq; + } + + err = 0; + +err_out_irq: + writel(irqMasked, ioaddr + TYPHOON_REG_INTR_MASK); + writel(irqEnabled, ioaddr + TYPHOON_REG_INTR_ENABLE); + + pci_free_consistent(pdev, PAGE_SIZE, dpage, dpage_dma); + +err_out: + return err; +} + +static int +typhoon_boot_3XP(struct typhoon *tp, u32 initial_status) +{ + unsigned long ioaddr = tp->ioaddr; + + if(typhoon_wait_status(ioaddr, initial_status) < 0) { + printk(KERN_ERR "%s: boot ready timeout\n", tp->name); + goto out_timeout; + } + + writel(0, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_HI); + writel(tp->shared_dma, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_LO); + typhoon_post_pci_writes(ioaddr); + writel(TYPHOON_BOOTCMD_REG_BOOT_RECORD, ioaddr + TYPHOON_REG_COMMAND); + + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) { + printk(KERN_ERR "%s: boot finish timeout (status 0x%x)\n", + tp->name, readl(ioaddr + TYPHOON_REG_STATUS)); + goto out_timeout; + } + + /* Clear the Transmit and Command ready registers + */ + writel(0, ioaddr + TYPHOON_REG_TX_HI_READY); + writel(0, ioaddr + TYPHOON_REG_CMD_READY); + writel(0, ioaddr + TYPHOON_REG_TX_LO_READY); + typhoon_post_pci_writes(ioaddr); + writel(TYPHOON_BOOTCMD_BOOT, ioaddr + TYPHOON_REG_COMMAND); + + return 0; + +out_timeout: + return -ETIMEDOUT; +} + +static u32 +typhoon_clean_tx(struct typhoon *tp, struct transmit_ring *txRing, + volatile u32 * index) +{ + u32 lastRead = txRing->lastRead; + struct tx_desc *tx; + dma_addr_t skb_dma; + int dma_len; + int type; + + while(lastRead != le32_to_cpu(*index)) { + tx = (struct tx_desc *) (txRing->ringBase + lastRead); + type = tx->flags & TYPHOON_TYPE_MASK; + + if(type == TYPHOON_TX_DESC) { + /* This tx_desc describes a packet. + */ + unsigned long ptr = tx->addr | ((u64)tx->addrHi << 32); + struct sk_buff *skb = (struct sk_buff *) ptr; + dev_kfree_skb_irq(skb); + } else if(type == TYPHOON_FRAG_DESC) { + /* This tx_desc describes a memory mapping. Free it. + */ + skb_dma = (dma_addr_t) le32_to_cpu(tx->addr); + dma_len = le16_to_cpu(tx->len); + pci_unmap_single(tp->pdev, skb_dma, dma_len, + PCI_DMA_TODEVICE); + } + + tx->flags = 0; + typhoon_inc_tx_index(&lastRead, 1); + } + + return lastRead; +} + +static void +typhoon_tx_complete(struct typhoon *tp, struct transmit_ring *txRing, + volatile u32 * index) +{ + u32 lastRead; + int numDesc = MAX_SKB_FRAGS + 1; + + /* This will need changing if we start to use the Hi Tx ring. */ + lastRead = typhoon_clean_tx(tp, txRing, index); + if(netif_queue_stopped(tp->dev) && typhoon_num_free(txRing->lastWrite, + lastRead, TXLO_ENTRIES) > (numDesc + 2)) + netif_wake_queue(tp->dev); + + txRing->lastRead = lastRead; + smp_wmb(); +} + +static void +typhoon_recycle_rx_skb(struct typhoon *tp, u32 idx) +{ + struct typhoon_indexes *indexes = tp->indexes; + struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; + struct basic_ring *ring = &tp->rxBuffRing; + struct rx_free *r; + + if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == + indexes->rxBuffCleared) { + /* no room in ring, just drop the skb + */ + dev_kfree_skb_any(rxb->skb); + rxb->skb = NULL; + return; + } + + r = (struct rx_free *) (ring->ringBase + ring->lastWrite); + typhoon_inc_rxfree_index(&ring->lastWrite, 1); + r->virtAddr = idx; + r->physAddr = cpu_to_le32(rxb->dma_addr); + + /* Tell the card about it */ + wmb(); + indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); +} + +static int +typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) +{ + struct typhoon_indexes *indexes = tp->indexes; + struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; + struct basic_ring *ring = &tp->rxBuffRing; + struct rx_free *r; + struct sk_buff *skb; + dma_addr_t dma_addr; + + rxb->skb = NULL; + + if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == + indexes->rxBuffCleared) + return -ENOMEM; + + skb = dev_alloc_skb(PKT_BUF_SZ); + if(!skb) + return -ENOMEM; + +#if 0 + /* Please, 3com, fix the firmware to allow DMA to a unaligned + * address! Pretty please? + */ + skb_reserve(skb, 2); +#endif + + skb->dev = tp->dev; + dma_addr = pci_map_single(tp->pdev, skb->tail, + PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + + /* Since no card does 64 bit DAC, the high bits will never + * change from zero. + */ + r = (struct rx_free *) (ring->ringBase + ring->lastWrite); + typhoon_inc_rxfree_index(&ring->lastWrite, 1); + r->virtAddr = idx; + r->physAddr = cpu_to_le32(dma_addr); + rxb->skb = skb; + rxb->dma_addr = dma_addr; + + /* Tell the card about it */ + wmb(); + indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); + return 0; +} + +static int +typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready, + volatile u32 * cleared, int budget) +{ + struct rx_desc *rx; + struct sk_buff *skb, *new_skb; + struct rxbuff_ent *rxb; + dma_addr_t dma_addr; + u32 local_ready; + u32 rxaddr; + int pkt_len; + u32 idx; + u32 csum_bits; + int received; + + received = 0; + local_ready = le32_to_cpu(*ready); + rxaddr = le32_to_cpu(*cleared); + while(rxaddr != local_ready && budget > 0) { + rx = (struct rx_desc *) (rxRing->ringBase + rxaddr); + idx = rx->addr; + rxb = &tp->rxbuffers[idx]; + skb = rxb->skb; + dma_addr = rxb->dma_addr; + + rxaddr += sizeof(struct rx_desc); + rxaddr %= RX_ENTRIES * sizeof(struct rx_desc); + + if(rx->flags & TYPHOON_RX_ERROR) { + typhoon_recycle_rx_skb(tp, idx); + continue; + } + + pkt_len = le16_to_cpu(rx->frameLen); + + if(pkt_len < rx_copybreak && + (new_skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + new_skb->dev = tp->dev; + skb_reserve(new_skb, 2); + pci_dma_sync_single(tp->pdev, dma_addr, PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0); + skb_put(new_skb, pkt_len); + typhoon_recycle_rx_skb(tp, idx); + } else { + new_skb = skb; + skb_put(new_skb, pkt_len); + pci_unmap_single(tp->pdev, dma_addr, PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + typhoon_alloc_rx_skb(tp, idx); + } + new_skb->protocol = eth_type_trans(new_skb, tp->dev); + csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD | + TYPHOON_RX_UDP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD); + if(csum_bits == + (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD) + || csum_bits == + (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) { + new_skb->ip_summed = CHECKSUM_UNNECESSARY; + } else + new_skb->ip_summed = CHECKSUM_NONE; + + spin_lock(&tp->state_lock); + if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN) + vlan_hwaccel_receive_skb(new_skb, tp->vlgrp, + ntohl(rx->vlanTag) & 0xffff); + else + netif_receive_skb(new_skb); + spin_unlock(&tp->state_lock); + + tp->dev->last_rx = jiffies; + received++; + budget--; + } + *cleared = cpu_to_le32(rxaddr); + + return received; +} + +static void +typhoon_fill_free_ring(struct typhoon *tp) +{ + u32 i; + + for(i = 0; i < RXENT_ENTRIES; i++) { + struct rxbuff_ent *rxb = &tp->rxbuffers[i]; + if(rxb->skb) + continue; + if(typhoon_alloc_rx_skb(tp, i) < 0) + break; + } +} + +static int +typhoon_poll(struct net_device *dev, int *total_budget) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + struct typhoon_indexes *indexes = tp->indexes; + int orig_budget = *total_budget; + int budget, work_done, done; + + rmb(); + if(!tp->awaiting_resp && indexes->respReady != indexes->respCleared) + typhoon_process_response(tp, 0, NULL); + + if(le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead) + typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared); + + if(orig_budget > dev->quota) + orig_budget = dev->quota; + + budget = orig_budget; + work_done = 0; + done = 1; + + if(indexes->rxHiCleared != indexes->rxHiReady) { + work_done = typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady, + &indexes->rxHiCleared, budget); + budget -= work_done; + } + + if(indexes->rxLoCleared != indexes->rxLoReady) { + work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady, + &indexes->rxLoCleared, budget); + } + + if(work_done) { + *total_budget -= work_done; + dev->quota -= work_done; + + if(work_done >= orig_budget) + done = 0; + } + + if(le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) { + /* rxBuff ring is empty, try to fill it. */ + typhoon_fill_free_ring(tp); + } + + if(done) { + netif_rx_complete(dev); + writel(TYPHOON_INTR_NONE, tp->ioaddr + TYPHOON_REG_INTR_MASK); + typhoon_post_pci_writes(tp->ioaddr); + } + + return (done ? 0 : 1); +} + +static void +typhoon_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) +{ + struct net_device *dev = (struct net_device *) dev_instance; + unsigned long ioaddr = dev->base_addr; + u32 intr_status; + + intr_status = readl(ioaddr + TYPHOON_REG_INTR_STATUS); + if(!intr_status) + return; + + writel(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS); + + if(netif_rx_schedule_prep(dev)) { + writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); + typhoon_post_pci_writes(ioaddr); + __netif_rx_schedule(dev); + } else { + printk(KERN_ERR "%s: Error, poll already scheduled\n", + dev->name); + } +} + +static void +typhoon_free_rx_rings(struct typhoon *tp) +{ + u32 i; + + for(i = 0; i < RXENT_ENTRIES; i++) { + struct rxbuff_ent *rxb = &tp->rxbuffers[i]; + if(rxb->skb) { + pci_unmap_single(tp->pdev, rxb->dma_addr, PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(rxb->skb); + rxb->skb = NULL; + } + } +} + +static int +typhoon_sleep(struct typhoon *tp, int state, u16 events) +{ + struct pci_dev *pdev = tp->pdev; + unsigned long ioaddr = tp->ioaddr; + struct cmd_desc xp_cmd; + int err; + + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_ENABLE_WAKE_EVENTS); + xp_cmd.parm1 = events; + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) { + printk(KERN_ERR "%s: typhoon_sleep(): wake events cmd err %d\n", + tp->name, err); + return err; + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) { + printk(KERN_ERR "%s: typhoon_sleep(): sleep cmd err %d\n", + tp->name, err); + return err; + } + + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0) + return -ETIMEDOUT; + + pci_enable_wake(tp->pdev, state, 1); + pci_disable_device(pdev); + return pci_set_power_state(pdev, state); +} + +static int +typhoon_wakeup(struct typhoon *tp, int wait_type) +{ + struct pci_dev *pdev = tp->pdev; + unsigned long ioaddr = tp->ioaddr; + + pci_set_power_state(pdev, 0); + pci_restore_state(pdev, tp->pci_state); + + writel(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND); + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) + return typhoon_reset(ioaddr, wait_type); + + return 0; +} + +static int +typhoon_start_runtime(struct typhoon *tp) +{ + struct net_device *dev = tp->dev; + unsigned long ioaddr = tp->ioaddr; + struct cmd_desc xp_cmd; + int err; + + typhoon_init_rings(tp); + typhoon_fill_free_ring(tp); + + err = typhoon_download_firmware(tp); + if(err < 0) { + printk("%s: cannot load runtime on 3XP\n", tp->name); + goto error_out; + } + + if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) { + printk("%s: cannot boot 3XP\n", tp->name); + err = -EIO; + goto error_out; + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAX_PKT_SIZE); + xp_cmd.parm1 = cpu_to_le16(PKT_BUF_SZ); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS); + xp_cmd.parm1 = cpu_to_le16(ntohs(*(u16 *)&dev->dev_addr[0])); + xp_cmd.parm2 = cpu_to_le32(ntohl(*(u32 *)&dev->dev_addr[2])); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + /* Disable IRQ coalescing -- we can reenable it when 3Com gives + * us some more information on how to control it. + */ + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_IRQ_COALESCE_CTRL); + xp_cmd.parm1 = 0; + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT); + xp_cmd.parm1 = tp->xcvr_select; + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE); + xp_cmd.parm1 = __constant_cpu_to_le16(ETH_P_8021Q); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS); + spin_lock_bh(&tp->state_lock); + xp_cmd.parm2 = tp->offload; + xp_cmd.parm3 = tp->offload; + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + spin_unlock_bh(&tp->state_lock); + if(err < 0) + goto error_out; + + typhoon_set_rx_mode(dev); + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_ENABLE); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_ENABLE); + err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + if(err < 0) + goto error_out; + + tp->card_state = Running; + smp_wmb(); + + writel(TYPHOON_INTR_ENABLE_ALL, ioaddr + TYPHOON_REG_INTR_ENABLE); + writel(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_MASK); + typhoon_post_pci_writes(ioaddr); + + return 0; + +error_out: + typhoon_reset(ioaddr, WaitNoSleep); + typhoon_free_rx_rings(tp); + typhoon_init_rings(tp); + return err; +} + +static int +typhoon_stop_runtime(struct typhoon *tp, int wait_type) +{ + struct typhoon_indexes *indexes = tp->indexes; + struct transmit_ring *txLo = &tp->txLoRing; + unsigned long ioaddr = tp->ioaddr; + struct cmd_desc xp_cmd; + int i; + + /* Disable interrupts early, since we can't schedule a poll + * when called with !netif_running(). This will be posted + * when we force the posting of the command. + */ + writel(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_ENABLE); + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_DISABLE); + typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + + /* Wait 1/2 sec for any outstanding transmits to occur + * We'll cleanup after the reset if this times out. + */ + for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) { + if(indexes->txLoCleared == cpu_to_le32(txLo->lastWrite)) + break; + udelay(TYPHOON_UDELAY); + } + + if(i == TYPHOON_WAIT_TIMEOUT) + printk(KERN_ERR + "%s: halt timed out waiting for Tx to complete\n", + tp->name); + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE); + typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + + /* save the statistics so when we bring the interface up again, + * the values reported to userspace are correct. + */ + tp->card_state = Sleeping; + smp_wmb(); + typhoon_do_get_stats(tp); + memcpy(&tp->stats_saved, &tp->stats, sizeof(struct net_device_stats)); + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_HALT); + typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); + + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0) + printk(KERN_ERR "%s: timed out waiting for 3XP to halt\n", + tp->name); + + if(typhoon_reset(ioaddr, wait_type) < 0) { + printk(KERN_ERR "%s: unable to reset 3XP\n", tp->name); + return -ETIMEDOUT; + } + + /* cleanup any outstanding Tx packets */ + if(indexes->txLoCleared != cpu_to_le32(txLo->lastWrite)) { + indexes->txLoCleared = cpu_to_le32(txLo->lastWrite); + typhoon_clean_tx(tp, &tp->txLoRing, &indexes->txLoCleared); + } + + return 0; +} + +static void +typhoon_tx_timeout(struct net_device *dev) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + + if(typhoon_reset(dev->base_addr, WaitNoSleep) < 0) { + printk(KERN_WARNING "%s: could not reset in tx timeout\n", + dev->name); + goto truely_dead; + } + + /* If we ever start using the Hi ring, it will need cleaning too */ + typhoon_clean_tx(tp, &tp->txLoRing, &tp->indexes->txLoCleared); + typhoon_free_rx_rings(tp); + + if(typhoon_start_runtime(tp) < 0) { + printk(KERN_ERR "%s: could not start runtime in tx timeout\n", + dev->name); + goto truely_dead; + } + + netif_wake_queue(dev); + return; + +truely_dead: + /* Reset the hardware, and turn off carrier to avoid more timeouts */ + typhoon_reset(dev->base_addr, NoWait); + netif_carrier_off(dev); +} + +static int +typhoon_open(struct net_device *dev) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + int err; + + err = typhoon_wakeup(tp, WaitSleep); + if(err < 0) { + printk(KERN_ERR "%s: unable to wakeup device\n", dev->name); + goto out_sleep; + } + + err = request_irq(dev->irq, &typhoon_interrupt, SA_SHIRQ, + dev->name, dev); + if(err < 0) + goto out_sleep; + + err = typhoon_start_runtime(tp); + if(err < 0) + goto out_irq; + + netif_start_queue(dev); + return 0; + +out_irq: + free_irq(dev->irq, dev); + +out_sleep: + if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { + printk(KERN_ERR "%s: unable to reboot into sleep img\n", + dev->name); + typhoon_reset(dev->base_addr, NoWait); + goto out; + } + + if(typhoon_sleep(tp, 3, 0) < 0) + printk(KERN_ERR "%s: unable to go back to sleep\n", dev->name); + +out: + return err; +} + +static int +typhoon_close(struct net_device *dev) +{ + struct typhoon *tp = (struct typhoon *) dev->priv; + + netif_stop_queue(dev); + + if(typhoon_stop_runtime(tp, WaitSleep) < 0) + printk(KERN_ERR "%s: unable to stop runtime\n", dev->name); + + /* Make sure there is no irq handler running on a different CPU. */ + typhoon_synchronize_irq(dev->irq); + free_irq(dev->irq, dev); + + typhoon_free_rx_rings(tp); + typhoon_init_rings(tp); + + if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) + printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name); + + if(typhoon_sleep(tp, 3, 0) < 0) + printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name); + + return 0; +} + +#if CONFIG_PM +static int +typhoon_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct typhoon *tp = (struct typhoon *) dev->priv; + + /* If we're down, resume when we are upped. + */ + if(!netif_running(dev)) + return 0; + + if(typhoon_wakeup(tp, WaitNoSleep) < 0) { + printk(KERN_ERR "%s: critical: could not wake up in resume\n", + dev->name); + goto reset; + } + + if(typhoon_start_runtime(tp) < 0) { + printk(KERN_ERR "%s: critical: could not start runtime in " + "resume\n", dev->name); + goto reset; + } + + netif_device_attach(dev); + netif_start_queue(dev); + return 0; + +reset: + typhoon_reset(dev->base_addr, NoWait); + return -EBUSY; +} + +static int +typhoon_suspend(struct pci_dev *pdev, u32 state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct typhoon *tp = (struct typhoon *) dev->priv; + struct cmd_desc xp_cmd; + + /* If we're down, we're already suspended. + */ + if(!netif_running(dev)) + return 0; + + spin_lock_bh(&tp->state_lock); + if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) { + spin_unlock_bh(&tp->state_lock); + printk(KERN_ERR "%s: cannot do WAKE_MAGIC with VLANS\n", + dev->name); + return -EBUSY; + } + spin_unlock_bh(&tp->state_lock); + + netif_device_detach(dev); + + if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) { + printk(KERN_ERR "%s: unable to stop runtime\n", dev->name); + goto need_resume; + } + + typhoon_free_rx_rings(tp); + typhoon_init_rings(tp); + + if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { + printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name); + goto need_resume; + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS); + xp_cmd.parm1 = cpu_to_le16(ntohs(*(u16 *)&dev->dev_addr[0])); + xp_cmd.parm2 = cpu_to_le32(ntohl(*(u32 *)&dev->dev_addr[2])); + if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) { + printk(KERN_ERR "%s: unable to set mac address in suspend\n", + dev->name); + goto need_resume; + } + + INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER); + xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST; + if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) { + printk(KERN_ERR "%s: unable to set rx filter in suspend\n", + dev->name); + goto need_resume; + } + + if(typhoon_sleep(tp, state, tp->wol_events) < 0) { + printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name); + goto need_resume; + } + + return 0; + +need_resume: + typhoon_resume(pdev); + return -EBUSY; +} + +static int +typhoon_enable_wake(struct pci_dev *pdev, u32 state, int enable) +{ + return pci_enable_wake(pdev, state, enable); +} +#endif + +static int __devinit +typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int did_version = 0; + struct net_device *dev; + struct typhoon *tp; + int card_id = (int) ent->driver_data; + unsigned long ioaddr; + void *shared; + dma_addr_t shared_dma; + struct cmd_desc xp_cmd; + struct resp_desc xp_resp; + int i; + int err = 0; + + if(!did_version++) + printk(KERN_INFO "%s", version); + + dev = alloc_etherdev(sizeof(*tp)); + if(dev == NULL) { + printk(ERR_PFX "%s: unable to alloc new net device\n", + pdev->slot_name); + err = -ENOMEM; + goto error_out; + } + SET_MODULE_OWNER(dev); + + err = pci_enable_device(pdev); + if(err < 0) { + printk(ERR_PFX "%s: unable to enable device\n", + pdev->slot_name); + goto error_out_dev; + } + + /* If we transitioned from D3->D0 in pci_enable_device(), + * we lost our configuration and need to restore it to the + * conditions at boot. + */ + pci_restore_state(pdev, NULL); + + err = pci_set_dma_mask(pdev, 0xffffffffULL); + if(err < 0) { + printk(ERR_PFX "%s: No usable DMA configuration\n", + pdev->slot_name); + goto error_out_dev; + } + + /* sanity checks, resource #1 is our mmio area + */ + if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { + printk(ERR_PFX + "%s: region #1 not a PCI MMIO resource, aborting\n", + pdev->slot_name); + err = -ENODEV; + goto error_out_dev; + } + if(pci_resource_len(pdev, 1) < 128) { + printk(ERR_PFX "%s: Invalid PCI MMIO region size, aborting\n", + pdev->slot_name); + err = -ENODEV; + goto error_out_dev; + } + + err = pci_request_regions(pdev, "typhoon"); + if(err < 0) { + printk(ERR_PFX "%s: could not request regions\n", + pdev->slot_name); + goto error_out_dev; + } + + pci_set_master(pdev); + pci_set_mwi(pdev); + + /* map our MMIO region + */ + ioaddr = pci_resource_start(pdev, 1); + ioaddr = (unsigned long) ioremap(ioaddr, 128); + if(!ioaddr) { + printk(ERR_PFX "%s: cannot remap MMIO, aborting\n", + pdev->slot_name); + err = -EIO; + goto error_out_regions; + } + dev->base_addr = ioaddr; + + /* allocate pci dma space for rx and tx descriptor rings + */ + shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared), + &shared_dma); + if(!shared) { + printk(ERR_PFX "%s: could not allocate DMA memory\n", + pdev->slot_name); + err = -ENOMEM; + goto error_out_remap; + } + + dev->irq = pdev->irq; + tp = dev->priv; + tp->shared = (struct typhoon_shared *) shared; + tp->shared_dma = shared_dma; + tp->pdev = pdev; + tp->tx_pdev = pdev; + tp->ioaddr = dev->base_addr; + tp->tx_ioaddr = dev->base_addr; + tp->dev = dev; + + /* need to be able to restore PCI state after a suspend */ + pci_save_state(pdev, tp->pci_state); + + /* Init sequence: + * 1) Reset the adapter to clear any bad juju + * 2) Reload the sleep image + * 3) Boot the sleep image + * 4) Get the hardware address. + * 5) Put the card to sleep. + */ + if(typhoon_reset(ioaddr, WaitSleep) < 0) { + printk(ERR_PFX "%s: could not reset 3XP\n", pdev->slot_name); + err = -EIO; + goto error_out_dma; + } + + /* dev->name is not valid until we register, but we need to + * use some common routines to initialize the card. So that those + * routines print the right name, we keep our oun pointer to the name + */ + tp->name = pdev->slot_name; + + typhoon_init_interface(tp); + typhoon_init_rings(tp); + + if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { + printk(ERR_PFX "%s: cannot boot 3XP sleep image\n", + pdev->slot_name); + err = -EIO; + goto error_out_reset; + } + + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS); + if(typhoon_issue_command(tp, 1, &xp_cmd, 1, &xp_resp) < 0) { + printk(ERR_PFX "%s: cannot read MAC address\n", + pdev->slot_name); + err = -EIO; + goto error_out_reset; + } + + *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp.parm1)); + *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp.parm2)); + + if(!is_valid_ether_addr(dev->dev_addr)) { + printk(ERR_PFX "%s: Could not obtain valid ethernet address, " + "aborting\n", pdev->slot_name); + goto error_out_reset; + } + + if(typhoon_sleep(tp, 3, 0) < 0) { + printk(ERR_PFX "%s: cannot put adapter to sleep\n", + pdev->slot_name); + err = -EIO; + goto error_out_reset; + } + + tp->capabilities = typhoon_card_info[card_id].capabilities; + tp->xcvr_select = TYPHOON_XCVR_AUTONEG; + + /* The chip-specific entries in the device structure. */ + dev->open = typhoon_open; + dev->hard_start_xmit = typhoon_start_tx; + dev->stop = typhoon_close; + dev->set_multicast_list = typhoon_set_rx_mode; + dev->tx_timeout = typhoon_tx_timeout; + dev->poll = typhoon_poll; + dev->weight = 16; + dev->watchdog_timeo = TX_TIMEOUT; + dev->get_stats = typhoon_get_stats; + dev->set_mac_address = typhoon_set_mac_address; + dev->do_ioctl = typhoon_ioctl; + dev->vlan_rx_register = typhoon_vlan_rx_register; + dev->vlan_rx_kill_vid = typhoon_vlan_rx_kill_vid; + + /* We can handle scatter gather, up to 16 entries, and + * we can do IP checksumming (only version 4, doh...) + */ + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->features |= NETIF_F_TSO; + + if(register_netdev(dev) < 0) + goto error_out_reset; + + /* fixup our local name */ + tp->name = dev->name; + + pci_set_drvdata(pdev, dev); + + printk(KERN_INFO "%s: %s at 0x%lx, ", + dev->name, typhoon_card_info[card_id].name, ioaddr); + for(i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x\n", dev->dev_addr[i]); + + return 0; + +error_out_reset: + typhoon_reset(ioaddr, NoWait); + +error_out_dma: + pci_free_consistent(pdev, sizeof(struct typhoon_shared), + shared, shared_dma); +error_out_remap: + iounmap((void *) ioaddr); +error_out_regions: + pci_release_regions(pdev); +error_out_dev: + kfree(dev); +error_out: + return err; +} + +static void __devexit +typhoon_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct typhoon *tp = (struct typhoon *) (dev->priv); + + unregister_netdev(dev); + pci_set_power_state(pdev, 0); + pci_restore_state(pdev, tp->pci_state); + typhoon_reset(dev->base_addr, NoWait); + iounmap((char *) (dev->base_addr)); + pci_free_consistent(pdev, sizeof(struct typhoon_shared), + tp->shared, tp->shared_dma); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + kfree(dev); +} + +static struct pci_driver typhoon_driver = { + .name = DRV_MODULE_NAME, + .id_table = typhoon_pci_tbl, + .probe = typhoon_init_one, + .remove = __devexit_p(typhoon_remove_one), +#if CONFIG_PM + .suspend = typhoon_suspend, + .resume = typhoon_resume, + .enable_wake = typhoon_enable_wake, +#endif +}; + +static int __init +typhoon_init(void) +{ + return pci_module_init(&typhoon_driver); +} + +static void __exit +typhoon_cleanup(void) +{ + pci_unregister_driver(&typhoon_driver); +} + +module_init(typhoon_init); +module_exit(typhoon_cleanup); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/typhoon-firmware.h linux.21pre4-ac6/drivers/net/typhoon-firmware.h --- linux.21pre4/drivers/net/typhoon-firmware.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/net/typhoon-firmware.h 2003-02-19 16:01:19.000000000 +0000 @@ -0,0 +1,4108 @@ +/* + * Copyright 1999-2002 3Com Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms of the 3CR990img.h + * microcode software are permitted provided that the following conditions + * are met: + * 1. Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of 3Com may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY 3COM ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3CR990img.h + * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY + * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS + * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) + * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN + * COMBINATION WITH THE 3CR990img.h microcode SOFTWARE + */ +const u8 typhoon_firmware_image[] = { +0x54, 0x59, 0x50, 0x48, 0x4f, 0x4f, 0x4e, 0x00, 0x02, 0x00, 0x00, 0x00, +0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x40, 0x01, 0x00, 0x00, +0x6c, 0xef, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, +0x05, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, +0x02, 0x00, 0x00, 0xea, 0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, +0xa5, 0x14, 0x00, 0xea, 0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, +0x00, 0x10, 0x0f, 0xe1, 0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, +0xfe, 0xff, 0xff, 0xea, 0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, +0x01, 0x00, 0x50, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, +0x00, 0xa0, 0xa0, 0xe1, 0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, +0xa8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, +0x00, 0x00, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, +0x01, 0x00, 0x80, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x6c, 0xd0, 0x9f, 0xe5, 0x7b, 0x14, 0x00, 0xeb, +0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, +0x60, 0x00, 0x9f, 0xe5, 0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, +0xdb, 0xff, 0xff, 0xeb, 0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, +0x00, 0x20, 0xa0, 0xe3, 0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, +0x54, 0x10, 0x9f, 0xe5, 0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, +0x0b, 0xf0, 0xa0, 0xe1, 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, +0xd4, 0xff, 0xff, 0xeb, 0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, +0xc6, 0xff, 0xff, 0xea, 0xbd, 0x20, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, +0x1c, 0x00, 0x10, 0x00, 0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, +0xfc, 0x3f, 0x00, 0x80, 0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, +0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 0xa8, 0xbc, 0x00, 0x00, +0x24, 0xab, 0x20, 0x40, 0x34, 0x29, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, +0x6d, 0xc8, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xd8, 0x56, 0x00, 0x00, 0x06, 0x24, 0x00, 0x00, +0x60, 0x01, 0xff, 0xff, 0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x00, 0x25, +0xe0, 0x6b, 0x00, 0x28, 0x1d, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, +0x37, 0xfd, 0xe1, 0x6b, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x14, 0xd0, +0x38, 0x01, 0x0d, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, +0x41, 0x6b, 0x80, 0x29, 0x0b, 0xd2, 0x01, 0x31, 0x41, 0x63, 0xe0, 0x6b, +0xc1, 0x69, 0xc0, 0x46, 0xe1, 0x63, 0x39, 0x07, 0x41, 0x60, 0xc7, 0x62, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x1c, 0xfa, 0xe7, 0x00, 0x00, +0x28, 0x17, 0x00, 0x80, 0xee, 0x05, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, +0x02, 0x49, 0xca, 0x6b, 0xc0, 0x46, 0xc2, 0x61, 0xc8, 0x63, 0x70, 0x47, +0x28, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, +0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, +0x00, 0x10, 0xa0, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, +0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, +0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, +0x40, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, +0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, +0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, +0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, +0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, +0x91, 0x00, 0x00, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, +0x01, 0x00, 0x80, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, +0x64, 0x28, 0x04, 0xd3, 0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, +0x03, 0xe0, 0x38, 0x63, 0x04, 0x49, 0x05, 0xf0, 0xc1, 0xfa, 0x78, 0x63, +0xb8, 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0x88, 0x13, 0x00, 0x00, 0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, +0x64, 0x2f, 0x03, 0xd2, 0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, +0x10, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, +0xbb, 0x42, 0x05, 0xd2, 0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, +0xc8, 0x63, 0xf1, 0xe7, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, +0x04, 0x48, 0xc1, 0x6b, 0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, +0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, +0x90, 0xb5, 0x07, 0x1c, 0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, +0x0b, 0xd2, 0xb9, 0x6e, 0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, +0x91, 0x42, 0x07, 0xd2, 0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, +0x21, 0x64, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, +0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xe7, 0xfd, 0x38, 0x1c, +0x02, 0xf0, 0xa4, 0xfa, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, +0xc8, 0x72, 0x05, 0x49, 0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, +0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0xe4, 0xe7, 0xe8, 0x0d, 0x00, 0x80, +0x78, 0x2a, 0x00, 0x80, 0x10, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, +0xc0, 0x6d, 0x02, 0x23, 0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, +0x03, 0xd0, 0xd1, 0x63, 0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, +0x07, 0x68, 0x7b, 0x1c, 0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, +0xf3, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, +0x60, 0x01, 0x00, 0x80, 0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, +0x10, 0x18, 0x0a, 0x04, 0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, +0x01, 0x0c, 0x05, 0xd0, 0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, +0x01, 0x0c, 0xf9, 0xd1, 0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, +0x00, 0x22, 0x00, 0x29, 0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f, +0x06, 0xd0, 0x07, 0x88, 0xba, 0x18, 0x02, 0x30, 0x1f, 0x1c, 0x01, 0x3b, +0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, +0x00, 0x88, 0x00, 0x06, 0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, +0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, +0x10, 0x04, 0x00, 0x0c, 0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, +0xc7, 0x89, 0xfb, 0x18, 0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, +0x40, 0x7a, 0x00, 0x02, 0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, +0x00, 0x0c, 0x3b, 0x0c, 0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, +0x11, 0x1c, 0xff, 0xf7, 0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, +0xb0, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, +0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, +0x93, 0x69, 0x01, 0x33, 0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, +0x00, 0x68, 0x1c, 0x18, 0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, +0xac, 0xff, 0xc0, 0x43, 0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, +0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, +0x52, 0x09, 0x0e, 0xd3, 0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, +0xcb, 0x68, 0x02, 0x68, 0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, +0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, +0x90, 0xb5, 0x80, 0x23, 0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, +0x15, 0xd0, 0x4a, 0x68, 0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, +0x01, 0x33, 0xd3, 0x61, 0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, +0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, +0x00, 0x28, 0x00, 0xd1, 0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, +0xff, 0xff, 0x00, 0x00, 0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, +0x38, 0x69, 0xb9, 0x68, 0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, +0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, +0x04, 0x1c, 0xb8, 0x68, 0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, +0x0c, 0xd2, 0x2a, 0x68, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, +0x05, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, +0x26, 0xff, 0x04, 0x1c, 0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, +0x1a, 0xd3, 0xb8, 0x6a, 0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, +0xed, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, +0x20, 0x23, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, +0x01, 0x63, 0x07, 0xe0, 0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, +0xb9, 0x61, 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, +0xb8, 0x6b, 0x41, 0x09, 0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, +0x39, 0x30, 0x00, 0x7b, 0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, +0x53, 0xf8, 0x01, 0x1c, 0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69, +0x19, 0x43, 0xb9, 0x61, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x07, 0xe0, +0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, +0xb9, 0x61, 0xc1, 0x6a, 0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, +0xb8, 0x6b, 0x81, 0x09, 0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, +0x39, 0x30, 0x00, 0x7b, 0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, +0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, +0x05, 0x04, 0x2d, 0x0c, 0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, +0x1f, 0xf8, 0x00, 0x28, 0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, +0x98, 0x42, 0x07, 0xd0, 0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, +0x60, 0x6b, 0x01, 0x30, 0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, +0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, +0x00, 0x20, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, +0xff, 0xff, 0x00, 0x00, 0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, +0xe0, 0x6b, 0x61, 0x6c, 0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, +0x00, 0x20, 0x8a, 0x08, 0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, +0x9f, 0x58, 0x03, 0xae, 0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, +0xf7, 0xd8, 0x60, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, +0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, +0xff, 0xf7, 0x87, 0xfe, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, +0xff, 0xf7, 0x6d, 0xfe, 0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, +0x61, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, +0xc0, 0x46, 0x01, 0x91, 0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, +0x0c, 0xd2, 0xa2, 0x6a, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, +0x2f, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, +0x50, 0xfe, 0x07, 0x1c, 0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, +0x08, 0x18, 0x69, 0x8a, 0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, +0xa1, 0x6c, 0x62, 0x6c, 0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, +0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, +0x05, 0xd0, 0x08, 0x04, 0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, +0xf9, 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, +0x00, 0x0c, 0x7f, 0xb0, 0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xb0, 0xb4, 0x00, 0x22, 0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, +0xdc, 0x00, 0x47, 0x18, 0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, +0xff, 0x00, 0x80, 0x08, 0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, +0x4d, 0x1e, 0x02, 0xc8, 0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, +0x09, 0xd0, 0x0c, 0x04, 0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, +0x02, 0xc8, 0x1c, 0x1c, 0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, +0x08, 0x1c, 0xf8, 0x40, 0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, +0x42, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, +0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, +0x70, 0x47, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, +0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23, +0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x03, 0x1b, 0x0b, 0x8a, 0x58, +0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, +0x01, 0x30, 0x04, 0x28, 0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, +0x09, 0x0b, 0x07, 0x48, 0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, +0x02, 0xd0, 0x38, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, +0x28, 0x03, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 0xe8, 0x0d, 0x00, 0x80, +0x98, 0xb4, 0x14, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, +0xc0, 0x58, 0x07, 0x03, 0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, +0x12, 0x0b, 0x11, 0x48, 0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, +0xe4, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, +0xcc, 0x00, 0x01, 0x21, 0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, +0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, +0x18, 0x1a, 0x84, 0x42, 0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, +0x55, 0x55, 0x55, 0x55, 0xa0, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, +0x88, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, +0x00, 0xd0, 0x01, 0x3a, 0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, +0xc0, 0x46, 0x3b, 0x60, 0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, +0x08, 0x32, 0x10, 0x4b, 0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, +0x12, 0x58, 0x0f, 0x4b, 0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, +0x1b, 0x68, 0x9b, 0x00, 0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, +0x0a, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, +0x70, 0x47, 0x08, 0x4b, 0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, +0x00, 0x20, 0xf6, 0xe7, 0x88, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, +0xa0, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x90, 0x03, 0x00, 0x80, 0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, +0x01, 0xb6, 0xa0, 0xe3, 0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, +0x01, 0x7a, 0xa0, 0xe3, 0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, +0xc8, 0x60, 0x9f, 0xe5, 0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, +0x00, 0x00, 0x54, 0xe3, 0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, +0x11, 0x00, 0x00, 0x0a, 0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, +0x21, 0x00, 0x00, 0x0a, 0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, +0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, +0x1c, 0x00, 0x85, 0xe5, 0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, +0x02, 0x0a, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, +0x02, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, +0x14, 0x80, 0x85, 0xe5, 0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, +0x1c, 0x00, 0x96, 0xe5, 0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, +0x1c, 0x00, 0x85, 0xe5, 0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, +0x40, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, +0x02, 0x0b, 0x14, 0xe3, 0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, +0x20, 0x00, 0x00, 0x1b, 0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, +0x18, 0x00, 0x89, 0xe5, 0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, +0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, +0x14, 0x70, 0x85, 0xe5, 0xe1, 0xff, 0xff, 0xea, 0xff, 0x5f, 0xbd, 0xe8, +0x04, 0xf0, 0x5e, 0xe2, 0xe8, 0x0d, 0x00, 0x80, +0x08, 0x83, 0x20, 0x40, 0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, +0x00, 0x20, 0xc3, 0xe1, 0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, +0x0c, 0x20, 0x81, 0xe5, 0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, +0x18, 0x10, 0x9f, 0xe5, 0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, +0xb0, 0x24, 0xc1, 0xe1, 0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, +0x3c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, +0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, +0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, +0x24, 0x20, 0x91, 0xe5, 0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x24, 0x20, 0x80, 0xe5, 0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x28, 0x10, 0x80, 0xe5, 0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, +0x2c, 0x20, 0x80, 0xe5, 0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, +0x1e, 0xff, 0x2f, 0x11, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, +0x01, 0x10, 0x81, 0xe2, 0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, +0x0b, 0x02, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0xb0, 0x03, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, +0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, +0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, +0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, +0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, +0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, +0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, +0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, +0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, +0x0c, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, +0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, +0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, +0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, +0x4c, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, +0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, +0x01, 0x06, 0xa0, 0xe3, 0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0x80, 0x21, 0x1f, 0xe5, 0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x80, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x81, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, +0x01, 0x06, 0xa0, 0xe3, 0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, +0x1c, 0x10, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, +0x1e, 0xff, 0x2f, 0xe1, 0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x1c, 0x10, 0x82, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, +0x0c, 0x00, 0x81, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x1c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, +0x38, 0x1c, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, +0x00, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, +0x09, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x68, 0xf8, +0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, +0x3a, 0x78, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, +0xff, 0x22, 0x01, 0x32, 0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, +0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, +0x5b, 0x02, 0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, +0x82, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, +0x1a, 0x43, 0x08, 0x2a, 0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, +0x41, 0x60, 0x81, 0x68, 0x0e, 0x31, 0x2c, 0xe0, 0x13, 0x02, 0x12, 0x0a, +0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x2e, 0x3a, +0x16, 0x4b, 0x9a, 0x42, 0x24, 0xd8, 0x01, 0x25, 0x42, 0x68, 0x15, 0x43, +0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x12, 0x4b, +0x9a, 0x42, 0x19, 0xd1, 0xfb, 0x1d, 0x09, 0x33, 0x44, 0xcb, 0x9b, 0x07, +0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33, 0x9e, 0x40, 0x16, 0x43, +0x03, 0x2e, 0x0f, 0xd1, 0x39, 0x7d, 0x7b, 0x7d, 0x1b, 0x02, 0x19, 0x43, +0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43, 0x41, 0x60, 0x81, 0x68, +0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x01, 0xe0, 0x00, 0x21, 0x84, 0x60, +0x08, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xae, 0x05, 0x00, 0x00, +0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68, 0xd1, 0x08, 0x3f, 0xd3, +0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39, 0x8f, 0x78, 0x3f, 0x07, +0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d, 0x0d, 0x32, 0xc2, 0x60, +0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60, 0x08, 0x23, 0x1a, 0x43, +0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f, 0x92, 0x00, 0x02, 0x61, +0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, +0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x61, +0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23, 0x42, 0x68, 0x1a, 0x43, +0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23, 0x42, 0x68, 0x1a, 0x43, +0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23, 0x42, 0x68, 0x1a, 0x43, +0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23, 0x42, 0x68, 0x1a, 0x43, +0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76, 0x80, 0xbc, 0x70, 0x47, +0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78, 0x1b, 0x02, 0x1a, 0x43, +0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43, 0x02, 0x60, 0xc9, 0x78, +0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x07, 0x1c, +0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a, 0xc9, 0x68, 0x40, 0x18, +0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, +0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42, 0x18, 0xd1, 0x78, 0x6a, +0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xb0, 0xf8, +0x38, 0x1c, 0x01, 0xf0, 0x6d, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, +0xc8, 0x72, 0x07, 0x49, 0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, +0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x20, 0xfa, 0xe7, 0x98, 0x19, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, +0x10, 0x2a, 0x00, 0x80, 0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, +0x01, 0x23, 0x9b, 0x07, 0x01, 0x1d, 0x18, 0x43, +0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02, 0x12, 0x0e, 0x12, 0x06, +0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40, 0x10, 0x43, 0x0a, 0x0a, +0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02, 0x1b, 0x0a, 0x19, 0x40, +0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, +0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04, 0x1a, 0x40, 0x11, 0x43, +0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43, 0x00, 0x0e, 0x08, 0x43, +0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23, 0x81, 0x6b, 0x19, 0x40, +0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d, 0x39, 0x37, 0x39, 0x7b, +0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1, 0x01, 0x6b, 0xc0, 0x46, +0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d, 0x2d, 0x35, 0x00, 0x22, +0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50, 0x01, 0x32, 0x07, 0x2a, +0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63, 0x82, 0x6a, 0xc0, 0x46, +0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33, 0x5a, 0x83, 0x40, 0x6a, +0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27, 0x42, 0x68, 0x00, 0x2a, +0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1, 0x42, 0x69, 0x00, 0x2a, +0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a, 0x02, 0x29, 0x02, 0xd3, +0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0, 0x13, 0xf8, 0x09, 0xe0, +0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x03, 0xe0, +0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61, 0x38, 0x1c, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0xec, 0x05, 0x00, 0x80, +0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68, 0x00, 0x2b, 0x34, 0xd0, +0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68, 0x9b, 0x6a, 0xc0, 0x46, +0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19, 0x7f, 0x02, 0x17, 0x4b, +0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63, 0x07, 0x63, 0xcb, 0x1d, +0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69, 0x00, 0x2b, 0x01, 0xd0, +0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61, 0x0f, 0x1c, 0xc9, 0x68, +0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63, 0xf8, 0x1d, 0xff, 0x30, +0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60, 0xc2, 0x60, 0x38, 0x1c, +0x00, 0xf0, 0xc4, 0xfa, 0x38, 0x6a, 0x01, 0x30, 0x38, 0x62, 0x38, 0x1c, +0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, +0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, +0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31, 0x88, 0x6a, 0xc2, 0x1d, +0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32, 0x1a, 0x43, 0xc8, 0x6a, +0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18, 0x82, 0x79, 0xc3, 0x79, +0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, +0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38, 0x92, 0x04, 0x92, 0x0c, +0x00, 0x26, 0x25, 0x4d, 0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, +0x04, 0xd0, 0x20, 0x8a, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, +0x01, 0x23, 0x9b, 0x07, 0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, +0x12, 0x04, 0x12, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, +0x10, 0x43, 0x03, 0x1c, 0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, +0xc8, 0x6b, 0x19, 0x1c, 0x01, 0xf0, 0xd8, 0xff, 0x00, 0x28, 0x04, 0xda, +0x20, 0x8a, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, +0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x08, 0x60, 0x01, 0x04, +0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8, 0x00, 0x28, 0x14, 0xd1, +0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43, 0x20, 0x82, 0x21, 0x8a, +0x38, 0x1c, 0x00, 0xf0, 0x98, 0xfb, 0xe8, 0x68, 0x01, 0x23, 0x9b, 0x07, +0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xe8, 0x60, 0x30, 0x1c, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0xfa, 0xe7, 0x00, 0x00, +0xec, 0x05, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0xfc, 0x1d, 0xf9, 0x34, +0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35, 0x33, 0x48, 0xc0, 0x6a, +0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18, 0x01, 0x20, 0x80, 0x07, +0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x90, 0x01, 0x23, +0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43, 0x00, 0x68, 0x38, 0x1c, +0x29, 0x1c, 0x00, 0xf0, 0xb8, 0xfa, 0xa8, 0x88, 0x40, 0x07, 0x01, 0xd0, +0x00, 0x20, 0x47, 0xe0, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a, +0xf1, 0x6b, 0x40, 0x18, 0x71, 0x6c, 0xfa, 0x1d, 0xcd, 0x32, 0x01, 0xf0, +0x2b, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69, +0x40, 0x18, 0xc3, 0x1d, 0x03, 0x33, 0x00, 0x20, 0x81, 0x00, 0x5e, 0x58, +0xc9, 0x19, 0xff, 0x31, 0x01, 0x31, 0x4e, 0x61, 0x01, 0x30, 0x04, 0x28, +0xf6, 0xd3, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, +0x00, 0x20, 0x00, 0x22, 0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, +0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xd4, 0xfb, +0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 0x01, 0x20, 0x21, 0x6b, +0xff, 0xf7, 0xcc, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, +0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0xc4, 0xfb, 0xa1, 0x6b, 0x08, 0x4a, +0x01, 0x20, 0xff, 0xf7, 0xbf, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46, +0x48, 0x62, 0x01, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xc8, 0x29, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00, +0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a, +0xd5, 0x1d, 0xf9, 0x35, 0x68, 0x62, 0x01, 0x20, 0x00, 0x05, 0xb3, 0x49, +0xc0, 0x46, 0x08, 0x60, 0xa8, 0x6a, 0xc4, 0x1d, 0x2d, 0x34, 0xb1, 0x48, +0xc0, 0x6a, 0xd7, 0x1d, 0xff, 0x37, 0x3a, 0x37, 0x39, 0x68, 0x4b, 0x00, +0x59, 0x18, 0x49, 0x01, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, +0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, +0xc0, 0x46, 0x09, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x00, 0x0a, +0x0a, 0x90, 0x0a, 0x98, 0xa4, 0x4e, 0x01, 0x28, 0x59, 0xd1, 0x28, 0x6b, +0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69, 0x09, 0x04, 0x09, 0x0c, +0x01, 0xf0, 0x1e, 0xf9, 0x28, 0x6b, 0x79, 0x69, 0x40, 0x18, 0xc1, 0x1d, +0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b, 0xd3, 0x18, 0xff, 0x33, +0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50, 0x01, 0x30, 0x04, 0x28, +0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, +0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, 0xb3, 0x50, 0x01, 0x30, +0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90, 0x90, 0x49, 0x42, 0x00, +0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0, 0x8e, 0x48, 0xc1, 0x89, +0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28, +0x03, 0xd1, 0x38, 0x8a, 0x10, 0x23, 0x18, 0x43, 0x71, 0xe0, 0x38, 0x8a, +0x40, 0x23, 0x18, 0x43, 0x6d, 0xe0, 0x00, 0xf0, 0x11, 0xf9, 0x01, 0xf0, +0x47, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98, +0x00, 0x28, 0x0c, 0xd1, 0xb8, 0x68, 0x41, 0x1c, 0xb9, 0x60, 0x00, 0x28, +0x03, 0xd1, 0x38, 0x8a, 0x01, 0x23, 0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, +0x04, 0x23, 0x18, 0x43, 0x38, 0x82, 0x78, 0x68, 0x01, 0x30, 0x78, 0x60, +0x62, 0xe0, 0x0a, 0x98, 0x02, 0x28, 0x5f, 0xd1, 0x09, 0x98, 0x40, 0x0c, +0x73, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, +0x00, 0x68, 0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, +0x0c, 0x38, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x8a, 0x00, 0x6b, 0x4b, +0xd6, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, +0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 0x00, 0x21, 0x83, 0x1e, +0x0c, 0x93, 0x68, 0x4a, 0x16, 0x6b, 0xc0, 0x46, 0x0b, 0x96, 0x8a, 0x00, +0x0c, 0x9b, 0x9b, 0x18, 0x0b, 0x9e, 0x9e, 0x19, 0x01, 0x23, 0x9b, 0x07, +0x33, 0x43, 0x1b, 0x68, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x04, 0x29, +0xf1, 0xd3, 0x69, 0x46, 0x8b, 0x1c, 0x07, 0x93, 0x00, 0x21, 0x08, 0x91, +0x04, 0xae, 0x4a, 0x00, 0x07, 0x9b, 0x9b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, +0x11, 0xd0, 0x58, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xf8, 0x68, +0x41, 0x1c, 0xf9, 0x60, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x8a, 0x20, 0x23, +0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 0x80, 0x23, 0x18, 0x43, 0x38, 0x82, +0x8f, 0xe7, 0x01, 0x31, 0x06, 0x29, 0xe4, 0xd3, 0x08, 0x99, 0x00, 0x29, +0x0d, 0xd1, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0x04, 0xd1, +0x39, 0x8a, 0x02, 0x23, 0x19, 0x43, 0x03, 0xe0, 0x0c, 0xe0, 0x39, 0x8a, +0x08, 0x23, 0x19, 0x43, 0x39, 0x82, 0x29, 0x6b, 0x08, 0x18, 0x01, 0x23, +0x9b, 0x07, 0x01, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x20, 0x76, +0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x11, 0x30, 0x18, 0x43, 0x00, 0x68, +0x01, 0x06, 0x09, 0x0e, 0x00, 0xe0, 0x19, 0xe0, 0x35, 0x48, 0x2a, 0x6b, +0xc0, 0x46, 0xea, 0x62, 0x04, 0x29, 0x4f, 0xd1, 0x01, 0x21, 0xc6, 0x1d, +0xff, 0x36, 0x5a, 0x36, 0x31, 0x72, 0x0a, 0x99, 0x02, 0x29, 0x1e, 0xd1, +0x09, 0x99, 0x09, 0x0e, 0x49, 0x06, 0x1a, 0xd1, 0xe1, 0x1d, 0x05, 0x31, +0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x39, 0x1a, 0xe0, +0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, +0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 0x00, 0x04, +0x00, 0x0c, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0xbc, 0xd1, +0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d, 0x05, 0x31, 0x19, 0x43, +0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60, 0xe8, 0x6a, 0xc0, 0x46, +0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfc, 0x20, 0x7e, 0x33, 0x28, +0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21, 0x14, 0x4c, 0xc0, 0x46, +0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x85, 0xf8, 0x28, 0x6b, +0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c, 0xff, 0xf7, 0xca, 0xfd, +0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20, 0x30, 0x72, 0x11, 0xe0, +0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1, 0x07, 0x1c, 0x00, 0xf0, +0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xba, 0xfd, +0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x50, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0, 0x12, 0xf8, 0xf6, 0xe7, 0x00, 0x00, +0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x29, 0x00, 0x80, +0x1c, 0xad, 0x20, 0x40, 0xc0, 0x06, 0x00, 0x80, 0x02, 0x07, 0x00, 0x80, +0x78, 0x2a, 0x00, 0x80, 0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48, +0x41, 0x68, 0x01, 0x31, 0x41, 0x60, 0x24, 0x4f, 0xf9, 0x1d, 0xf9, 0x31, +0x00, 0x24, 0x88, 0x6a, 0xfa, 0x68, 0xc0, 0x46, 0x94, 0x61, 0x04, 0x22, +0xfb, 0x68, 0xc0, 0x46, 0xda, 0x60, 0x10, 0x22, 0xfb, 0x68, 0xc0, 0x46, +0x9a, 0x61, 0xfa, 0x1d, 0xff, 0x32, 0x5a, 0x32, 0x13, 0x7a, 0x1b, 0x4a, +0x00, 0x2b, 0x0b, 0xd0, 0x15, 0x8a, 0x2e, 0x0a, 0x36, 0x02, 0x33, 0x23, +0x2b, 0x40, 0x9b, 0x00, 0x1e, 0x43, 0xcc, 0x23, 0x2b, 0x40, 0x9b, 0x08, +0x33, 0x43, 0x13, 0x82, 0x12, 0x8a, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x83, +0x4a, 0x6b, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x81, 0x0a, 0x6b, 0xc0, 0x46, +0x82, 0x62, 0xc4, 0x62, 0xc3, 0x1d, 0x39, 0x33, 0x4a, 0x6b, 0xc0, 0x46, +0x5a, 0x83, 0x04, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 0x88, 0x6a, +0x01, 0xf0, 0x14, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, +0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x60, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, +0x2c, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a, +0x01, 0x23, 0x9b, 0x07, 0xd1, 0x1d, 0x45, 0x31, 0x19, 0x43, 0x09, 0x68, +0x0b, 0x06, 0x1b, 0x0e, 0x01, 0x27, 0xc1, 0x1d, 0xff, 0x31, 0x4a, 0x31, +0x33, 0x2b, 0x05, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 0x10, 0x1c, 0x00, 0xf0, +0x0f, 0xf8, 0x06, 0xe0, 0x32, 0x2b, 0x08, 0xd1, 0x8b, 0x70, 0x01, 0x1c, +0x10, 0x1c, 0x00, 0xf0, 0x3c, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x20, 0x88, 0x70, 0xf9, 0xe7, 0x90, 0xb4, 0xca, 0x1d, +0xf9, 0x32, 0x33, 0x27, 0xcc, 0x1d, 0xff, 0x34, 0x4a, 0x34, 0xd3, 0x6a, +0xc0, 0x46, 0xa7, 0x70, 0xff, 0x31, 0x41, 0x31, 0x07, 0x6c, 0xc0, 0x46, +0x4f, 0x61, 0xfb, 0x18, 0x39, 0x1c, 0x9f, 0x1e, 0x01, 0x23, 0x9b, 0x07, +0xfc, 0x1c, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x9b, 0x00, +0x1b, 0x04, 0x1b, 0x0c, 0xc9, 0x18, 0x08, 0x31, 0x01, 0x64, 0x01, 0x23, +0x9b, 0x07, 0xb9, 0x1c, 0x19, 0x43, 0x09, 0x68, 0x34, 0x30, 0x01, 0x76, +0xf8, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1d, +0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, +0xd0, 0x63, 0x90, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xca, 0x1d, 0xf9, 0x32, +0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d, 0xff, 0x37, 0x4a, 0x37, +0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d, 0xff, 0x34, 0x3a, 0x34, +0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30, 0xe8, 0x60, 0x60, 0x69, +0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07, 0x38, 0x1d, 0x18, 0x43, +0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, +0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, 0xf8, 0x1d, 0x03, 0x30, +0xff, 0xf7, 0x06, 0xfc, 0x20, 0x62, 0xf8, 0x1d, 0x07, 0x30, 0xff, 0xf7, +0x01, 0xfc, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98, +0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, +0x05, 0x34, 0x23, 0x43, 0x1c, 0x68, 0xff, 0x23, 0xfe, 0x33, 0x23, 0x40, +0x7f, 0x6b, 0x3f, 0x04, 0x3b, 0x43, 0x0b, 0x60, 0x34, 0x30, 0x1c, 0x1c, +0x80, 0x23, 0x23, 0x40, 0x01, 0x9f, 0xff, 0x37, 0x41, 0x37, 0x00, 0x2b, +0x3c, 0xd0, 0x0c, 0x23, 0x00, 0x93, 0x00, 0x23, 0x9d, 0x00, 0xae, 0x18, +0x36, 0x69, 0x6d, 0x18, 0x6e, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, +0x00, 0x23, 0x9d, 0x00, 0xae, 0x18, 0x76, 0x6a, 0x6d, 0x18, 0xae, 0x62, +0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 0x01, 0x9b, 0xff, 0x33, 0x51, 0x33, +0x9b, 0x78, 0x33, 0x2b, 0x0e, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d, +0x01, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23, +0x9b, 0x07, 0xc5, 0x1d, 0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x16, 0xe0, +0x7b, 0x69, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d, +0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x7d, 0x69, 0x5d, 0x1b, 0x01, 0x23, +0x9b, 0x07, 0xc6, 0x1d, 0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0xeb, 0x18, +0x0c, 0x3b, 0x02, 0xe0, 0x00, 0x23, 0x00, 0x93, 0x4b, 0x81, 0xcb, 0x80, +0x63, 0x09, 0x49, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xc4, 0x1d, 0x05, 0x34, +0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x81, 0x01, 0x23, 0x9b, 0x07, +0xc4, 0x1d, 0x0d, 0x34, 0x23, 0x43, 0x1b, 0x68, 0x0c, 0x89, 0x1b, 0x1b, +0x00, 0x9c, 0x1c, 0x1b, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, +0x00, 0x68, 0x20, 0x18, 0x88, 0x80, 0x38, 0x6a, 0x04, 0x0e, 0xff, 0x23, +0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a, 0x1c, 0x43, 0xff, 0x23, 0x1b, 0x02, +0x03, 0x40, 0x1b, 0x02, 0x23, 0x43, 0x00, 0x06, 0x18, 0x43, 0xc8, 0x60, +0x78, 0x6a, 0x07, 0x0e, 0xff, 0x23, 0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a, +0x1f, 0x43, 0xff, 0x23, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x3b, 0x43, +0x00, 0x06, 0x18, 0x43, 0x08, 0x61, 0xd0, 0x6b, 0xc0, 0x46, 0xc8, 0x63, +0x90, 0x6b, 0xc0, 0x46, 0x08, 0x64, 0x50, 0x6c, 0xc0, 0x46, 0x48, 0x64, +0x10, 0x6c, 0xc0, 0x46, 0x88, 0x64, 0xd0, 0x6c, 0xc0, 0x46, 0xc8, 0x64, +0x90, 0x6c, 0xc0, 0x46, 0x08, 0x65, 0x02, 0xe0, 0x00, 0x23, 0x0b, 0x81, +0x8b, 0x80, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0x0f, 0x4a, 0x93, 0x89, 0x01, 0x33, 0x93, 0x81, 0xc2, 0x1d, 0xf9, 0x32, +0x04, 0x23, 0x90, 0x6a, 0xc0, 0x46, 0xc3, 0x60, 0x10, 0x23, 0x83, 0x61, +0xcb, 0x0a, 0x01, 0xd3, 0x18, 0x23, 0x83, 0x61, 0xc1, 0x83, 0x51, 0x6b, +0xc0, 0x46, 0xc1, 0x81, 0x51, 0x6b, 0xc2, 0x1d, 0x39, 0x32, 0x51, 0x83, +0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xa4, 0xf8, +0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x1b, 0x4c, +0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20, 0xe7, 0x1d, 0x19, 0x37, +0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30, 0x00, 0x29, 0x15, 0xd0, +0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25, 0x0a, 0xe0, 0xff, 0xf7, +0x93, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a, 0x02, 0x28, 0x00, 0xd3, +0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, +0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x6a, 0x00, 0x28, +0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69, 0x00, 0x28, 0x04, 0xd0, +0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0x8e, 0xfc, +0xef, 0xe7, 0x60, 0x68, 0x00, 0x28, 0xec, 0xd0, 0x00, 0xf0, 0x50, 0xf8, +0xe9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xb4, 0x03, 0x00, 0x80, +0xb0, 0xb5, 0x07, 0x1c, 0x20, 0x23, 0xb8, 0x68, 0x18, 0x40, 0x00, 0x25, +0x00, 0x28, 0x03, 0xd1, 0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xc4, 0x23, 0x48, 0x68, 0x18, 0x40, 0x01, 0x24, 0x00, 0x28, 0x03, 0xd1, +0x38, 0x6a, 0x00, 0xf0, 0x0d, 0xfc, 0x2f, 0xe0, 0x38, 0x1c, 0x00, 0xf0, +0x1d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x7e, 0xfa, 0xb8, 0x68, 0xc0, 0x08, +0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xd2, 0xfb, 0xb8, 0x68, 0x39, 0x6a, +0xc0, 0x46, 0x88, 0x60, 0x38, 0x6a, 0xc0, 0x46, 0xc5, 0x60, 0x0f, 0x48, +0x41, 0x68, 0x00, 0x29, 0x11, 0xd1, 0xc1, 0x68, 0x00, 0x29, 0x09, 0xd1, +0x41, 0x69, 0x00, 0x29, 0x06, 0xd1, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, +0x41, 0x60, 0x00, 0xf0, 0x11, 0xf8, 0x0b, 0xe0, 0x39, 0x6a, 0xc0, 0x46, +0x81, 0x60, 0x41, 0x60, 0x06, 0xe0, 0x39, 0x6a, 0x82, 0x68, 0xc0, 0x46, +0xd1, 0x60, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x20, 0x1c, 0xc0, 0xe7, +0xec, 0x05, 0x00, 0x80, 0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, +0x0f, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x28, 0x0a, 0xd1, +0x60, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x60, 0x60, 0x38, 0x1c, 0x00, 0xf0, +0xc7, 0xfb, 0x00, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, +0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, +0xfe, 0x1d, 0x49, 0x36, 0x30, 0x78, 0x40, 0x00, 0xc0, 0x19, 0x85, 0x8b, +0x2d, 0x4b, 0x9d, 0x42, 0x56, 0xd0, 0x2d, 0x4c, 0x38, 0x1c, 0x21, 0x1c, +0x2a, 0x1c, 0x00, 0xf0, 0x23, 0xf9, 0xa0, 0x88, 0x40, 0x07, 0x4d, 0xd1, +0x29, 0x48, 0x80, 0x6a, 0x58, 0x21, 0x69, 0x43, 0x40, 0x18, 0x01, 0x23, +0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x25, 0x4d, +0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 0xc0, 0x19, 0xc1, 0x1d, 0x19, 0x31, +0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x09, 0x7b, 0xea, 0x1d, 0x21, 0x32, +0x00, 0xf0, 0xe2, 0xfc, 0x30, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, +0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x00, 0x22, +0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, 0xfa, 0xd3, 0x21, 0x1c, +0x16, 0x4a, 0x00, 0x20, 0xfe, 0xf7, 0x9a, 0xff, 0x01, 0x22, 0x52, 0x04, +0x78, 0x68, 0x02, 0x43, 0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x92, 0xff, +0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, +0xfe, 0xf7, 0x8a, 0xff, 0x0d, 0x49, 0x0e, 0x4a, 0x01, 0x20, 0xfe, 0xf7, +0x85, 0xff, 0x01, 0x20, 0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, +0xea, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x20, 0xfa, 0xe7, 0xff, 0xff, 0x00, 0x00, 0x98, 0xad, 0x20, 0x40, +0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, +0x84, 0xad, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 0xf0, 0xb5, 0x83, 0xb0, +0x00, 0x21, 0x58, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0x01, 0x21, +0xc9, 0x04, 0x56, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0xc1, 0x1d, 0x19, 0x31, +0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x53, 0x48, 0x00, 0x68, 0x03, 0xf0, +0x97, 0xfb, 0x98, 0xe0, 0x4e, 0x48, 0x47, 0x68, 0xfc, 0x1d, 0x49, 0x34, +0x22, 0x78, 0x50, 0x00, 0xc0, 0x19, 0x80, 0x8b, +0x4d, 0x49, 0x89, 0x6a, 0x58, 0x23, 0x58, 0x43, 0x0d, 0x18, 0x01, 0x23, +0x9b, 0x07, 0xe9, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x35, +0x2b, 0x43, 0x1d, 0x68, 0xff, 0x23, 0x1b, 0x02, 0x2b, 0x40, 0x1b, 0x0a, +0x45, 0x4d, 0x01, 0x2b, 0x24, 0xd1, 0xd0, 0x19, 0xc1, 0x1d, 0x19, 0x31, +0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x42, 0x4a, 0x09, 0x7b, 0x00, 0xf0, +0xd3, 0xfc, 0x20, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, +0x41, 0x18, 0x00, 0x20, 0x82, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, +0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf7, 0xd3, 0xca, 0x1d, 0x05, 0x32, +0x69, 0x46, 0x00, 0x20, 0x43, 0x00, 0xcd, 0x5a, 0xc0, 0x46, 0xd5, 0x52, +0x01, 0x30, 0x06, 0x28, 0xf8, 0xd3, 0x3e, 0xe0, 0x02, 0x2b, 0x3c, 0xd1, +0x09, 0x0a, 0x3a, 0xd3, 0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, +0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf7, 0xd3, 0x21, 0x78, +0x49, 0x00, 0xc9, 0x19, 0x09, 0x8f, 0x3a, 0x68, 0x8b, 0x18, 0x6a, 0x46, +0x00, 0x21, 0x4d, 0x00, 0x56, 0x5b, 0xc0, 0x46, 0x5e, 0x53, 0x01, 0x31, +0x06, 0x29, 0xf8, 0xd3, 0x22, 0x49, 0x8a, 0x6a, 0x12, 0x18, 0x01, 0x23, +0x9b, 0x07, 0xd5, 0x1d, 0x49, 0x35, 0x2b, 0x43, 0x6e, 0x46, 0x1d, 0x68, +0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x6b, 0x40, 0x1e, 0x4d, +0xee, 0x68, 0x73, 0x40, 0x13, 0x65, 0x89, 0x6a, 0x08, 0x18, 0x01, 0x23, +0x9b, 0x07, 0xc1, 0x1d, 0x4d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x6a, 0x46, +0x08, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x51, 0x40, 0xaa, 0x69, 0x51, 0x40, +0x41, 0x65, 0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 0x0d, 0xd0, +0x38, 0x1c, 0xff, 0xf7, 0xef, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 0x09, 0x4a, +0x50, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 0x00, 0xf0, +0xa3, 0xfa, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x72, 0xfa, 0x01, 0xf0, +0xc3, 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xb8, 0x03, 0x00, 0x80, +0xc8, 0x29, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 0x14, 0x06, 0x00, 0x80, +0x08, 0x83, 0x20, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x4b, 0x9f, 0x6a, +0x58, 0x23, 0x5a, 0x43, 0xba, 0x18, 0xc3, 0x1d, 0x49, 0x33, 0x1f, 0x78, +0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x01, 0x34, 0x23, 0x43, 0x1d, 0x68, +0x43, 0x68, 0x1c, 0x04, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x05, 0x36, +0x33, 0x43, 0x1b, 0x68, 0x1c, 0x43, 0x42, 0x23, 0x1c, 0x43, 0x0c, 0x60, +0xff, 0x26, 0x36, 0x02, 0x2e, 0x40, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, +0x74, 0xd1, 0x6b, 0x0c, 0x2b, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, +0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x4c, 0x89, +0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 0x01, 0x96, 0xb3, 0x18, +0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, +0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, +0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x1d, 0x36, +0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0x76, 0x18, +0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 0x06, 0xe0, 0x00, 0x23, +0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 0x0c, 0x60, 0x23, 0x1c, +0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, +0x1b, 0x79, 0x10, 0x33, 0x0b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, +0x0f, 0x89, 0xdb, 0x1b, 0x8b, 0x80, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, +0x35, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x63, 0x01, 0x23, +0x9b, 0x07, 0xd4, 0x1d, 0x31, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, +0x0b, 0x64, 0xab, 0x0e, 0x21, 0xd2, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, +0x3d, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x64, 0x01, 0x23, +0x9b, 0x07, 0xd4, 0x1d, 0x39, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, +0x8b, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x45, 0x34, 0x23, 0x43, +0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, +0x41, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x65, 0x00, 0xe0, +0x0f, 0xe0, 0xfb, 0x1f, 0x01, 0x3b, 0x1b, 0x04, 0x1b, 0x0c, 0x07, 0x68, +0xff, 0x18, 0x03, 0x69, 0x08, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x34, 0xf8, +0x2c, 0xe0, 0x00, 0x23, 0x0b, 0x81, 0x8b, 0x80, 0x28, 0xe0, 0x00, 0x23, +0x8b, 0x80, 0x0b, 0x81, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x7a, 0xc0, 0x46, +0x4b, 0x81, 0x7b, 0x00, 0x18, 0x18, 0x00, 0x8e, 0xc0, 0x46, 0xc8, 0x80, +0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 0x09, 0x34, 0x01, 0x23, +0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 0x7b, 0x61, 0x01, 0x30, +0x05, 0x28, 0xf2, 0xd3, 0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, +0x1d, 0x34, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, +0xbb, 0x62, 0x01, 0x30, 0x05, 0x28, 0xf2, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xc8, 0x29, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, +0x3b, 0x0c, 0x18, 0xd2, 0x17, 0x6d, 0x11, 0x4b, 0xc0, 0x46, 0xdf, 0x60, +0x52, 0x6d, 0xc0, 0x46, 0x1a, 0x61, 0xc7, 0x60, 0x1a, 0x69, 0xc0, 0x46, +0x02, 0x61, 0xd8, 0x68, 0xc0, 0x46, 0x08, 0x80, 0xd8, 0x68, 0x00, 0x0c, +0x48, 0x80, 0x18, 0x69, 0xc0, 0x46, 0x88, 0x80, 0x18, 0x69, 0x00, 0x0c, +0xc8, 0x80, 0x80, 0xbc, 0x70, 0x47, 0x4a, 0x88, 0x12, 0x04, 0x0b, 0x88, +0x1a, 0x43, 0xc2, 0x60, 0x8a, 0x88, 0xc9, 0x88, 0x09, 0x04, 0x11, 0x43, +0x01, 0x61, 0xf2, 0xe7, 0xac, 0x06, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, +0x00, 0x22, 0x08, 0x98, 0x00, 0x6a, 0x08, 0x9b, 0x99, 0x68, 0x49, 0x0a, +0x02, 0xd3, 0x01, 0x27, 0xff, 0x03, 0x00, 0xe0, 0x00, 0x27, 0x03, 0x8b, +0x00, 0x2b, 0x19, 0xd0, 0xa2, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, +0x63, 0x43, 0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, +0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x02, 0xd1, 0x08, 0x23, +0x1f, 0x43, 0x07, 0xe0, 0x41, 0x8b, 0x00, 0x29, 0x02, 0xd0, 0x0c, 0x23, +0x1f, 0x43, 0x01, 0xe0, 0x04, 0x23, 0x1f, 0x43, 0x83, 0x8a, 0x00, 0x2b, +0x18, 0xd0, 0x94, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, +0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, +0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 0x0f, 0x43, 0x07, 0xe0, +0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 0x1f, 0x43, 0x01, 0xe0, +0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 0x07, 0x91, 0x4b, 0x89, +0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 0x08, 0x9d, 0x2d, 0x68, +0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 0x1a, 0xd3, 0x1a, 0x1c, +0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, +0x92, 0x89, 0xc0, 0x46, 0x1a, 0x73, 0x07, 0x9a, 0x12, 0x89, 0xc0, 0x46, +0x02, 0x86, 0x04, 0x87, 0x82, 0x8a, 0x01, 0x3a, 0x82, 0x83, 0x01, 0x22, +0x19, 0x71, 0x08, 0x9b, 0x1b, 0x68, 0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, +0x1b, 0x04, 0x1b, 0x0c, 0x08, 0x33, 0x59, 0x18, 0xbb, 0x08, 0x47, 0xd3, +0x07, 0x9b, 0x5b, 0x89, 0x85, 0x18, 0x06, 0x95, 0x20, 0x35, 0x2b, 0x72, +0x07, 0x9b, 0x9b, 0x89, 0xc0, 0x46, 0x2b, 0x73, 0x07, 0x9b, 0x1b, 0x89, +0x2e, 0x1c, 0x55, 0x00, 0x2d, 0x18, 0x05, 0x95, 0x2b, 0x86, 0x00, 0x2a, +0x01, 0xd0, 0xc3, 0x8a, 0x00, 0xe0, 0x83, 0x8a, 0x01, 0x3b, 0x05, 0x9d, +0xc0, 0x46, 0xab, 0x83, 0x31, 0x71, 0x64, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, +0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, +0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, +0x01, 0xd1, 0x08, 0x31, 0x00, 0xe0, 0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, +0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, +0x24, 0x0c, 0x05, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, +0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x06, 0x9d, 0x40, 0x35, 0x2b, 0x70, +0x2b, 0x78, 0x02, 0x33, 0xe3, 0x1a, 0x1c, 0x04, 0x24, 0x0c, 0x01, 0x32, +0xbb, 0x08, 0x9b, 0x07, 0x6b, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, +0x19, 0x72, 0x01, 0x9b, 0x5d, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, +0x1b, 0x68, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9e, 0xc0, 0x46, +0x33, 0x73, 0x00, 0x95, 0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, +0x04, 0x9d, 0xc0, 0x46, 0x2b, 0x73, 0x00, 0x9d, 0xeb, 0x78, 0xad, 0x78, +0x1b, 0x02, 0x1d, 0x43, 0x2b, 0x02, 0x2d, 0x0a, 0x2d, 0x06, 0x2d, 0x0e, +0x2b, 0x43, 0x55, 0x00, 0x2d, 0x18, 0x2b, 0x86, 0x04, 0x9b, 0xc0, 0x46, +0x59, 0x72, 0x04, 0x9b, 0x1b, 0x7b, 0x2e, 0x1c, 0x04, 0x9d, 0xc0, 0x46, +0x6b, 0x73, 0x33, 0x8e, 0xc0, 0x46, 0x73, 0x86, 0x00, 0x9d, 0x2b, 0x78, +0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x59, 0x18, 0x04, 0x25, 0x3d, 0x40, +0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 0xb3, 0x83, 0x13, 0x1c, +0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 0x5b, 0x18, 0x5b, 0x78, +0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 0x3b, 0x09, 0x37, 0xd3, +0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 0x03, 0x8b, 0x55, 0x00, +0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 0x03, 0x93, 0x20, 0x33, +0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 0x1b, 0x18, 0x02, 0x93, +0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, +0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, +0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0, 0x10, 0x31, 0x81, 0x23, +0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, +0x1c, 0x04, 0x24, 0x0c, 0x02, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, +0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x03, 0x9c, 0x40, 0x34, +0x23, 0x70, 0x01, 0x32, 0x07, 0x9b, 0xc0, 0x46, 0xd9, 0x80, 0x51, 0x1e, +0xc3, 0x1d, 0x49, 0x33, 0x19, 0x70, 0x07, 0x61, 0x04, 0x2a, 0x06, 0xd2, +0x06, 0x49, 0x53, 0x00, 0x1b, 0x18, 0x99, 0x83, 0x01, 0x32, 0x04, 0x2a, +0xf9, 0xd3, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xc8, 0x29, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, +0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x12, 0x48, 0x01, 0x68, +0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x78, 0x68, +0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x0d, 0x48, +0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0, +0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 0x10, 0x23, 0x02, 0x98, +0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 0xcd, 0xff, 0x68, 0x46, +0x02, 0xf0, 0x82, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x8c, 0xb0, +0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, +0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 0x02, 0xf0, 0x6c, 0xfe, +0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, +0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 0x40, 0x68, 0xc0, 0x46, +0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 0x90, 0x80, 0xc8, 0x68, +0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 0x10, 0x81, 0x88, 0x68, +0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 0x90, 0x73, 0x08, 0x69, +0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 0x08, 0x68, 0x00, 0x28, +0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 0x0a, 0x60, 0xfa, 0xe7, +0xec, 0x05, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 0xc0, 0x46, 0xc2, 0x60, +0x08, 0x60, 0x70, 0x47, 0xec, 0x05, 0x00, 0x80, 0xb0, 0xb4, 0x00, 0x22, +0x12, 0x4f, 0x3b, 0x7f, 0x01, 0x33, 0x3b, 0x77, 0x03, 0x23, 0xfc, 0x1d, +0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 0x0e, 0x4c, 0x25, 0x68, +0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x10, 0xd1, 0x24, 0x68, +0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0xfb, 0x62, +0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x99, 0x60, 0x58, 0x60, +0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 0x10, 0x1c, 0x38, 0x64, +0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, +0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00, +0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 0x47, 0x4d, 0x07, 0x23, +0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 0xe0, 0x6a, 0x01, 0x30, +0xe0, 0x62, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x43, 0x48, 0x41, 0x69, +0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, +0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, +0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, +0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x3a, 0xfe, 0x38, 0x68, 0x01, 0x28, +0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, +0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, +0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, +0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, +0x1f, 0xfe, 0x38, 0x68, 0x02, 0x28, 0x2f, 0xd1, 0xbb, 0x23, 0x1b, 0x01, +0xee, 0x18, 0x70, 0x7a, 0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, 0x70, 0x72, +0x00, 0xf0, 0x30, 0xfd, 0x30, 0x7a, 0x00, 0x28, 0x02, 0xd0, 0x78, 0x68, +0x02, 0xf0, 0x96, 0xff, 0x1b, 0x23, 0xdb, 0x01, 0xe8, 0x18, 0x40, 0x8b, +0x04, 0x26, 0x06, 0x40, 0xa0, 0x6a, 0xb0, 0x42, +0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x19, 0x28, 0x11, 0xd3, +0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 0xff, 0x30, 0x41, 0x30, +0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 0x02, 0xf0, 0x7c, 0xff, +0x00, 0x20, 0xf8, 0x60, 0xa6, 0x62, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60, +0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 0x79, 0x34, 0xa0, 0x6b, +0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 0xef, 0xfb, 0x02, 0x23, +0xa0, 0x6b, 0x98, 0x43, 0xa0, 0x63, 0x38, 0x68, 0x01, 0x30, 0x38, 0x60, +0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xbc, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0xd0, 0x2c, 0x00, 0x80, +0x50, 0x2c, 0x00, 0x80, 0xa8, 0x04, 0x00, 0x80, 0x90, 0xb4, 0x1c, 0x48, +0x02, 0x8a, 0x1c, 0x49, 0x0f, 0x8a, 0x01, 0x23, 0xba, 0x42, 0x03, 0xd1, +0xc2, 0x89, 0x4f, 0x8a, 0xba, 0x42, 0x10, 0xd0, 0x02, 0x7b, 0x00, 0x2a, +0x0d, 0xd0, 0x42, 0x7b, 0x00, 0x2a, 0x0a, 0xd0, 0xc7, 0x8a, 0x8a, 0x8a, +0x97, 0x42, 0x04, 0xdc, 0x13, 0x4a, 0xc0, 0x46, 0x53, 0x60, 0x8b, 0x82, +0x01, 0xe0, 0x01, 0x32, 0x8a, 0x82, 0x42, 0x8b, 0x57, 0x1c, 0x47, 0x83, +0x07, 0x8b, 0xba, 0x42, 0x0e, 0xdb, 0x07, 0x8a, 0x84, 0x8a, 0x00, 0x22, +0xa7, 0x42, 0x05, 0xda, 0xc7, 0x89, 0x44, 0x8a, 0xa7, 0x42, 0x01, 0xda, +0x42, 0x73, 0x00, 0xe0, 0x43, 0x73, 0xc2, 0x81, 0x02, 0x82, 0x42, 0x83, +0xc2, 0x89, 0xc0, 0x46, 0x4a, 0x82, 0x00, 0x8a, 0xc0, 0x46, 0x08, 0x82, +0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xbc, 0x03, 0x00, 0x80, +0x40, 0x01, 0x18, 0x00, 0xf7, 0xb5, 0x91, 0xb0, 0x6b, 0x46, 0x84, 0x1e, +0x12, 0x99, 0x14, 0x29, 0x1a, 0xd9, 0x00, 0x20, 0x81, 0x00, 0x67, 0x58, +0xc0, 0x46, 0x57, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, +0xf6, 0xd3, 0x00, 0x21, 0x05, 0x20, 0x87, 0x00, 0xd6, 0x59, 0x4f, 0x1c, +0x3d, 0x06, 0x2d, 0x0e, 0x0f, 0x1c, 0xbf, 0x00, 0xde, 0x51, 0x29, 0x1c, +0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 0xf1, 0xd3, 0x09, 0xe0, +0x00, 0x20, 0x81, 0x00, 0x63, 0x58, 0xc0, 0x46, 0x53, 0x50, 0x01, 0x30, +0x00, 0x06, 0x00, 0x0e, 0x06, 0x28, 0xf6, 0xd3, 0x00, 0x20, 0xe0, 0x70, +0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, 0x20, 0x73, 0x60, 0x73, 0x12, 0x99, +0x14, 0x29, 0x37, 0xd9, 0x69, 0x46, 0x8e, 0x1c, 0x91, 0x78, 0x09, 0x07, +0x09, 0x0f, 0x89, 0x00, 0x14, 0x39, 0x0d, 0x06, 0x2d, 0x16, 0x00, 0x27, +0x00, 0x2d, 0x1b, 0xdd, 0xf0, 0x19, 0x10, 0xa9, 0x00, 0xf0, 0x3d, 0xf8, +0x00, 0x28, 0x0e, 0xd0, 0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, +0x09, 0xdd, 0x00, 0x22, 0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, +0x00, 0x0e, 0x10, 0xa9, 0x09, 0x78, 0x88, 0x42, 0xf6, 0xdb, 0x10, 0xa8, +0x00, 0x78, 0x38, 0x18, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xe3, 0xdb, +0x68, 0x46, 0xe2, 0x1d, 0x0d, 0x32, 0x00, 0x21, 0xab, 0x08, 0x5f, 0x1c, +0x08, 0xd0, 0x8b, 0x00, 0xc4, 0x58, 0xc0, 0x46, 0xd4, 0x50, 0x01, 0x31, +0x09, 0x06, 0x09, 0x0e, 0x8f, 0x42, 0xf6, 0xd8, 0x14, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x90, 0xb4, 0x87, 0x1e, 0x00, 0x20, 0x89, 0x08, +0x4b, 0x1c, 0x08, 0xd0, 0x81, 0x00, 0x54, 0x58, 0xc0, 0x46, 0x7c, 0x50, +0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x83, 0x42, +0xf6, 0xd8, 0x90, 0xbc, 0x70, 0x47, 0x80, 0xb4, 0x02, 0x78, 0xd2, 0x06, +0xd2, 0x0e, 0x00, 0x23, 0x01, 0x27, 0x01, 0x2a, 0x01, 0xdc, 0x0f, 0x70, +0x11, 0xe0, 0x40, 0x78, 0xc0, 0x46, 0x08, 0x70, 0x14, 0x2a, 0x04, 0xd1, +0x08, 0x48, 0x01, 0x7a, 0x01, 0x31, 0x01, 0x72, 0x07, 0xe0, 0x02, 0x2a, +0x05, 0xd0, 0x05, 0x2a, 0x03, 0xd0, 0x06, 0x2a, 0x01, 0xd0, 0x15, 0x2a, +0x02, 0xd1, 0x18, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x38, 0x1c, 0xfb, 0xe7, +0xe0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x0f, 0x48, 0x01, 0x23, 0x1b, 0x06, +0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, +0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 0x19, 0x1c, 0x09, 0x4a, 0xc0, 0x46, +0x11, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, +0x03, 0xd0, 0x02, 0xf0, 0x4f, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x04, 0x48, +0x41, 0x88, 0x01, 0x31, 0x41, 0x80, 0xf8, 0xe7, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x00, 0x00, 0xb0, 0xe0, 0x82, 0x20, 0x40, 0x70, 0x47, 0x00, 0x00, +0xf0, 0xb5, 0x85, 0xb0, 0x94, 0x49, 0xc8, 0x68, 0xcf, 0x1d, 0x79, 0x37, +0x01, 0x28, 0x0b, 0xd1, 0xb8, 0x88, 0x00, 0x28, 0x08, 0xd1, 0xc3, 0x1e, +0xca, 0x6f, 0x1a, 0x40, 0xca, 0x67, 0x8f, 0x48, 0xc0, 0x46, 0x02, 0x60, +0x14, 0x20, 0xb8, 0x80, 0x8d, 0x4c, 0x62, 0x6a, 0x8d, 0x48, 0xc3, 0x6b, +0x9a, 0x18, 0xc2, 0x63, 0xa0, 0x6a, 0x19, 0x23, 0xdb, 0x01, 0xcc, 0x18, +0x60, 0x62, 0xe2, 0x69, 0x12, 0x03, 0x12, 0x0b, 0x82, 0x42, 0x05, 0xd1, +0x01, 0x20, 0x40, 0x04, 0x86, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xef, 0xe0, +0x3b, 0x8a, 0x58, 0x1c, 0x38, 0x82, 0xbd, 0x8a, 0x01, 0x20, 0x00, 0x22, +0xab, 0x42, 0x02, 0xdb, 0x78, 0x73, 0x3a, 0x82, 0x7a, 0x83, 0x33, 0x23, +0x9b, 0x01, 0xcb, 0x18, 0x04, 0x93, 0x1b, 0x69, 0x0f, 0x2b, 0x73, 0xd2, +0x00, 0x22, 0x2f, 0x23, 0x9b, 0x01, 0xcf, 0x18, 0xfa, 0x60, 0xe1, 0x69, +0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x4b, 0x68, 0x1e, 0x0c, 0x36, 0x04, +0x76, 0x4d, 0x05, 0xd1, 0x3b, 0x2a, 0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, +0x9a, 0x42, 0x01, 0xd9, 0xa8, 0x72, 0xc7, 0xe0, 0x01, 0x23, 0x9b, 0x07, +0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, +0x09, 0x88, 0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0xf9, 0x81, 0x49, 0x09, +0x05, 0x31, 0x09, 0x06, 0x09, 0x0e, 0x6a, 0x4a, 0xc0, 0x46, 0x02, 0x92, +0x06, 0x1c, 0x69, 0x48, 0x43, 0x6a, 0xc0, 0x46, 0x01, 0x93, 0x83, 0x6a, +0xc0, 0x46, 0x00, 0x93, 0xc2, 0x1d, 0x11, 0x32, 0x80, 0x69, 0x00, 0x03, +0x00, 0x0b, 0x92, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, +0x90, 0x42, 0x01, 0xd1, 0x30, 0x1c, 0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, +0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b, 0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, +0x12, 0x1a, 0x01, 0x20, 0x09, 0x01, 0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, +0x01, 0x28, 0x62, 0xd1, 0xe0, 0x68, 0x00, 0x28, 0x60, 0xd0, 0x04, 0x99, +0x08, 0x69, 0x01, 0x30, 0x08, 0x61, 0x02, 0x20, 0xe1, 0x69, 0xc0, 0x46, +0x08, 0x60, 0x00, 0xf0, 0x8f, 0xfc, 0x38, 0x63, 0x4e, 0x49, 0xc0, 0x46, +0x79, 0x60, 0xe1, 0x69, 0x62, 0x6b, 0x8a, 0x18, 0x23, 0x6b, 0x9a, 0x42, +0x00, 0xd9, 0xe1, 0x6a, 0xc0, 0x46, 0x79, 0x62, 0x79, 0x6a, 0x0c, 0x31, +0xb9, 0x62, 0x00, 0x21, 0xb9, 0x61, 0x03, 0xa9, 0x49, 0x88, 0xc9, 0x09, +0x03, 0xd3, 0x00, 0xe0, 0x78, 0xe0, 0x31, 0x1c, +0x00, 0xe0, 0x00, 0x21, 0x39, 0x60, 0x39, 0x68, 0xc0, 0x46, 0x01, 0x60, +0xf8, 0x89, 0x41, 0x4e, 0x60, 0x28, 0x04, 0xdc, 0x30, 0x83, 0xf8, 0x89, +0xc0, 0x46, 0x70, 0x83, 0x08, 0xe0, 0x60, 0x20, 0x30, 0x83, 0xf9, 0x89, +0xb8, 0x6a, 0x42, 0x18, 0x23, 0x6b, 0x9a, 0x42, 0x03, 0xd8, 0x71, 0x83, +0x00, 0x21, 0xf9, 0x62, 0x05, 0xe0, 0xe1, 0x6a, 0xc0, 0x46, 0xf9, 0x62, +0x21, 0x6b, 0x08, 0x1a, 0x70, 0x83, 0x38, 0x6b, 0x41, 0x68, 0xc0, 0x46, +0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x01, 0x69, 0xc0, 0x46, +0x39, 0x61, 0x40, 0x69, 0xc0, 0x46, 0x78, 0x61, 0x38, 0x1c, 0x00, 0xf0, +0x23, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xe0, 0xfa, +0xf8, 0x89, 0x71, 0x8b, 0x88, 0x42, 0x04, 0xd1, 0xb9, 0x6a, 0x08, 0x18, +0x04, 0xe0, 0x38, 0xe0, 0x32, 0xe0, 0xfa, 0x6a, 0x10, 0x18, 0x40, 0x1a, +0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x21, 0x6b, +0x09, 0x1a, 0x62, 0x6b, 0x91, 0x42, 0x00, 0xd2, 0xe0, 0x6a, 0xc0, 0x46, +0xe0, 0x61, 0xe8, 0x7a, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x21, 0xe9, 0x72, +0x04, 0x99, 0x08, 0x69, 0x01, 0x38, 0x08, 0x61, 0x38, 0x6b, 0x00, 0xf0, +0x5d, 0xfa, 0x18, 0x48, 0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, +0x0a, 0xd1, 0xe0, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x0c, 0x4c, 0xa1, 0x6a, +0x88, 0x42, 0x03, 0xd0, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x01, 0x20, 0x40, 0x04, 0x09, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x05, 0xe0, +0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x9f, 0xfa, 0xae, 0x72, +0xee, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, +0x00, 0x40, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, +0x98, 0x19, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, +0xe8, 0x19, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, +0x78, 0x6a, 0x40, 0x89, 0xff, 0x21, 0x01, 0x31, 0x01, 0x40, 0x10, 0x48, +0x02, 0xd1, 0x81, 0x6c, 0x01, 0x31, 0x81, 0x64, 0x79, 0x6a, 0x49, 0x89, +0x49, 0x0b, 0x02, 0xd2, 0x41, 0x6c, 0x01, 0x31, 0x41, 0x64, 0x0b, 0x48, +0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, +0x48, 0x62, 0x38, 0x6b, 0x00, 0xf0, 0xe2, 0xfb, 0x38, 0x1c, 0x00, 0xf0, +0x9f, 0xf8, 0x01, 0x20, 0x04, 0x49, 0xc0, 0x46, 0xc8, 0x72, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x98, 0x19, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, +0x61, 0x31, 0x0d, 0x1c, 0x78, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x40, 0x89, +0x03, 0x0c, 0x01, 0xd2, 0x40, 0x0a, 0x03, 0xd2, 0x38, 0x1c, 0xff, 0xf7, +0xc1, 0xff, 0x54, 0xe0, 0x2b, 0x48, 0x80, 0x6b, 0x00, 0x09, 0x1f, 0xd3, +0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 0x43, 0x00, 0xcc, 0x5a, +0x27, 0x4e, 0x9e, 0x19, 0x65, 0x23, 0x5b, 0x01, 0xf3, 0x18, 0x9b, 0x8b, +0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, +0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x38, 0x1c, 0x00, 0xf0, +0x13, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x60, 0xf8, 0x33, 0xe0, 0x01, 0x30, +0x03, 0x28, 0xe3, 0xd3, 0x1a, 0x48, 0x0b, 0x23, 0x1b, 0x02, 0xc1, 0x18, +0x09, 0x69, 0x00, 0x29, 0x24, 0xd0, 0x7d, 0x63, 0x00, 0x99, 0x49, 0x89, +0x09, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 0x2d, 0x23, +0x9b, 0x01, 0xc1, 0x18, 0x89, 0x6b, 0x00, 0x29, 0x18, 0xd0, 0x05, 0x1c, +0xfe, 0x1d, 0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 0x9b, 0x01, +0xd2, 0x18, 0x92, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 0x7e, 0xfc, +0x01, 0x28, 0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x2d, 0x23, +0x9b, 0x01, 0xc0, 0x18, 0x80, 0x6b, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, +0x01, 0x2a, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0xf8, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x1a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, +0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, +0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x78, 0x6a, 0x40, 0x89, +0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 0x38, 0x68, 0x40, 0x08, +0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x10, 0xfc, 0x38, 0x1c, 0x00, 0xf0, +0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0x02, 0xe0, 0x38, 0x1c, +0xff, 0xf7, 0x44, 0xff, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 0x01, 0x60, 0x70, 0x47, +0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 0x89, 0x08, 0x09, 0x04, +0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 0x00, 0x20, 0x00, 0x29, +0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, +0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, +0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xa0, 0xb0, +0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 0x19, 0x43, 0x09, 0x68, +0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 0x19, 0x43, 0x1f, 0x91, +0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 0x1e, 0x92, 0x17, 0xab, +0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 0x0a, 0x6a, 0x13, 0x43, +0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 0x09, 0x0b, 0x22, 0x69, +0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 0x39, 0x34, 0x64, 0x8b, +0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 0x1c, 0x94, 0x56, 0x1a, +0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x26, +0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 0x32, 0x1c, 0x0b, 0xe0, +0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 0xb5, 0x18, 0x00, 0xe0, +0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42, 0x00, 0xd3, 0x00, 0x22, +0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43, 0x09, 0x68, 0xc0, 0x46, +0x39, 0x60, 0x93, 0x07, 0x01, 0x1d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, +0x79, 0x60, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, +0xb9, 0x60, 0x1f, 0x99, 0x09, 0x68, 0x1e, 0x9a, 0xc0, 0x46, 0x51, 0x83, +0xc1, 0x1d, 0x1d, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x38, 0x63, +0x79, 0x62, 0xc1, 0x1d, 0x11, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, +0xb9, 0x61, 0xc1, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, +0xf9, 0x60, 0xc1, 0x1d, 0x17, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, +0xf9, 0x83, 0x0e, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x81, +0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x60, 0xfb, +0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x58, 0xff, +0x20, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x03, 0x00, 0x80, +0x55, 0x55, 0x55, 0x55, 0xf8, 0xb5, 0x07, 0x1c, +0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x38, 0x4a, 0x91, 0x42, 0x00, 0xdd, +0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x20, 0x3a, 0x1d, +0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x12, 0xff, 0x32, 0x4a, 0xc0, 0x46, +0x00, 0x92, 0x32, 0x4e, 0x30, 0x6a, 0x32, 0x4c, 0xe1, 0x6d, 0x41, 0x18, +0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 0x72, 0x6a, 0x02, 0xf0, +0xff, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0xb1, 0x6a, 0x81, 0x42, 0x00, 0xd8, +0x00, 0x20, 0xe0, 0x65, 0x17, 0x23, 0xdb, 0x01, 0x20, 0x1c, 0xe1, 0x6d, +0xe4, 0x18, 0xe2, 0x6b, 0x92, 0x00, 0x27, 0x4b, 0xc0, 0x46, 0x99, 0x50, +0x26, 0x4d, 0xa8, 0x6b, 0x41, 0x08, 0x05, 0xd3, 0x40, 0x08, 0x40, 0x00, +0xa8, 0x63, 0x01, 0x20, 0x01, 0xf0, 0xd8, 0xff, 0x22, 0x4a, 0x1f, 0x48, +0x29, 0x7b, 0x00, 0x29, 0x02, 0xd0, 0x69, 0x7b, 0x00, 0x29, 0x00, 0xd1, +0x1f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x05, 0x1c, 0xe0, 0x6b, 0x80, 0x00, +0x19, 0x4b, 0xc3, 0x18, 0x05, 0xce, 0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, +0x02, 0xf0, 0xce, 0xfe, 0xe0, 0x6b, 0x01, 0x30, 0xe0, 0x63, 0x17, 0x28, +0x01, 0xd3, 0x00, 0x20, 0xe0, 0x63, 0x00, 0x20, 0x39, 0x6b, 0xc0, 0x46, +0x08, 0x65, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x33, 0x23, +0x9b, 0x01, 0xe8, 0x18, 0x41, 0x68, 0x00, 0x29, 0x03, 0xd1, 0x39, 0x6b, +0xc0, 0x46, 0x41, 0x60, 0x04, 0xe0, 0x39, 0x6b, 0x82, 0x68, 0xc0, 0x46, +0x11, 0x65, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 0xf8, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0x18, 0x00, 0x14, 0x02, +0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x44, 0x82, 0x20, 0x40, +0x68, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x03, +0xf0, 0xb5, 0x11, 0x4e, 0xff, 0x25, 0x01, 0x35, 0x10, 0x4f, 0xc0, 0x46, +0x35, 0x60, 0x38, 0x69, 0x01, 0x38, 0x38, 0x61, 0x7c, 0x68, 0x00, 0x2c, +0x10, 0xd0, 0x20, 0x6d, 0xc0, 0x46, 0x78, 0x60, 0x20, 0x1c, 0x00, 0xf0, +0x21, 0xf8, 0x20, 0x1c, 0x00, 0xf0, 0x04, 0xfa, 0x08, 0x48, 0x80, 0x6a, +0x00, 0x0c, 0x00, 0x07, 0xe9, 0xd1, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x05, 0x48, 0xc1, 0x79, 0x01, 0x31, 0xc1, 0x71, 0xf7, 0xe7, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0xa8, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, +0xa0, 0x82, 0x20, 0x40, 0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, +0x38, 0x68, 0xc0, 0x08, 0x09, 0xd3, 0x1d, 0x48, 0x01, 0x6a, 0x01, 0x39, +0x01, 0x62, 0x20, 0x30, 0x00, 0x79, 0x00, 0x28, 0x01, 0xd0, 0xfe, 0xf7, +0x09, 0xfe, 0x01, 0x23, 0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, +0x00, 0x68, 0x16, 0x4c, 0x21, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, +0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x01, 0x29, 0x1a, 0xd1, +0x00, 0xf0, 0x22, 0xf8, 0x20, 0x62, 0x20, 0x6a, 0xe1, 0x69, 0x88, 0x42, +0x05, 0xd0, 0x01, 0x21, 0x89, 0x07, 0x01, 0x43, 0x09, 0x68, 0x09, 0x04, +0xf2, 0xd0, 0x51, 0x21, 0x89, 0x03, 0x22, 0x6a, 0xe3, 0x6a, 0x9a, 0x42, +0x02, 0xd1, 0x20, 0x6b, 0x62, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x79, 0x6a, 0xc0, 0x46, +0x08, 0x60, 0xf7, 0xe7, 0xec, 0x05, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, +0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x01, 0x31, +0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x18, 0x0d, 0x30, +0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x04, 0x49, +0x4a, 0x6b, 0x12, 0x18, 0x0b, 0x6b, 0x9a, 0x42, 0x00, 0xd9, 0xc8, 0x6a, +0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x00, 0xb5, 0x04, 0x48, +0x80, 0x68, 0x10, 0x28, 0x01, 0xd3, 0x00, 0xf0, 0x05, 0xf8, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x88, 0xb5, 0x0c, 0x4f, +0x38, 0x78, 0x00, 0x28, 0x11, 0xd1, 0x0b, 0x49, 0x10, 0x20, 0x02, 0xf0, +0xfb, 0xfd, 0x00, 0x28, 0x0b, 0xd0, 0x01, 0x20, 0x38, 0x70, 0x08, 0x4a, +0xc0, 0x46, 0x00, 0x92, 0x07, 0x48, 0x42, 0x68, 0x07, 0x4b, 0x01, 0x68, +0x00, 0x20, 0x02, 0xf0, 0xe5, 0xfd, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x78, 0x1a, 0x00, 0x80, 0x69, 0x2c, 0xff, 0xff, 0x10, 0x00, 0x35, 0x02, +0xf8, 0x28, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x90, 0xb5, 0x01, 0x20, +0x40, 0x02, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4f, 0x10, 0x21, +0xf8, 0x1d, 0x3d, 0x30, 0x02, 0xf0, 0x52, 0xfc, 0x19, 0x23, 0xdb, 0x01, +0xfc, 0x18, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x14, 0xf8, +0x00, 0x20, 0xc9, 0x23, 0x1b, 0x01, 0xf9, 0x18, 0x08, 0x70, 0xa0, 0x68, +0x10, 0x28, 0x04, 0xd3, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xf9, 0x18, +0x48, 0x72, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, +0xe8, 0x0d, 0x00, 0x80, 0xf8, 0xb5, 0x37, 0x48, 0x19, 0x23, 0xdb, 0x01, +0xc1, 0x18, 0x89, 0x68, 0x35, 0x4d, 0x10, 0x29, 0x00, 0xd9, 0x10, 0x21, +0x29, 0x62, 0x32, 0x48, 0xc1, 0x6c, 0x00, 0x6e, 0x81, 0x42, 0x07, 0xd9, +0x08, 0x1a, 0x07, 0x09, 0x00, 0x24, 0x28, 0x6a, 0xb8, 0x42, 0x12, 0xd2, +0x07, 0x1c, 0x10, 0xe0, 0x81, 0x42, 0x2a, 0xd2, 0x2c, 0x4a, 0x52, 0x6b, +0x10, 0x1a, 0x07, 0x09, 0x28, 0x6a, 0xb8, 0x42, 0x05, 0xd9, 0x0c, 0x09, +0x39, 0x19, 0x88, 0x42, 0x03, 0xd2, 0xc4, 0x1b, 0x01, 0xe0, 0x00, 0x24, +0x07, 0x1c, 0x3e, 0x19, 0x30, 0x01, 0x25, 0x49, 0x02, 0xf0, 0x8a, 0xfd, +0x00, 0x28, 0x3d, 0xd0, 0x23, 0x48, 0x00, 0x2c, 0x1a, 0xd1, 0x1e, 0x49, +0x3a, 0x01, 0x2f, 0x62, 0x09, 0x6e, 0x8c, 0x18, 0x1d, 0x4d, 0x6b, 0x6b, +0xa3, 0x42, 0x00, 0xd8, 0xe4, 0x1a, 0x1e, 0x4b, 0x1a, 0x43, 0x00, 0x92, +0xea, 0x6a, 0x51, 0x18, 0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, +0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x00, 0x20, 0x28, 0x62, 0xf8, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x10, 0x49, 0x24, 0x01, 0x3f, 0x01, 0x11, 0x22, +0x52, 0x05, 0x3a, 0x43, 0x2e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, +0x09, 0x6e, 0x51, 0x18, 0x03, 0x1c, 0x06, 0x1c, 0x00, 0x20, 0x2a, 0x6b, +0x02, 0xf0, 0x50, 0xfd, 0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, +0xe9, 0x6a, 0x2a, 0x6b, 0x00, 0x20, 0x02, 0xf0, 0x47, 0xfd, 0x03, 0x48, +0xc0, 0x46, 0x04, 0x66, 0x00, 0xf0, 0x10, 0xf8, 0x01, 0x20, 0xda, 0xe7, +0xe8, 0x0d, 0x00, 0x80, 0xa8, 0x1a, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, +0xd1, 0x2d, 0xff, 0xff, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, +0xa0, 0x82, 0x20, 0x40, 0x04, 0x48, 0x01, 0x6e, 0x04, 0x4a, 0x80, 0x30, +0xd1, 0x60, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x70, 0x47, +0xe8, 0x0d, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, +0x01, 0x20, 0x80, 0x02, 0x1c, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x00, 0x27, 0x1b, 0x4e, 0x33, 0x23, 0x9b, 0x01, 0xf5, 0x18, +0x28, 0x6a, 0x00, 0x28, 0x1d, 0xd9, 0x19, 0x4c, 0x68, 0x46, 0x10, 0x21, +0x02, 0xf0, 0x96, 0xfb, 0x68, 0x46, 0x00, 0xf0, 0x33, 0xf8, 0x00, 0x28, +0x04, 0xd0, 0x15, 0x49, 0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x0a, 0xe0, +0x13, 0x49, 0x60, 0x7b, 0x01, 0x30, 0x60, 0x73, 0x88, 0x79, 0x01, 0x30, +0x88, 0x71, 0x11, 0x48, 0x00, 0x68, 0x02, 0xf0, 0x6b, 0xf9, 0x28, 0x6a, +0x01, 0x37, 0xb8, 0x42, 0xe2, 0xd8, 0xbb, 0x23, 0x1b, 0x01, 0xf0, 0x18, +0x81, 0x7a, 0x00, 0x29, 0x03, 0xd0, 0x00, 0x21, 0x81, 0x72, 0xff, 0xf7, +0x1d, 0xfb, 0xff, 0xf7, 0xe3, 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, +0xb0, 0x82, 0x20, 0x40, 0x08, 0x83, 0x20, 0x40, 0xa0, 0x82, 0x20, 0x40, +0xd8, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x17, 0x4f, 0x19, 0x23, 0xdb, 0x01, +0xf9, 0x18, 0x00, 0x22, 0x8b, 0x68, 0x00, 0x2b, 0x23, 0xd0, 0x01, 0x3b, +0x8b, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xff, 0x18, 0x7b, 0x69, 0x1c, 0x6d, +0xc0, 0x46, 0x7c, 0x61, 0x04, 0x68, 0xc0, 0x46, 0x5c, 0x60, 0x44, 0x68, +0xc0, 0x46, 0x9c, 0x60, 0x84, 0x68, 0xc0, 0x46, 0x1c, 0x61, 0xc0, 0x68, +0xc0, 0x46, 0x58, 0x61, 0x1a, 0x65, 0xc8, 0x68, 0x42, 0x1c, 0xca, 0x60, +0x00, 0x28, 0x03, 0xd0, 0xf8, 0x69, 0xc0, 0x46, 0x03, 0x65, 0x00, 0xe0, +0xbb, 0x61, 0xfb, 0x61, 0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x10, 0x1c, +0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x0a, 0x4a, 0x33, 0x23, +0x9b, 0x01, 0xd1, 0x18, 0x88, 0x69, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, +0xd3, 0x68, 0x00, 0x2b, 0x06, 0xd0, 0x01, 0x3b, 0xd3, 0x60, 0x8a, 0x69, +0x12, 0x6d, 0xc0, 0x46, 0x8a, 0x61, 0x70, 0x47, 0x00, 0x21, 0xd1, 0x60, +0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x06, 0x4a, 0xd1, 0x68, +0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x91, 0x69, +0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 0x70, 0x47, 0x00, 0x00, +0x68, 0x1a, 0x00, 0x80, 0x06, 0x4a, 0x91, 0x68, 0x4b, 0x1c, 0x93, 0x60, +0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x51, 0x69, 0x00, 0xe0, 0x00, 0x21, +0x01, 0x65, 0x50, 0x61, 0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, +0x90, 0xb4, 0x00, 0x21, 0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, +0x1b, 0x18, 0x9b, 0x8a, 0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, +0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xd3, 0x18, 0xdc, 0x1f, 0x49, 0x3c, +0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, +0x03, 0x2b, 0x02, 0xd0, 0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x31, +0x04, 0x29, 0xe4, 0xd3, 0x01, 0x20, 0xf8, 0xe7, 0xc8, 0x29, 0x00, 0x80, +0xf7, 0xb5, 0x86, 0xb0, 0x3d, 0x4a, 0x07, 0x1c, 0xd1, 0x69, 0x8f, 0x40, +0x03, 0x1c, 0x14, 0x6a, 0xe3, 0x40, 0x5f, 0x40, 0x07, 0x9e, 0x8e, 0x40, +0x77, 0x40, 0xcf, 0x40, 0x94, 0x69, 0xc0, 0x46, 0x05, 0x94, 0x03, 0x1c, +0xa3, 0x40, 0x00, 0x25, 0x14, 0x69, 0xc0, 0x46, 0x04, 0x94, 0x00, 0x2c, +0x5d, 0xd9, 0x1c, 0x1c, 0x32, 0x4e, 0x26, 0x43, 0x94, 0x69, 0xe6, 0x40, +0x33, 0x1c, 0x03, 0x96, 0x53, 0x6a, 0xc0, 0x46, 0x02, 0x93, 0xd2, 0x6a, +0xc0, 0x46, 0x01, 0x92, 0xbb, 0x00, 0x02, 0x9a, 0xd2, 0x58, 0x13, 0x1c, +0x05, 0x9c, 0xe3, 0x40, 0x03, 0x9c, 0xa3, 0x42, +0x3e, 0xd1, 0x8a, 0x40, 0xca, 0x40, 0x14, 0x1c, 0x63, 0x00, 0x1b, 0x19, +0x5b, 0x01, 0x01, 0x9a, 0xd2, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, +0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, +0x2c, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x51, 0x36, 0x33, 0x43, +0x1b, 0x68, 0x07, 0x9e, 0x1e, 0x40, 0x00, 0x96, 0x01, 0x23, 0x9b, 0x07, +0xd6, 0x1d, 0x49, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x83, 0x42, 0x1b, 0xd1, +0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x4d, 0x36, 0x33, 0x43, 0x1b, 0x68, +0x00, 0x9e, 0xb3, 0x42, 0x12, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, +0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x08, 0x9b, 0x32, 0x2b, 0x04, 0xd1, +0x02, 0x2a, 0x07, 0xd1, 0x20, 0x04, 0x00, 0x14, 0x0f, 0xe0, 0x08, 0x9b, +0x33, 0x2b, 0x01, 0xd1, 0x01, 0x2a, 0xf7, 0xd0, 0x04, 0x9a, 0x01, 0x37, +0x97, 0x42, 0x00, 0xd3, 0x00, 0x27, 0x04, 0x9a, 0x01, 0x35, 0xaa, 0x42, +0xae, 0xd8, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0xf0, 0xb5, 0x27, 0x4d, 0x68, 0x69, 0x00, 0x28, 0x06, 0xd0, 0x26, 0x48, +0x00, 0x68, 0x02, 0xf0, 0x31, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x23, 0x4c, 0x00, 0x26, 0xa0, 0x68, 0x23, 0x4f, 0x00, 0x28, 0x16, 0xd0, +0x0f, 0xe0, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, +0x0f, 0xe0, 0xa6, 0x60, 0xfd, 0xf7, 0x08, 0xff, 0x00, 0x28, 0xea, 0xd1, +0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, +0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe9, 0xd0, 0x68, 0x68, +0x00, 0x28, 0x1b, 0xd0, 0x01, 0x20, 0xa0, 0x60, 0xfe, 0xf7, 0xd2, 0xfb, +0x00, 0x28, 0xd6, 0xd1, 0x68, 0x68, 0x00, 0x28, 0xf6, 0xd1, 0x11, 0xe0, +0x00, 0x28, 0xd0, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, +0x38, 0x71, 0xca, 0xe7, 0xa6, 0x60, 0xfd, 0xf7, 0xe3, 0xfe, 0x00, 0x28, +0xc5, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, +0xe8, 0x68, 0x00, 0x28, 0xbd, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe7, 0xd0, +0xb9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xdc, 0x03, 0x00, 0x80, +0xc8, 0x29, 0x00, 0x80, 0x0c, 0x06, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, +0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, +0x1d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 0x9f, 0xfc, 0x03, 0x23, +0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0c, 0x0f, 0x61, 0x01, 0x09, 0x1b, +0x89, 0x00, 0x18, 0x4a, 0x8f, 0x18, 0x01, 0x21, 0x39, 0x80, 0x81, 0x6a, +0xc0, 0x46, 0x79, 0x65, 0x41, 0x6a, 0xc0, 0x46, 0x79, 0x67, 0xb9, 0x6c, +0xfa, 0x6c, 0x89, 0x18, 0xb9, 0x64, 0x00, 0x21, 0xf9, 0x64, 0xba, 0x6b, +0x3b, 0x6d, 0xd2, 0x18, 0xba, 0x63, 0x39, 0x65, 0x42, 0x6a, 0x20, 0x32, +0x51, 0x71, 0x79, 0x6d, 0x7a, 0x6f, 0xd2, 0x6d, 0xc0, 0x46, 0x11, 0x60, +0xfd, 0xf7, 0x10, 0xf8, 0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, +0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0x78, 0x6f, +0x01, 0xf0, 0xc8, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, +0xf0, 0xb5, 0x40, 0x20, 0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, +0x5b, 0xfc, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, +0x1b, 0x07, 0x18, 0x40, 0x06, 0x0f, 0x70, 0x01, 0x80, 0x1b, 0x80, 0x00, +0x0c, 0x49, 0x44, 0x18, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x78, 0x6a, +0xc0, 0x46, 0x60, 0x67, 0x80, 0x6f, 0x05, 0x1d, 0xe5, 0x63, 0xb9, 0x69, +0x28, 0x1c, 0x02, 0xf0, 0x8f, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x32, 0x1c, +0x2b, 0x1c, 0x00, 0xf0, 0x20, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0xf0, 0xb5, 0x4b, 0x6f, +0x9b, 0x6f, 0x1f, 0x1d, 0xcf, 0x63, 0x05, 0x68, 0x00, 0x23, 0x84, 0x69, +0xa4, 0x08, 0x08, 0xd0, 0x9c, 0x00, 0x2e, 0x59, 0xc0, 0x46, 0x3e, 0x51, +0x84, 0x69, 0xa4, 0x08, 0x01, 0x33, 0x9c, 0x42, 0xf6, 0xd8, 0x3b, 0x1c, +0x00, 0xf0, 0x03, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, +0x81, 0xb0, 0x04, 0x1c, 0x1d, 0x1c, 0x0f, 0x1c, 0x46, 0x48, 0x01, 0x69, +0x01, 0x31, 0x01, 0x61, 0xf9, 0x1d, 0x51, 0x31, 0xbd, 0x65, 0x00, 0x91, +0x20, 0x1c, 0xfd, 0xf7, 0xa3, 0xfc, 0xf8, 0x6d, 0x40, 0x09, 0x36, 0xd2, +0xb8, 0x6d, 0x06, 0x7b, 0x43, 0x7b, 0x1b, 0x02, 0x1e, 0x43, 0x17, 0x21, +0x49, 0x02, 0x01, 0x73, 0x0b, 0x0a, 0x43, 0x73, 0x00, 0x99, 0x20, 0x1c, +0xfd, 0xf7, 0x92, 0xfc, 0xb8, 0x6d, 0xc0, 0x46, 0x06, 0x73, 0x33, 0x0a, +0x43, 0x73, 0xf8, 0x6d, 0x40, 0x09, 0x20, 0xd2, 0x60, 0x68, 0x01, 0x04, +0x09, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0xce, 0xfc, 0x60, 0x68, 0x32, 0x4b, +0x18, 0x43, 0x60, 0x60, 0x20, 0x1c, 0x01, 0xf0, 0x37, 0xfd, 0x00, 0x25, +0x7d, 0x60, 0xbd, 0x60, 0x3d, 0x64, 0x7d, 0x64, 0x20, 0x1c, 0xfc, 0xf7, +0x77, 0xff, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0x7d, 0x62, +0x29, 0x48, 0xc0, 0x46, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xa0, 0xfb, +0x44, 0xe0, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, +0x00, 0x68, 0xc0, 0x46, 0x78, 0x64, 0x60, 0x68, 0x02, 0x04, 0x12, 0x0c, +0x78, 0x6e, 0x01, 0x26, 0xc1, 0x1d, 0x0d, 0x31, 0x8a, 0x42, 0x02, 0xd2, +0x3a, 0x64, 0x08, 0x1c, 0x0e, 0xe0, 0x41, 0x19, 0x89, 0x89, 0xf0, 0x23, +0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, +0x61, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x81, 0x42, 0x16, 0xd2, 0x39, 0x64, +0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, +0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, +0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, +0x20, 0x1c, 0x00, 0xf0, 0xbf, 0xfb, 0x0b, 0xe0, 0xb9, 0x68, 0x08, 0x1a, +0x00, 0x25, 0x78, 0x62, 0xbd, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x3c, 0xfc, +0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x64, 0xf8, 0x05, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0x01, 0x00, 0x00, 0xc0, 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x6c, +0xf9, 0x6b, 0x0d, 0x18, 0x21, 0x68, 0x41, 0x18, 0x00, 0x20, 0xa2, 0x69, +0x00, 0x2a, 0x0b, 0xd9, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, +0x33, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xab, 0x50, 0xa2, 0x69, 0x01, 0x30, +0x82, 0x42, 0xf3, 0xd8, 0x78, 0x6e, 0xf9, 0x6b, 0x09, 0x18, 0x89, 0x89, +0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, +0xf9, 0x61, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, +0x01, 0x68, 0x78, 0x6c, 0xfc, 0xf7, 0xdb, 0xff, +0x78, 0x64, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0xf8, 0x68, 0x81, 0x42, +0x19, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, +0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, +0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, +0x56, 0xfa, 0x01, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x5e, 0xfb, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb9, 0x68, 0x08, 0x1a, 0x78, 0x62, +0x00, 0x20, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xd9, 0xfb, 0x20, 0x1c, +0x39, 0x1c, 0x00, 0xf0, 0x01, 0xf8, 0xef, 0xe7, 0xf0, 0xb5, 0x84, 0xb0, +0x04, 0x1c, 0x0f, 0x1c, 0x8e, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, +0x03, 0x20, 0x00, 0x07, 0x61, 0x68, 0x08, 0x40, 0x06, 0x0f, 0x0a, 0x04, +0x12, 0x0c, 0x20, 0x68, 0x11, 0x18, 0xfb, 0x68, 0xd2, 0x1a, 0x7b, 0x68, +0x9d, 0x1a, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, +0x26, 0xfa, 0x00, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x2e, 0xfb, +0x60, 0x68, 0x40, 0x19, 0x01, 0x04, 0x09, 0x0c, 0x60, 0x60, 0x30, 0x1c, +0x01, 0xf0, 0xe2, 0xfb, 0x7d, 0x4e, 0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, +0xc0, 0x68, 0x00, 0x28, 0x19, 0xd0, 0x00, 0x25, 0x2d, 0x23, 0x9b, 0x01, +0xf0, 0x18, 0x80, 0x68, 0x00, 0x28, 0x12, 0xd0, 0xaa, 0x00, 0x92, 0x19, +0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x92, 0x68, 0x20, 0x1c, 0x39, 0x1c, +0x01, 0xf0, 0x22, 0xfe, 0x01, 0x35, 0xa8, 0x00, 0x80, 0x19, 0x2d, 0x23, +0x9b, 0x01, 0xc0, 0x18, 0x80, 0x68, 0x00, 0x28, 0xec, 0xd1, 0xf8, 0x6b, +0x01, 0x1f, 0x8a, 0x1c, 0xfa, 0x63, 0xfa, 0x68, 0x7d, 0x6c, 0x00, 0xf0, +0xbb, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xfc, 0xf7, +0x56, 0xff, 0x03, 0x90, 0xf9, 0x6b, 0x3a, 0x6e, 0x8e, 0x18, 0x20, 0x68, +0x12, 0x18, 0x01, 0x92, 0x7a, 0x6e, 0x8d, 0x18, 0x11, 0x18, 0x02, 0x91, +0xc8, 0x1d, 0x09, 0x30, 0xe0, 0x60, 0xb1, 0x88, 0x08, 0x02, 0x09, 0x0a, +0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x78, 0x61, +0x68, 0x68, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, +0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, +0x00, 0x06, 0x08, 0x43, 0x38, 0x61, 0xa8, 0x89, 0x09, 0x23, 0x1b, 0x02, +0x18, 0x40, 0xb8, 0x61, 0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, +0x02, 0x99, 0xc0, 0x46, 0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, +0x70, 0x81, 0x68, 0x60, 0x28, 0x82, 0xb9, 0x6e, 0x30, 0x1c, 0xfc, 0xf7, +0x2e, 0xff, 0x38, 0x86, 0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, +0x49, 0xff, 0x78, 0x86, 0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, +0x0e, 0xff, 0x00, 0x90, 0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, +0x41, 0x1a, 0x09, 0x04, 0x09, 0x0c, 0x7a, 0x6e, 0x82, 0x1a, 0x13, 0x04, +0x1b, 0x0c, 0x1a, 0x02, 0x1b, 0x0a, 0x1a, 0x43, 0x16, 0x04, 0x36, 0x0c, +0xba, 0x68, 0x82, 0x42, 0x01, 0xd2, 0x00, 0x20, 0x00, 0xe0, 0x10, 0x1a, +0xb8, 0x60, 0x08, 0x02, 0x09, 0x12, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, +0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x28, 0x1c, +0xfc, 0xf7, 0xe9, 0xfe, 0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, +0xe4, 0xfe, 0x06, 0x1c, 0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, +0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, +0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0xd5, 0xfe, +0x79, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x79, 0x61, 0x01, 0x9a, 0xc0, 0x46, +0x50, 0x81, 0x38, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, +0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, +0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x30, 0x1c, 0xfc, 0xf7, 0xbd, 0xfe, +0x39, 0x69, 0x7a, 0x68, 0x89, 0x18, 0x39, 0x61, 0xb9, 0x68, 0x00, 0x29, +0x09, 0xd1, 0x02, 0x99, 0x89, 0x89, 0xba, 0x69, 0x11, 0x43, 0x02, 0x9a, +0xc0, 0x46, 0x91, 0x81, 0xb9, 0x69, 0xfc, 0xf7, 0xac, 0xfe, 0x20, 0x82, +0x00, 0x20, 0x60, 0x82, 0xf8, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, +0x0a, 0xd3, 0x60, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, +0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x08, 0x82, 0x09, 0xe0, +0x60, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, +0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x88, 0x81, 0x04, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, +0xf1, 0xb5, 0x84, 0xb0, 0x6e, 0x4d, 0x28, 0x69, 0x01, 0x22, 0x04, 0x99, +0x8a, 0x40, 0x90, 0x43, 0x28, 0x61, 0x04, 0x98, 0x43, 0x01, 0x18, 0x1a, +0x80, 0x00, 0x16, 0x1c, 0x69, 0x49, 0x44, 0x18, 0xe0, 0x6b, 0xc0, 0x46, +0x00, 0x90, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x00, 0x26, 0x26, 0xe0, +0x65, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x04, 0x98, 0xfc, 0xf7, +0x4f, 0xfd, 0x07, 0x1c, 0x03, 0xd1, 0x28, 0x69, 0x30, 0x43, 0x28, 0x61, +0xb5, 0xe0, 0xa0, 0x68, 0x65, 0x68, 0xa8, 0x42, 0x00, 0xd2, 0x05, 0x1c, +0xa1, 0x6c, 0xa9, 0x42, 0x16, 0xd2, 0x40, 0x1a, 0x62, 0x6a, 0x10, 0x1a, +0x00, 0x26, 0x60, 0x62, 0xa6, 0x60, 0xa6, 0x62, 0x20, 0x88, 0x48, 0x23, +0x18, 0x43, 0x20, 0x80, 0x0d, 0x1c, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, +0x5f, 0xfd, 0x03, 0x20, 0x60, 0x80, 0x66, 0x60, 0x20, 0x1c, 0x00, 0xf0, +0x8d, 0xf9, 0x96, 0xe0, 0xe1, 0x68, 0x38, 0x68, 0x09, 0x18, 0xc3, 0x1f, +0x05, 0x3b, 0x20, 0x1c, 0x02, 0x39, 0x2a, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, +0x38, 0x1c, 0x00, 0xf0, 0xd7, 0xf9, 0xe0, 0x68, 0x46, 0x19, 0x78, 0x68, +0x30, 0x43, 0x78, 0x60, 0x04, 0x98, 0x31, 0x1c, 0x01, 0xf0, 0x8a, 0xfa, +0x21, 0x6e, 0x00, 0x98, 0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, +0x00, 0x0c, 0x61, 0x6e, 0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, +0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x91, 0x01, 0x02, +0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, +0x41, 0x80, 0x20, 0x8e, 0xfc, 0xf7, 0x11, 0xfe, 0x06, 0x1c, 0x60, 0x8e, +0x02, 0x99, 0xfc, 0xf7, 0x0c, 0xfe, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, +0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, +0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xfd, 0xfd, +0x61, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x61, 0x61, 0x01, 0x99, 0xc0, 0x46, +0x48, 0x81, 0x60, 0x6e, 0x00, 0x99, 0x46, 0x18, 0x20, 0x69, 0x01, 0x0e, +0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, +0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, +0x71, 0x60, 0x03, 0x98, 0xfc, 0xf7, 0xe1, 0xfd, 0x21, 0x69, 0x49, 0x19, +0x21, 0x61, 0xa1, 0x68, 0x49, 0x1b, 0xa1, 0x60, +0x06, 0xd1, 0xb1, 0x89, 0xa2, 0x69, 0x11, 0x43, 0xb1, 0x81, 0xa1, 0x69, +0xfc, 0xf7, 0xd3, 0xfd, 0x38, 0x82, 0x61, 0x6e, 0x38, 0x68, 0x09, 0x18, +0x0e, 0x31, 0xf9, 0x60, 0xe2, 0x68, 0x00, 0x99, 0x04, 0x38, 0x00, 0xf0, +0x4c, 0xf8, 0x02, 0x20, 0x78, 0x82, 0xe0, 0x6d, 0x41, 0x08, 0x16, 0xd3, +0x80, 0x0a, 0x0a, 0xd3, 0x78, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, +0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0xc8, 0x81, +0x09, 0xe0, 0x78, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, +0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0x48, 0x81, 0x05, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, +0xc8, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x03, 0x1c, +0x0f, 0x1c, 0x00, 0x20, 0x1c, 0x68, 0x26, 0x04, 0x31, 0x1c, 0x1d, 0x1d, +0xfc, 0xf7, 0x97, 0xfd, 0x40, 0xc7, 0x02, 0x9a, 0xd1, 0x1c, 0x89, 0x08, +0x01, 0x39, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 0x0d, 0xd0, 0x21, 0x0c, +0x10, 0xcd, 0x22, 0x04, 0x0a, 0x43, 0x11, 0x1c, 0x16, 0x1c, 0xfc, 0xf7, +0x86, 0xfd, 0x40, 0xc7, 0x02, 0x99, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, +0xf1, 0xd1, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x08, +0x80, 0x00, 0x89, 0x08, 0x89, 0x00, 0x03, 0x32, 0x93, 0x08, 0x5a, 0x1e, +0x00, 0x2b, 0x05, 0xd0, 0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, 0x3a, +0x00, 0x2b, 0xf9, 0xd1, 0x70, 0x47, 0xff, 0xb5, 0x86, 0xb0, 0x17, 0x1c, +0x00, 0x26, 0x06, 0x98, 0x80, 0x6c, 0xc0, 0x1b, 0x06, 0x99, 0xc0, 0x46, +0x88, 0x64, 0x01, 0x20, 0xc0, 0x05, 0x06, 0x99, 0x89, 0x6b, 0xc0, 0x46, +0x01, 0x91, 0x06, 0x99, 0x4c, 0x6b, 0x67, 0xe0, 0x21, 0x68, 0xc0, 0x46, +0x02, 0x91, 0x61, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa1, 0x68, 0xc0, 0x46, +0x04, 0x91, 0x02, 0xa9, 0x49, 0x88, 0xb9, 0x42, 0x08, 0xd2, 0x02, 0xad, +0x6d, 0x88, 0x02, 0xa9, 0x49, 0x88, 0x7f, 0x1a, 0x00, 0x21, 0x02, 0xab, +0x59, 0x80, 0x19, 0xe0, 0x02, 0xa9, 0x49, 0x88, 0xc9, 0x1b, 0x02, 0xab, +0x59, 0x80, 0x3d, 0x1c, 0x00, 0x27, 0x01, 0x21, 0x49, 0x06, 0x07, 0x9b, +0x9a, 0x07, 0x92, 0x0f, 0x0d, 0xd0, 0xeb, 0x06, 0xdb, 0x0e, 0x08, 0xd0, +0x1e, 0x2b, 0x08, 0xd3, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x2a, 0x04, 0xd1, +0x01, 0xe0, 0x02, 0x2a, 0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, +0x01, 0x43, 0x0a, 0x1c, 0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, +0x07, 0x9b, 0x01, 0xf0, 0x61, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, +0x00, 0x2e, 0x0a, 0xd0, 0x1d, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x1d, 0x48, +0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x52, 0xff, +0x00, 0x26, 0x02, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0c, 0xd0, 0x03, 0x98, +0x40, 0x19, 0x03, 0x90, 0x02, 0x98, 0xc0, 0x46, 0x20, 0x60, 0x03, 0x98, +0xc0, 0x46, 0x60, 0x60, 0x04, 0x98, 0xc0, 0x46, 0xa0, 0x60, 0x03, 0xe0, +0x01, 0x98, 0x01, 0x38, 0x01, 0x90, 0x10, 0x34, 0x06, 0x98, 0xc0, 0x46, +0x44, 0x63, 0x01, 0x98, 0x06, 0x99, 0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, +0x00, 0x2f, 0x02, 0xd0, 0x01, 0x99, 0x00, 0x29, 0x92, 0xd1, 0x09, 0x4a, +0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, +0x09, 0x9b, 0x01, 0xf0, 0x25, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, +0xf8, 0x28, 0x00, 0x80, 0x04, 0x00, 0x53, 0x02, 0x90, 0xb5, 0x0c, 0x1c, +0x07, 0x1c, 0x38, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, +0x01, 0x68, 0x38, 0x8a, 0xfc, 0xf7, 0xcb, 0xfc, 0xc0, 0x43, 0xf9, 0x68, +0xc0, 0x46, 0x08, 0x80, 0x78, 0x8a, 0x39, 0x68, 0x08, 0x1a, 0x38, 0x60, +0x38, 0x1c, 0x01, 0xf0, 0x8d, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0xd2, 0xfb, +0x20, 0x1c, 0xff, 0xf7, 0x33, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x80, 0xb5, 0x01, 0x88, 0x8a, 0x09, 0x21, 0xd3, 0xca, 0x09, 0x1f, 0xd2, +0x8a, 0x08, 0x1d, 0xd3, 0x00, 0x21, 0x01, 0x80, 0x41, 0x80, 0x47, 0x6f, +0x40, 0x6d, 0xfa, 0x1d, 0x19, 0x32, 0x51, 0x71, 0xfa, 0x6d, 0xc0, 0x46, +0x10, 0x60, 0x3a, 0x6e, 0xc0, 0x46, 0x10, 0x60, 0x0c, 0x48, 0xc0, 0x46, +0x41, 0x63, 0x81, 0x6b, 0x49, 0x08, 0x49, 0x00, 0x81, 0x63, 0x01, 0x20, +0x00, 0xf0, 0xce, 0xff, 0x38, 0x1c, 0x00, 0xf0, 0x6d, 0xff, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, +0x49, 0x09, 0xf6, 0xd2, 0x00, 0xf0, 0xb0, 0xf8, 0xf3, 0xe7, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0x10, 0x1c, 0x0d, 0x1c, +0x00, 0x24, 0x5e, 0x1e, 0x00, 0x2b, 0x19, 0xd0, 0x01, 0x68, 0xc0, 0x46, +0x39, 0x60, 0x41, 0x88, 0x0c, 0x19, 0x41, 0x68, 0xc0, 0x46, 0x79, 0x60, +0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0xc1, 0x68, 0xc0, 0x46, 0xf9, 0x60, +0x10, 0x30, 0x10, 0x37, 0xe9, 0x6a, 0x81, 0x42, 0x02, 0xd8, 0x28, 0x1c, +0x00, 0xf0, 0xee, 0xff, 0x31, 0x1c, 0x01, 0x3e, 0x00, 0x29, 0xe5, 0xd1, +0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0xc1, 0x61, +0x05, 0x49, 0x0a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 0x08, 0x60, 0x02, 0xe0, +0x4a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, +0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x08, 0x68, 0x00, 0x28, 0x02, 0xd0, +0xc2, 0x69, 0xc0, 0x46, 0x0a, 0x60, 0x70, 0x47, 0x3c, 0x2c, 0x00, 0x80, +0x00, 0x21, 0x81, 0x67, 0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1, +0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 0x90, 0x67, 0xc8, 0x60, +0x70, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68, +0x00, 0x28, 0x02, 0xd0, 0x82, 0x6f, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47, +0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, +0x08, 0x60, 0xff, 0xf7, 0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, +0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0a, 0x0f, 0x51, 0x01, 0x89, 0x1a, +0x89, 0x00, 0x0d, 0x4b, 0xc9, 0x18, 0x4b, 0x88, 0x00, 0x2b, 0x04, 0xd1, +0x11, 0x1c, 0xff, 0xf7, 0x3b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x2b, +0x02, 0xd1, 0xff, 0xf7, 0x05, 0xfc, 0xf8, 0xe7, 0x02, 0x2b, 0xf6, 0xd1, +0xff, 0xf7, 0x4e, 0xfb, 0xf3, 0xe7, 0x04, 0x48, 0x01, 0x6d, 0x01, 0x31, +0x01, 0x65, 0xee, 0xe7, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, +0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x20, 0x20, 0x0d, 0x49, 0xc0, 0x46, +0x08, 0x60, 0xff, 0xf7, 0xbf, 0xff, 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x88, +0x20, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 0x10, 0x23, 0x99, 0x43, +0x01, 0x80, 0x01, 0x88, 0x09, 0x0a, 0x01, 0xd3, 0xff, 0xf7, 0x2e, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x03, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, +0xf8, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x07, 0x1c, 0x22, 0x48, 0xc0, 0x46, +0x00, 0x90, 0x22, 0x48, 0xc3, 0x1d, 0x41, 0x33, 0x41, 0x6d, 0x82, 0x6d, +0x80, 0x6c, 0x00, 0x03, 0x00, 0x0b, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, +0x23, 0x43, 0x1b, 0x68, 0x98, 0x42, 0x00, 0xd1, 0x0c, 0xe0, 0x98, 0x42, +0x03, 0xd9, 0x10, 0x1a, 0x59, 0x1a, 0x41, 0x18, 0x00, 0xe0, 0x19, 0x1a, +0x01, 0x20, 0x10, 0x29, 0x00, 0xd8, 0x00, 0x20, 0x00, 0x28, 0x1f, 0xd0, +0x78, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0xb8, 0x6a, 0xf9, 0x6a, +0xc0, 0x46, 0x48, 0x60, 0x10, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xfb, 0x6a, +0x0f, 0x48, 0x42, 0x6d, 0x03, 0x20, 0x39, 0x6a, 0x01, 0xf0, 0xe8, 0xfd, +0x38, 0x88, 0x10, 0x23, 0x18, 0x43, 0x38, 0x80, 0x38, 0x88, 0x40, 0x23, +0x98, 0x43, 0x38, 0x80, 0x38, 0x1c, 0xff, 0xf7, 0x55, 0xff, 0x98, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, +0xf7, 0xe7, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, +0x08, 0x00, 0x11, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xb0, 0xb5, 0x40, 0x20, +0x2c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, 0xff, 0xfe, 0x07, 0x1c, +0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x05, 0x0f, 0x68, 0x01, +0x40, 0x1b, 0x80, 0x00, 0x26, 0x49, 0x44, 0x18, 0x20, 0x88, 0x02, 0x23, +0x18, 0x43, 0x20, 0x80, 0x20, 0x88, 0x41, 0x08, 0x34, 0xd3, 0x40, 0x08, +0x40, 0x00, 0x20, 0x80, 0xa0, 0x6c, 0xe1, 0x6c, 0x40, 0x18, 0xa0, 0x64, +0x00, 0x20, 0xe0, 0x64, 0xa1, 0x6b, 0x22, 0x6d, 0x89, 0x18, 0xa1, 0x63, +0x20, 0x65, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x03, 0x23, 0x1b, 0x07, +0x78, 0x68, 0x18, 0x40, 0x78, 0x60, 0x61, 0x68, 0x36, 0x31, 0x94, 0x29, +0x04, 0xd8, 0x38, 0x23, 0x18, 0x43, 0x78, 0x60, 0x38, 0x20, 0x03, 0xe0, +0x94, 0x23, 0x18, 0x43, 0x78, 0x60, 0x94, 0x20, 0xb8, 0x61, 0x39, 0x68, +0x78, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x20, 0x1c, 0xcb, 0x1f, 0x05, 0x3b, +0xff, 0xf7, 0xd7, 0xfd, 0x02, 0x20, 0x60, 0x80, 0x38, 0x1c, 0xff, 0xf7, +0xdf, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfc, 0xf7, +0x4d, 0xfa, 0x28, 0x01, 0x06, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, +0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xef, 0xe7, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, +0x90, 0xb5, 0x00, 0x27, 0x0f, 0x4c, 0x0d, 0xe0, 0x02, 0x6b, 0x01, 0x3a, +0x02, 0x63, 0x00, 0x2a, 0x05, 0xdc, 0xc2, 0x6a, 0xc0, 0x46, 0x02, 0x63, +0x80, 0x6a, 0x01, 0xf0, 0xcc, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, +0x38, 0x01, 0x00, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x41, 0x6a, +0x00, 0x29, 0xe9, 0xd1, 0x01, 0x20, 0x40, 0x06, 0x03, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x00, 0x00, 0xb0, 0x11, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, +0x10, 0x49, 0xc8, 0x68, 0x01, 0x28, 0x19, 0xd1, 0xc8, 0x1d, 0x79, 0x30, +0x82, 0x88, 0x00, 0x2a, 0x14, 0xd0, 0x01, 0x3a, 0x82, 0x80, 0x82, 0x88, +0x00, 0x2a, 0x0f, 0xd1, 0xc2, 0x88, 0x00, 0x2a, 0x0a, 0xd1, 0x02, 0x23, +0xca, 0x6f, 0x1a, 0x43, 0xca, 0x67, 0x07, 0x49, 0xc0, 0x46, 0x0a, 0x60, +0x04, 0x21, 0x81, 0x80, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xc1, 0x80, +0x70, 0x47, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xb0, 0xb5, 0x07, 0x1c, +0x01, 0x23, 0xf8, 0x1d, 0x69, 0x30, 0x03, 0x73, 0x1d, 0x49, 0xca, 0x1d, +0x79, 0x32, 0xd4, 0x89, 0x60, 0x1c, 0xd0, 0x81, 0x55, 0x8a, 0x00, 0x20, +0xac, 0x42, 0x02, 0xdb, 0x53, 0x73, 0xd0, 0x81, 0x50, 0x83, 0x01, 0x23, +0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 0xc0, 0x46, 0xba, 0x61, +0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 0x12, 0x49, 0xc0, 0x46, +0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x61, 0x48, 0x69, +0xfa, 0x6c, 0x90, 0x43, 0x48, 0x61, 0x01, 0x21, 0x09, 0x05, 0xc8, 0x60, +0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 0xf9, 0x69, 0x41, 0x1a, +0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, +0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 0x81, 0x42, 0xe2, 0xd3, +0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0xff, 0x23, +0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 0x21, 0x37, 0xe1, 0x6e, +0x38, 0x1c, 0x01, 0xf0, 0xcf, 0xfc, 0x2d, 0x4d, 0x00, 0x28, 0x13, 0xd1, +0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 0x19, 0x43, 0x01, 0x72, +0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 0x01, 0x6d, 0x42, 0x6d, +0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb4, 0xfc, 0x00, 0x20, 0xf8, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 0x20, 0x61, 0x23, 0x49, +0xc8, 0x1d, 0xb9, 0x30, 0xc2, 0x6a, 0x92, 0x00, 0x51, 0x18, 0xc0, 0x31, +0xcf, 0x60, 0xc1, 0x6a, 0x01, 0x31, 0x89, 0x07, 0x89, 0x0f, 0xc1, 0x62, +0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 0x03, 0xd8, 0x23, 0x22, +0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 0x7e, 0x1a, 0x07, 0xd1, +0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18, +0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x0a, 0x43, 0x00, 0x92, +0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 0x2b, 0x1c, 0x01, 0xf0, +0x81, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 0x00, 0x92, 0x61, 0x6e, +0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0x77, 0xfc, 0x20, 0x6b, +0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 0x81, 0x42, 0x00, 0xd8, +0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7, 0x44, 0x80, 0x20, 0x40, +0x04, 0x00, 0x1b, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, +0x80, 0xb5, 0x01, 0x20, 0xc0, 0x03, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, +0x0c, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x27, 0x00, 0x2a, +0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x08, 0x49, +0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, +0x08, 0x1c, 0xff, 0xf7, 0x2f, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x00, 0x00, 0xb0, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, +0x90, 0xb5, 0x07, 0x1c, 0x10, 0x20, 0x18, 0x49, 0xc0, 0x46, 0x08, 0x60, +0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x16, 0x48, 0xc4, 0x1d, 0xb9, 0x34, +0x21, 0x6b, 0x89, 0x00, 0x09, 0x18, 0xc0, 0x31, 0xc9, 0x68, 0x7a, 0x68, +0x92, 0x00, 0xd2, 0x19, 0x51, 0x64, 0x21, 0x6b, 0x89, 0x00, 0x08, 0x18, +0xc0, 0x30, 0xc1, 0x68, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, +0x01, 0xf0, 0xa6, 0xfa, 0x01, 0x23, 0x78, 0x68, +0x58, 0x40, 0x78, 0x60, 0x20, 0x6b, 0x01, 0x30, 0x80, 0x07, 0x80, 0x0f, +0x20, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 0x00, 0x28, 0x02, 0xd1, +0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, +0x39, 0x48, 0x80, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xb8, 0x6a, 0xc0, 0x68, +0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 0x78, 0x6f, 0xfc, 0xf7, +0x9d, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31, +0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x6c, 0x2f, 0x49, +0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, +0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0x00, 0xf0, +0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 0x09, 0x18, 0x09, 0x09, +0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 0x89, 0x1a, 0xa1, 0x62, +0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 0x00, 0x2a, 0x07, 0xd0, +0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 0x80, 0x00, 0xb9, 0x6a, +0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 0x80, 0x00, 0xc0, 0x19, +0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 0x41, 0x64, 0xb8, 0x6a, +0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 0x40, 0x1a, 0xb8, 0x62, +0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 0x40, 0x18, 0xb8, 0x62, +0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 0x00, 0x29, 0xb8, 0xd1, +0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 0x3a, 0x6c, 0x91, 0x42, +0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 0x80, 0x00, 0xc0, 0x19, +0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x01, 0xd0, +0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 0xa1, 0xd0, 0x01, 0x38, +0x38, 0x61, 0x9e, 0xe7, 0xe8, 0x18, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, +0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x20, 0x05, 0x90, +0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 0x80, 0x6a, 0xc0, 0x46, +0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 0x49, 0x6b, 0xc0, 0x46, +0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 0xc0, 0x46, 0xa8, 0x60, +0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 0xf0, 0x48, 0xc0, 0x46, +0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a, 0xc1, 0x1b, 0x09, 0x09, +0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46, 0x0f, 0x93, 0xeb, 0x4b, +0xc0, 0x46, 0x0e, 0x93, 0x91, 0x42, 0x01, 0xd3, 0xb8, 0x42, 0x21, 0xd8, +0xe1, 0x68, 0x02, 0x29, 0x1e, 0xd2, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, +0x48, 0x71, 0x00, 0x20, 0x03, 0x99, 0x01, 0xf0, 0x5b, 0xfb, 0x00, 0x28, +0x03, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, 0x01, 0x30, 0x98, 0x63, 0x01, 0x20, +0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0xdd, 0x4a, 0xc0, 0x46, +0x00, 0x92, 0xdd, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0xdc, 0x4b, 0x00, 0x20, +0x01, 0xf0, 0x3e, 0xfb, 0x38, 0x1c, 0x5c, 0xe3, 0xb8, 0x42, 0x03, 0xd8, +0x20, 0x1c, 0x00, 0xf0, 0x7b, 0xfc, 0x07, 0x1c, 0xd7, 0x48, 0x80, 0x68, +0x00, 0x28, 0x64, 0xd0, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, +0x60, 0xd1, 0x05, 0x98, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x05, 0x90, +0x38, 0x78, 0xf0, 0x23, 0x18, 0x40, 0x58, 0xd1, 0xe0, 0x6a, 0xc0, 0x1b, +0x00, 0x09, 0x0c, 0x99, 0x88, 0x42, 0x02, 0xd2, +0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 0x88, 0x68, 0x00, 0xf0, +0x87, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 0x28, 0x1c, 0x39, 0x1c, +0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 0x2e, 0x62, 0xf8, 0x68, +0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x49, +0xc9, 0x68, 0x00, 0xf0, 0x74, 0xff, 0xf8, 0x89, 0x00, 0x28, 0x03, 0xd0, +0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x6d, 0xff, 0x7a, 0x68, 0xc0, 0x46, +0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 0x30, 0x1c, 0xb8, 0x49, +0x09, 0x68, 0x00, 0xf0, 0x62, 0xff, 0x00, 0x28, 0x17, 0xd1, 0x30, 0x1c, +0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x5b, 0xff, 0x10, 0x37, 0xe0, 0x6a, +0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x27, 0xfc, 0x07, 0x1c, +0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, +0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 0xb0, 0xe0, 0xa8, 0x69, +0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a, +0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 0xa4, 0xe0, 0x10, 0x28, +0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 0x18, 0x40, 0x01, 0x0f, +0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 0x82, 0x18, 0x01, 0x92, +0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 0x2f, 0xd3, 0x9d, 0x48, +0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x80, +0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, +0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, +0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, +0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x8f, 0x49, 0x40, 0x18, +0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 0x50, 0x68, 0x36, 0x30, +0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 0x94, 0x20, 0xa8, 0x61, +0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 0x58, 0xe0, 0x7a, 0x88, +0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x23, 0xe0, +0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 0x1d, 0xd0, 0x03, 0x93, +0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68, +0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46, +0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, +0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49, 0x40, 0x18, 0x01, 0x9a, +0xc0, 0x46, 0x50, 0x63, 0x02, 0xe0, 0x33, 0xe0, 0x2a, 0xe0, 0x03, 0x93, +0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x12, 0x9a, 0x50, 0x78, +0x05, 0x99, 0x43, 0x1a, 0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, +0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x92, 0xfb, 0x07, 0x1c, 0x01, 0x9a, +0x50, 0x6b, 0x91, 0x6b, 0x09, 0x01, 0x40, 0x18, 0x0b, 0x9b, 0x21, 0x1c, +0x3a, 0x1c, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x9a, 0xc0, 0x46, 0xd0, 0x64, +0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x13, 0x65, 0x01, 0x23, 0x5b, 0x06, +0x68, 0x68, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 0x0d, 0xe0, +0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, +0x71, 0xfb, 0x07, 0x1c, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, +0x00, 0xd1, 0xf8, 0xe6, 0xa8, 0x69, 0x03, 0x99, 0x01, 0xf0, 0x2a, 0xfa, +0x00, 0x28, 0x2a, 0xd1, 0x38, 0x1c, 0x21, 0x1c, +0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 0x04, 0xd3, 0x30, 0x1c, +0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x85, 0xfe, 0x41, 0x49, 0x00, 0x20, +0x01, 0xf0, 0x18, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, +0x01, 0x30, 0x98, 0x63, 0x11, 0xe0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, +0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0x3a, 0x4a, +0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x39, 0x4b, +0x00, 0x20, 0x01, 0xf0, 0xf7, 0xf9, 0x00, 0x20, 0x15, 0xe2, 0x05, 0x98, +0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x0c, 0x90, 0x0b, 0x90, +0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, +0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 0x00, 0x26, 0x00, 0x20, +0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 0x01, 0x38, 0x0d, 0x90, +0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 0x12, 0x0c, 0x90, 0x42, +0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x90, +0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x0d, 0x98, +0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 0x30, 0x18, 0x88, 0x42, +0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 0x1c, 0xe0, 0x11, 0x20, +0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd1, +0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 0x89, 0x0f, 0x0f, 0xd0, +0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 0x1e, 0x28, 0x09, 0xdb, +0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29, +0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 0x0a, 0x9a, 0x00, 0x2a, +0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90, +0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 0x00, 0x90, 0x04, 0x98, +0x83, 0x19, 0x1d, 0xe0, 0x68, 0x0e, 0x00, 0x80, 0x79, 0x48, 0xff, 0xff, +0xa8, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, +0x44, 0x80, 0x20, 0x40, 0xe8, 0x18, 0x00, 0x80, 0xe0, 0x03, 0x00, 0x80, +0x00, 0x00, 0x00, 0x80, 0xc8, 0x2a, 0x00, 0x80, 0xc9, 0x31, 0xff, 0xff, +0x58, 0x5f, 0x21, 0x40, 0x81, 0x3c, 0xff, 0xff, 0x41, 0x31, 0xff, 0xff, +0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, +0x6f, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98, 0x00, 0x28, 0x16, 0xd0, +0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1, 0x09, 0x23, 0x5b, 0x04, +0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 0x06, 0x98, 0xc2, 0x4a, 0x02, 0x43, +0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0xc1, 0x48, 0x01, 0x6d, 0x42, 0x6d, +0x00, 0x20, 0x01, 0xf0, 0x55, 0xf9, 0x00, 0x20, 0x02, 0x90, 0x08, 0x98, +0x00, 0x28, 0x0b, 0xd1, 0x0b, 0x9b, 0x01, 0x3b, 0x0b, 0x93, 0x10, 0x37, +0xe0, 0x6a, 0xb8, 0x42, 0x0c, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x8a, 0xfa, +0x07, 0x1c, 0x07, 0xe0, 0x78, 0x68, 0x07, 0x9a, 0x80, 0x18, 0x78, 0x60, +0x78, 0x88, 0x07, 0x9a, 0x80, 0x1a, 0x78, 0x80, 0x0a, 0x9a, 0x50, 0x1c, +0x02, 0x04, 0x12, 0x0c, 0x0a, 0x92, 0x0c, 0x98, 0x0a, 0x9a, 0x82, 0x42, +0x03, 0xda, 0xa9, 0x69, 0xb1, 0x42, 0x00, 0xd9, 0x53, 0xe7, 0xa8, 0x69, +0xb0, 0x42, 0x6b, 0xd1, 0xa8, 0x68, 0x01, 0x09, 0x69, 0xd2, 0x08, 0x9a, +0x00, 0x2a, 0x56, 0xd0, 0x0c, 0x99, 0x0a, 0x9a, 0x8a, 0x42, 0x3e, 0xdb, +0xb1, 0x07, 0x89, 0x0f, 0x0c, 0xd0, 0x08, 0x9a, +0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 0x06, 0xdb, 0x1e, 0x2a, +0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd2, +0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, +0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, +0x05, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, +0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x92, 0x48, 0x01, 0x22, +0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x8e, 0x48, 0x01, 0x6d, +0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xf0, 0xf8, 0x00, 0x20, 0x02, 0x90, +0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, +0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 0x00, 0xe0, 0x08, 0x9a, +0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, +0x06, 0xca, 0x01, 0xf0, 0xd9, 0xf8, 0x08, 0x98, 0x36, 0x18, 0x10, 0x37, +0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x14, 0xfa, +0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 0x0a, 0x98, 0xc0, 0x46, +0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 0x0d, 0x98, 0x09, 0x99, +0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 0x5f, 0xe0, 0x5e, 0xe0, +0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 0xa9, 0x68, 0x8c, 0x23, +0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 0x1a, 0x43, 0xb1, 0x07, +0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, +0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, +0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 0x02, 0x1c, 0x09, 0x98, +0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x1a, 0x43, 0x00, 0x92, +0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, +0x93, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 0x02, 0x98, 0x00, 0x28, +0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, +0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92, +0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, +0x01, 0xf0, 0x7a, 0xf8, 0x00, 0x20, 0x02, 0x90, 0xe0, 0x6a, 0xb8, 0x42, +0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 0x07, 0x1c, 0x09, 0x98, +0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, +0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x68, 0x60, +0xe8, 0x6a, 0x00, 0xf0, 0x7b, 0xfa, 0x28, 0xe0, 0x27, 0xe0, 0xa8, 0x68, +0x00, 0x09, 0x14, 0xd3, 0x68, 0x68, 0x80, 0x0e, 0x15, 0xd2, 0x01, 0x9a, +0x00, 0x2a, 0x12, 0xd0, 0x01, 0x9a, 0x50, 0x6b, 0x0b, 0x9b, 0x21, 0x1c, +0x3a, 0x1c, 0xff, 0xf7, 0x87, 0xf9, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, +0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x93, 0x63, 0x03, 0xe0, 0xe8, 0x6a, +0x31, 0x1c, 0x00, 0xf0, 0x5d, 0xfa, 0x68, 0x68, 0x30, 0x43, 0x68, 0x60, +0xa8, 0x69, 0xb0, 0x42, 0x05, 0xd9, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x1b, +0x00, 0xf0, 0xee, 0xf9, 0xae, 0x61, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, +0x0b, 0xd0, 0x2f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0xc3, 0x1f, +0x05, 0x3b, 0x2a, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, +0x27, 0xf8, 0x01, 0x23, 0x9b, 0x07, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, +0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42, +0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 0x41, 0x1a, 0x01, 0xd5, +0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 0x3f, 0xfb, 0xe1, 0x69, +0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 0x24, 0xd3, 0x40, 0x1a, +0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 0x20, 0x69, 0x02, 0x28, +0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 0x41, 0x69, 0xe2, 0x6c, +0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 0x99, 0x43, 0x81, 0x61, +0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x08, 0x61, +0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, +0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xce, 0xfa, +0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 0x05, 0x99, 0x40, 0x18, +0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xf8, 0x28, 0x00, 0x80, +0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 0xe8, 0x0d, 0x00, 0x80, +0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, +0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 0xa0, 0x6f, 0x00, 0xf0, +0x49, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x79, 0x68, +0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 0x24, 0x49, 0x40, 0x18, +0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x36, 0xe0, +0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x20, 0x4e, +0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xa9, 0x6b, 0x19, 0x43, 0xa9, 0x63, +0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xb9, 0x6a, 0x22, 0x6e, +0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd1, 0x69, 0x6b, +0x01, 0x31, 0x69, 0x63, 0x08, 0x29, 0x07, 0xd3, 0x68, 0x63, 0x01, 0x20, +0x00, 0xf0, 0x86, 0xf8, 0xa8, 0x6b, 0x40, 0x08, 0x40, 0x00, 0xa8, 0x63, +0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 0x1b, 0x02, 0xf1, 0x18, +0x89, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 0x04, 0xd2, 0x20, 0x1c, +0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, +0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x4a, 0xfc, 0x20, 0x1c, 0x00, 0xf0, +0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, +0x1c, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30, 0x01, 0x79, 0x00, 0x29, +0x04, 0xd0, 0x00, 0x21, 0x01, 0x71, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xfb, +0xf8, 0x68, 0x02, 0x28, 0x0d, 0xd0, 0xb8, 0x68, 0x80, 0x00, 0xc2, 0x19, +0x50, 0x6c, 0x00, 0x28, 0x11, 0xd0, 0xb8, 0x6a, 0x41, 0x78, 0x09, 0x01, +0x10, 0x31, 0x52, 0x6b, 0x10, 0x1a, 0x88, 0x42, 0x05, 0xd3, 0x38, 0x1c, +0xff, 0xf7, 0x42, 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, +0xff, 0xf7, 0x2a, 0xfa, 0xf8, 0xe7, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, +0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf1, 0xe7, 0xb0, 0xb5, 0x87, 0xb0, +0x0f, 0x1c, 0x80, 0x6f, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 0x13, 0x4d, +0x0b, 0x23, 0x1b, 0x02, 0xe8, 0x18, 0x40, 0x69, 0x00, 0x28, 0x17, 0xd0, +0x69, 0x46, 0xa2, 0x00, 0x52, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xd2, 0x18, +0x52, 0x69, 0x38, 0x1c, 0x00, 0xf0, 0x96, 0xfb, 0x00, 0x28, 0x09, 0xd1, +0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x0b, 0x23, +0x1b, 0x02, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, +0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x9d, 0xf9, 0x07, 0xb0, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 0x16, 0x49, 0x01, 0xd0, +0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 0x0c, 0x22, 0xa4, 0x18, +0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 0x1c, 0x22, 0x0b, 0x68, +0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x7b, 0x00, 0x2d, 0x13, 0xd0, +0x5b, 0x7b, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 0x5b, 0x06, 0x1a, 0x43, +0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 0x00, 0x92, 0x4a, 0x68, +0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xe3, 0xfe, 0xb8, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 0x1a, 0x43, 0xf1, 0xe7, +0x3c, 0xef, 0x20, 0x40, 0xf8, 0x28, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, +0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x4a, 0x68, 0x00, 0x2a, 0x01, 0xd1, +0x48, 0x60, 0x02, 0xe0, 0x8a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x88, 0x60, +0x70, 0x47, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x80, 0x03, 0x49, 0x48, 0x68, +0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x4a, 0x60, 0x70, 0x47, +0xa8, 0x0e, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40, +0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x3a, +0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 0x53, 0x6b, 0xc0, 0x46, +0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 0x49, 0x6c, 0x53, 0x6c, +0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 0x92, 0x00, 0x52, 0x18, +0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 0x3d, 0x30, 0x0a, 0x68, +0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 0x9a, 0x1a, 0x02, 0x60, +0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x32, +0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 0x40, 0x18, 0x0a, 0x61, +0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 0xb8, 0xb5, 0x04, 0x1c, +0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xd9, 0xff, +0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x80, 0xfe, 0x01, 0x20, 0xf9, 0x1d, +0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 0x00, 0x20, 0xa0, 0x61, +0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, +0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x66, 0xfe, 0xb8, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, +0x44, 0x80, 0x20, 0x40, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, +0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, +0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 0x50, 0x2d, 0x00, 0x80, +0xa0, 0x82, 0x20, 0x40, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, +0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, +0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, +0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x03, 0x30, 0x80, 0x08, +0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, +0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, +0x0a, 0x71, 0x70, 0x47, 0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x02, 0x48, 0x41, 0x79, 0x01, 0x31, 0x41, 0x71, +0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x82, 0x00, +0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 0x89, 0x08, 0x0b, 0x1d, +0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 0xd7, 0x68, 0x12, 0x4c, +0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 0x03, 0xd1, 0x81, 0x42, +0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 0xb9, 0x42, 0x09, 0xd9, +0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, +0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 0x81, 0x42, 0x05, 0xd8, +0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x02, 0xd8, +0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 0x05, 0x30, 0xfa, 0xe7, +0xf0, 0x03, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 0x0f, 0x4a, 0x17, 0x58, +0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 0x01, 0xe0, 0x88, 0x08, +0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 0x09, 0xd9, 0x39, 0x68, +0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, +0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 0x38, 0x69, 0x00, 0xf0, +0xd5, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xf0, 0x03, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x01, 0x40, +0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 0x92, 0x07, 0x02, 0x40, +0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 0x89, 0x0f, 0x00, 0x04, +0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 0x01, 0x30, 0x00, 0x2a, +0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 0xf9, 0x68, 0x7a, 0x68, +0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, +0xf8, 0x68, 0x00, 0xf0, 0xa9, 0xfd, 0xf8, 0x60, 0x0f, 0x48, 0x00, 0x69, +0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 0x02, 0xd0, 0x20, 0x1c, +0xfe, 0xf7, 0xc8, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79, +0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 0xc8, 0x1d, 0x19, 0x30, +0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 0x08, 0x1c, 0xff, 0xf7, +0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0x03, 0x00, 0x80, +0x3c, 0x2c, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, +0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x78, 0x00, 0x29, 0x03, 0xd1, 0x41, 0x68, +0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, 0x49, 0x08, 0x02, 0xd3, +0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21, 0x09, 0x04, 0x0c, 0xc8, +0x08, 0x38, 0x19, 0x43, 0x87, 0x68, 0xbb, 0x0a, 0x03, 0xd3, 0x43, 0x68, +0x5b, 0x08, 0x00, 0xd3, 0x01, 0x31, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, +0x18, 0x40, 0x07, 0x0f, 0xf8, 0x00, 0x1d, 0x4c, 0x00, 0x19, 0x23, 0x68, +0xc0, 0x18, 0x50, 0x30, 0x00, 0x79, 0x01, 0x28, 0x10, 0xd1, 0x60, 0x68, +0x01, 0x28, 0x0d, 0xd0, 0x10, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x01, +0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, +0x41, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x01, 0x00, 0x19, +0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0x5d, 0x1c, 0x05, 0x63, +0xbd, 0x02, 0x2d, 0x19, 0xdb, 0x00, 0xeb, 0x18, 0x80, 0x33, 0x19, 0x63, +0xda, 0x62, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x01, 0x21, 0xb9, 0x40, +0x22, 0x68, 0x11, 0x43, 0x21, 0x60, 0x01, 0x6b, 0x80, 0x29, 0xe2, 0xd3, +0x00, 0x21, 0x01, 0x63, 0xdf, 0xe7, 0x00, 0x00, +0xa8, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, +0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 0x36, 0xd1, 0x00, 0x24, +0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 0xb0, 0x60, 0x32, 0x68, +0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 0x00, 0xd3, 0xb4, 0x60, +0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x87, 0x6b, +0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 0xaa, 0x02, 0x92, 0x19, +0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 0xca, 0x6a, 0x09, 0x6b, +0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 0xc4, 0x62, 0x00, 0x2f, +0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 0xdb, 0x43, 0x37, 0x68, +0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 0x43, 0x63, 0x10, 0x1c, +0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 0x00, 0x28, 0xc9, 0xd0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, +0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 0x00, 0x27, 0x2f, 0x4b, +0x2f, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 0x01, 0x30, 0xd8, 0x62, +0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 0x02, 0x69, 0x53, 0x1c, +0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 0x41, 0x69, 0x01, 0x31, +0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 0x07, 0x61, 0x0f, 0x29, +0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c, +0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 0x6e, 0x1c, 0xad, 0x00, +0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 0x01, 0x35, 0x55, 0x61, +0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 0x0f, 0x2d, 0x00, 0xd3, +0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x17, 0x4f, 0x3a, 0x6f, 0xfd, 0x68, +0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0e, 0xd1, 0xdb, 0x6d, 0x5b, 0x08, +0x0b, 0xd3, 0x8b, 0x88, 0x00, 0x2b, 0x08, 0xd1, 0x03, 0x3b, 0xfd, 0x6f, +0x2b, 0x40, 0xfb, 0x67, 0x0f, 0x4d, 0xc0, 0x46, 0x2b, 0x60, 0x14, 0x23, +0x8b, 0x80, 0x10, 0x60, 0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, +0x00, 0xd0, 0x01, 0x38, 0x50, 0x60, 0xc9, 0x69, 0x08, 0x32, 0x91, 0x42, +0x00, 0xd8, 0x08, 0x4a, 0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, +0x82, 0x61, 0x3a, 0x67, 0xbc, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, +0x1c, 0x1c, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, +0x24, 0xa7, 0x20, 0x40, 0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, +0xc0, 0x05, 0x16, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, +0x67, 0x69, 0x00, 0x2f, 0x16, 0xd0, 0xe0, 0x68, 0x41, 0x1c, 0x80, 0x00, +0x00, 0x19, 0xe1, 0x60, 0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x90, 0xfe, +0xe0, 0x68, 0x0f, 0x28, 0x00, 0xd3, 0xe5, 0x60, 0xe0, 0x68, 0x80, 0x00, +0x00, 0x19, 0x80, 0x69, 0x00, 0x08, 0x01, 0xd3, 0x00, 0x2f, 0xea, 0xd1, +0x67, 0x61, 0x03, 0xe0, 0x08, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, +0x65, 0x60, 0x20, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x22, 0xff, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0x1c, 0x1c, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, +0xb0, 0xb4, 0x10, 0x23, 0x82, 0x68, 0x13, 0x40, 0x00, 0x21, 0x00, 0x2b, +0x15, 0xd0, 0x0c, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x24, 0x14, 0x43, +0x02, 0x68, 0x15, 0x68, 0x13, 0x1d, 0x80, 0xcb, +0x1b, 0x68, 0x04, 0x3a, 0x02, 0x60, 0x20, 0xc2, 0x80, 0xc2, 0x08, 0xc2, +0x14, 0x60, 0x42, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x32, 0x1a, 0x43, +0x42, 0x60, 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, +0xf0, 0xb4, 0x82, 0x68, 0x53, 0x09, 0x34, 0xd3, 0x1b, 0x4b, 0x1a, 0x40, +0x12, 0x01, 0x81, 0x26, 0x16, 0x43, 0x03, 0x68, 0x1d, 0x68, 0x1f, 0x1d, +0x10, 0xcf, 0x3f, 0x68, 0x04, 0x3b, 0x03, 0x60, 0x20, 0xc3, 0x10, 0xc3, +0x80, 0xc3, 0x1e, 0x60, 0x43, 0x68, 0x1f, 0x1d, 0x01, 0x23, 0x9b, 0x07, +0x3b, 0x43, 0x43, 0x60, 0xcb, 0x6b, 0x18, 0x1f, 0xc8, 0x63, 0x80, 0xcb, +0x80, 0xc0, 0x1c, 0x68, 0x1f, 0x1d, 0x03, 0x1d, 0x04, 0x60, 0x38, 0x1c, +0x3f, 0x68, 0xc0, 0x46, 0x1f, 0x60, 0x1f, 0x1d, 0x43, 0x68, 0x1c, 0x04, +0x24, 0x0c, 0x81, 0x23, 0x23, 0x43, 0x3b, 0x60, 0x40, 0x68, 0x00, 0x0c, +0x00, 0x04, 0x10, 0x43, 0x78, 0x60, 0x08, 0x6e, 0x04, 0x30, 0x08, 0x66, +0x48, 0x6e, 0x04, 0x30, 0x48, 0x66, 0x00, 0x20, 0xf0, 0xbc, 0x70, 0x47, +0x00, 0xf0, 0xff, 0x0f, 0x80, 0xb4, 0x81, 0x6a, 0x01, 0x23, 0x9b, 0x07, +0xca, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0xcf, 0x1d, 0x01, 0x37, +0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x60, 0x01, 0x23, 0x9b, 0x07, +0x0f, 0x1d, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x60, 0x01, 0x23, +0x9b, 0x07, 0x0b, 0x43, 0x1b, 0x68, 0x0c, 0xc1, 0x02, 0x62, 0x01, 0x6b, +0xc0, 0x46, 0x0a, 0x62, 0x04, 0x23, 0x81, 0x69, 0x19, 0x43, 0x81, 0x61, +0x02, 0x6b, 0xc0, 0x46, 0x91, 0x61, 0x81, 0x6a, 0x04, 0x31, 0x81, 0x62, +0x02, 0x6b, 0xc0, 0x46, 0x91, 0x62, 0xc1, 0x1d, 0x39, 0x31, 0x4a, 0x8b, +0x04, 0x3a, 0x4a, 0x83, 0x49, 0x8b, 0x02, 0x6b, 0x40, 0x32, 0x51, 0x83, +0xc1, 0x89, 0x04, 0x39, 0xc1, 0x81, 0xc1, 0x68, 0x00, 0x6b, 0xc0, 0x46, +0xc1, 0x60, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x47, 0x08, 0x47, +0x10, 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47, 0x30, 0x47, 0x38, 0x47, +0x30, 0x40, 0x2d, 0xe9, 0x0c, 0xc0, 0x9d, 0xe5, 0x0c, 0x48, 0xa0, 0xe1, +0x24, 0x48, 0xb0, 0xe1, 0x1e, 0x00, 0x00, 0x0a, 0x01, 0xc0, 0x4c, 0xe2, +0x18, 0x40, 0xa0, 0xe3, 0x64, 0x51, 0x9f, 0xe5, 0x94, 0x50, 0x20, 0xe0, +0x00, 0x50, 0x90, 0xe5, 0x14, 0x40, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, +0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, +0x10, 0x10, 0x90, 0xe5, 0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, +0x0c, 0x50, 0x90, 0x55, 0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, +0x04, 0x10, 0x90, 0xe5, 0x00, 0x50, 0x80, 0xe5, 0x00, 0x50, 0x81, 0xe5, +0x00, 0x00, 0xa0, 0xe3, 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, +0x00, 0x30, 0x93, 0xe5, 0x08, 0x20, 0x90, 0xe5, 0x01, 0x31, 0x83, 0xe3, +0x02, 0x36, 0x83, 0xe3, 0x03, 0x00, 0x55, 0xe1, 0x14, 0x30, 0x80, 0xe5, +0xf2, 0xff, 0xff, 0x1a, 0x01, 0x00, 0xa0, 0xe3, 0xf4, 0xff, 0xff, 0xea, +0x01, 0x06, 0x1c, 0xe3, 0xf1, 0xff, 0xff, 0x0a, 0xec, 0x10, 0x9f, 0xe5, +0x02, 0xc6, 0xcc, 0xe3, 0x54, 0x20, 0x91, 0xe5, 0xe4, 0x30, 0x9f, 0xe5, +0x50, 0x10, 0x91, 0xe5, 0xd9, 0xff, 0xff, 0xea, 0xf0, 0x47, 0x2d, 0xe9, +0x20, 0xc0, 0x9d, 0xe5, 0x0c, 0x68, 0xa0, 0xe1, 0x26, 0x68, 0xb0, 0xe1, +0x25, 0x00, 0x00, 0x0a, 0x18, 0x40, 0xa0, 0xe3, 0xb8, 0x50, 0x9f, 0xe5, +0x94, 0x00, 0x00, 0xe0, 0x05, 0x00, 0x80, 0xe0, +0x08, 0x40, 0x90, 0xe5, 0x04, 0x80, 0x90, 0xe5, 0x00, 0x70, 0xa0, 0xe3, +0x1f, 0xc0, 0xa0, 0xe3, 0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x50, 0x90, 0xe5, +0x10, 0x90, 0x90, 0xe5, 0x14, 0xa0, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, +0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, +0x10, 0x50, 0x85, 0xe2, 0x09, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, +0x0a, 0x00, 0x55, 0xe1, 0x15, 0x00, 0x00, 0x0a, 0x03, 0x70, 0x17, 0xe2, +0x20, 0x10, 0x81, 0xe2, 0x20, 0x30, 0x83, 0xe2, 0x0a, 0x00, 0x00, 0x0a, +0x00, 0x60, 0x96, 0xe2, 0x01, 0x70, 0x87, 0xe2, 0x09, 0x00, 0x00, 0x0a, +0x20, 0x60, 0x46, 0xe2, 0x20, 0x00, 0x56, 0xe3, 0xec, 0xff, 0xff, 0xca, +0x00, 0x70, 0xa0, 0xe3, 0x01, 0xc0, 0x46, 0xe2, 0x02, 0xc4, 0x8c, 0xe3, +0x00, 0x60, 0xa0, 0xe3, 0xe7, 0xff, 0xff, 0xea, 0x00, 0x50, 0x88, 0xe5, +0xf2, 0xff, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x50, 0x80, 0xe5, +0x01, 0x00, 0xa0, 0xe1, 0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, +0x00, 0xa0, 0x94, 0xe5, 0x0a, 0x00, 0x55, 0xe1, 0x14, 0xa0, 0x80, 0xe5, +0xe5, 0xff, 0xff, 0x1a, 0x01, 0x10, 0xa0, 0xe3, 0xf5, 0xff, 0xff, 0xea, +0x28, 0x03, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x00, 0x80, 0x20, 0x40, +0x68, 0x82, 0x9f, 0xe5, 0x0b, 0x92, 0xa0, 0xe3, 0x64, 0xa2, 0x9f, 0xe5, +0x58, 0xb0, 0x9a, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, +0x1e, 0xff, 0x2f, 0xe1, 0x3f, 0x40, 0x2d, 0xe9, 0x00, 0x00, 0x4f, 0xe1, +0x1f, 0x00, 0x00, 0xe2, 0x12, 0x00, 0x50, 0xe3, 0x54, 0x00, 0x00, 0x0a, +0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x99, 0xe5, 0x09, 0x00, 0x00, 0xea, +0x02, 0x00, 0x14, 0xe3, 0x53, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x14, 0xe3, +0x59, 0x00, 0x00, 0x1b, 0x20, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, +0x02, 0x07, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x01, 0x06, 0x14, 0xe3, +0x59, 0x00, 0x00, 0x1b, 0x08, 0x00, 0x14, 0xe3, 0x45, 0x00, 0x00, 0x1b, +0x02, 0x05, 0x14, 0xe3, 0x4a, 0x00, 0x00, 0x1b, 0x02, 0x08, 0x14, 0xe3, +0x4b, 0x00, 0x00, 0x1b, 0xe5, 0x0e, 0x14, 0xe3, 0x07, 0x00, 0x00, 0x0a, +0x04, 0x20, 0x98, 0xe5, 0x0c, 0x10, 0x98, 0xe5, 0x04, 0x30, 0x52, 0xe2, +0x3c, 0x30, 0xa0, 0xb3, 0x04, 0x30, 0x88, 0xe5, 0x02, 0x00, 0x91, 0xe7, +0x0f, 0xe0, 0xa0, 0xe1, 0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, +0x03, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, +0x00, 0x00, 0x14, 0xe1, 0x1b, 0xff, 0x2f, 0x11, 0x08, 0x00, 0x9a, 0xe5, +0x00, 0x00, 0x14, 0xe1, 0x0b, 0x00, 0x00, 0x0a, 0x01, 0x0c, 0x14, 0xe3, +0x98, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, +0x02, 0x04, 0x14, 0xe3, 0x8c, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, +0x10, 0xff, 0x2f, 0x11, 0x01, 0x09, 0x14, 0xe3, 0x80, 0x01, 0x9f, 0x15, +0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, 0x04, 0x00, 0x9a, 0xe5, +0x00, 0x00, 0x14, 0xe1, 0x16, 0x00, 0x00, 0x0a, 0x54, 0xe0, 0x8f, 0xe2, +0x04, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, +0x02, 0x0a, 0x14, 0xe3, 0x44, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, +0x02, 0x09, 0x14, 0xe3, 0x48, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, +0x01, 0x02, 0x14, 0xe3, 0x4c, 0x00, 0x9a, 0x15, +0x10, 0xff, 0x2f, 0x11, 0x01, 0x04, 0x14, 0xe3, 0x50, 0x00, 0x9a, 0x15, +0x10, 0xff, 0x2f, 0x11, 0x01, 0x0a, 0x14, 0xe3, 0x21, 0x00, 0x00, 0x1b, +0x02, 0x00, 0x14, 0xe3, 0x0e, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x9a, 0xe5, +0x00, 0x00, 0x14, 0xe1, 0x1c, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x99, 0xe5, +0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x94, 0xe2, 0x1b, 0xff, 0x2f, 0x11, +0x3f, 0x40, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2, 0xc0, 0x00, 0x80, 0xe3, +0x00, 0xf0, 0x61, 0xe1, 0xfa, 0xff, 0xff, 0xea, 0x18, 0x00, 0x9a, 0xe5, +0x1c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, +0x1c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, +0x20, 0x10, 0x9a, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x11, 0xff, 0x2f, 0xe1, +0x24, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x28, 0x10, 0x9a, 0xe5, +0x11, 0xff, 0x2f, 0xe1, 0x2c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, +0x30, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x34, 0x10, 0x9a, 0xe5, +0x11, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea, 0x38, 0xe0, 0x9a, 0xe5, +0x3c, 0x10, 0x9a, 0xe5, 0x18, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, +0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, +0x11, 0xff, 0x2f, 0xe1, 0x64, 0x20, 0x9f, 0xe5, 0x00, 0x30, 0x92, 0xe5, +0x00, 0x30, 0x53, 0xe0, 0x0a, 0x00, 0x00, 0xba, 0x00, 0x30, 0x82, 0xe5, +0x0c, 0x00, 0x92, 0xe5, 0x08, 0x30, 0x92, 0xe5, 0x00, 0x10, 0x91, 0xe2, +0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0x80, 0xe7, 0x04, 0x30, 0x53, 0xe2, +0x3c, 0x30, 0xa0, 0xb3, 0x08, 0x30, 0x82, 0xe5, 0x01, 0x00, 0xa0, 0xe3, +0x1e, 0xff, 0x2f, 0xe1, 0x3c, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, +0x01, 0x00, 0x80, 0xe2, 0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, +0xf8, 0xff, 0xff, 0xea, 0x10, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x90, 0xe5, +0x04, 0x10, 0x51, 0xe2, 0x3c, 0x10, 0xa0, 0xb3, 0x08, 0x10, 0x80, 0xe5, +0x1e, 0xff, 0x2f, 0xe1, 0x50, 0x2d, 0x00, 0x80, 0x4c, 0x04, 0x00, 0x80, +0xe5, 0x2a, 0xff, 0xff, 0x45, 0x3d, 0xff, 0xff, 0x3d, 0x2b, 0xff, 0xff, +0xa0, 0x82, 0x20, 0x40, 0xc9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0x01, 0x23, +0x85, 0x4a, 0x5b, 0x07, 0x18, 0x43, 0x13, 0x68, 0x5b, 0x18, 0x13, 0x60, +0x00, 0x1f, 0x81, 0xa3, 0x5b, 0x1a, 0x18, 0x47, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0x50, 0x2d, 0x00, 0x80, 0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, +0x01, 0x20, 0x40, 0xe0, 0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, +0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, +0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, +0x78, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x74, 0x00, 0x9f, 0xe5, +0x74, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x60, 0x30, 0x9f, 0xe5, +0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, +0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, +0xf8, 0xff, 0xff, 0xea, 0x50, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, +0x4c, 0x00, 0x9f, 0xe5, 0x4c, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, +0x2c, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, +0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, +0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, +0x28, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0x7c, 0x34, 0x00, 0x80, 0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, +0x40, 0x04, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0x80, 0x34, 0x00, 0x80, +0x44, 0x04, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80, 0x40, 0x38, 0x00, 0x80, +0x48, 0x04, 0x00, 0x80, 0x78, 0x47, 0x00, 0x00, 0x91, 0xea, 0xff, 0xea, +0x78, 0x47, 0x00, 0x00, 0x39, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, +0x63, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xea, +0x78, 0x47, 0x00, 0x00, 0x8b, 0xea, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, +0x61, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xb9, 0x0b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +0xd5, 0x0b, 0xff, 0xff, 0x03, 0xff, 0x06, 0x54, 0x03, 0x00, 0x00, 0x00, +0x75, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x05, 0xff, 0xff, +0x04, 0xff, 0x07, 0x54, 0x03, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0xf1, 0x05, 0xff, 0xff, 0x05, 0xff, 0x05, 0x54, +0x03, 0x00, 0x00, 0x00, 0x39, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +0x55, 0x05, 0xff, 0xff, 0x00, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, +0xf5, 0x17, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0e, 0xff, 0xff, +0x01, 0xff, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x02, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0xf1, 0x02, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x65, 0x0d, 0xff, 0xff, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, +0xbd, 0x4f, 0xff, 0xff, 0x01, 0x50, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x04, 0x00, 0x80, +0x19, 0x78, 0x21, 0x40, 0x23, 0x78, 0x21, 0x40, 0x39, 0x78, 0x21, 0x40, +0x51, 0x78, 0x21, 0x40, 0x5d, 0x78, 0x21, 0x40, 0x6b, 0x78, 0x21, 0x40, +0x85, 0x78, 0x21, 0x40, 0xb1, 0x78, 0x21, 0x40, 0x75, 0x79, 0x21, 0x40, +0xcd, 0x79, 0x21, 0x40, 0xdb, 0x79, 0x21, 0x40, 0xe5, 0x79, 0x21, 0x40, +0xef, 0x79, 0x21, 0x40, 0x81, 0x7a, 0x21, 0x40, 0x8f, 0x7a, 0x21, 0x40, +0x9d, 0x7a, 0x21, 0x40, 0x35, 0x7b, 0x21, 0x40, 0x03, 0x7f, 0x21, 0x40, +0x71, 0x7f, 0x21, 0x40, 0x19, 0x80, 0x21, 0x40, 0x4d, 0x81, 0x21, 0x40, +0x59, 0x81, 0x21, 0x40, 0xb9, 0x81, 0x21, 0x40, 0x1d, 0x82, 0x21, 0x40, +0x49, 0x82, 0x21, 0x40, 0x6d, 0x82, 0x21, 0x40, 0xad, 0x82, 0x21, 0x40, +0xd5, 0x82, 0x21, 0x40, 0x1d, 0x83, 0x21, 0x40, 0x2d, 0x83, 0x21, 0x40, +0x55, 0x83, 0x21, 0x40, 0x65, 0x83, 0x21, 0x40, 0xad, 0x83, 0x21, 0x40, +0xeb, 0x83, 0x21, 0x40, 0x41, 0x84, 0x21, 0x40, 0xa1, 0x84, 0x21, 0x40, +0xab, 0x84, 0x21, 0x40, 0xaf, 0x84, 0x21, 0x40, 0x1d, 0x85, 0x21, 0x40, +0x75, 0x85, 0x21, 0x40, 0xcd, 0x85, 0x21, 0x40, +0x09, 0x86, 0x21, 0x40, 0x6d, 0x86, 0x21, 0x40, 0xa5, 0x86, 0x21, 0x40, +0xb5, 0x86, 0x21, 0x40, 0xed, 0x86, 0x21, 0x40, 0xfd, 0x86, 0x21, 0x40, +0x11, 0x87, 0x21, 0x40, 0x39, 0x87, 0x21, 0x40, 0x43, 0x87, 0x21, 0x40, +0x4d, 0x87, 0x21, 0x40, 0x57, 0x87, 0x21, 0x40, 0xc1, 0x87, 0x21, 0x40, +0xcd, 0x87, 0x21, 0x40, 0x41, 0x88, 0x21, 0x40, 0x4b, 0x88, 0x21, 0x40, +0x55, 0x88, 0x21, 0x40, 0x5f, 0x88, 0x21, 0x40, 0x69, 0x88, 0x21, 0x40, +0x73, 0x88, 0x21, 0x40, 0x7d, 0x88, 0x21, 0x40, 0x87, 0x88, 0x21, 0x40, +0x91, 0x88, 0x21, 0x40, 0x9b, 0x88, 0x21, 0x40, 0xa5, 0x88, 0x21, 0x40, +0xaf, 0x88, 0x21, 0x40, 0xb9, 0x88, 0x21, 0x40, 0xc3, 0x88, 0x21, 0x40, +0xeb, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40, 0x51, 0x89, 0x21, 0x40, +0x5b, 0x89, 0x21, 0x40, 0x65, 0x89, 0x21, 0x40, 0x6f, 0x89, 0x21, 0x40, +0x79, 0x89, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0x83, 0x89, 0x21, 0x40, +0xe9, 0x89, 0x21, 0x40, 0x35, 0x8a, 0x21, 0x40, 0x81, 0x8a, 0x21, 0x40, +0x91, 0x8a, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xdd, 0x8a, 0x21, 0x40, +0xe1, 0x8a, 0x21, 0x40, 0xe5, 0x8a, 0x21, 0x40, 0x3d, 0x8b, 0x21, 0x40, +0x65, 0x8b, 0x21, 0x40, 0x71, 0x8b, 0x21, 0x40, 0x75, 0x8b, 0x21, 0x40, +0x79, 0x8b, 0x21, 0x40, 0xe9, 0x8b, 0x21, 0x40, 0xed, 0x8b, 0x21, 0x40, +0xf1, 0x8b, 0x21, 0x40, 0x7d, 0x8b, 0x21, 0x40, 0x05, 0x88, 0x21, 0x40, +0xa5, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xf5, 0x8b, 0x21, 0x40, +0xe9, 0xc1, 0x21, 0x40, 0xe9, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, +0xa5, 0x77, 0x21, 0x40, 0xcd, 0xc2, 0x21, 0x40, 0x03, 0xc3, 0x21, 0x40, +0x35, 0xc3, 0x21, 0x40, 0x4d, 0x8c, 0x21, 0x40, 0x3f, 0x7b, 0x21, 0x40, +0x99, 0x7e, 0x21, 0x40, 0xd5, 0x7e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x5c, 0x01, 0x18, 0x40, 0x58, 0x01, 0x18, 0x40, 0x24, 0xa3, 0x20, 0x40, +0x24, 0xa7, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x6c, 0x01, 0x18, 0x40, 0x68, 0x01, 0x18, 0x40, 0x24, 0x83, 0x20, 0x40, +0x24, 0xa3, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7c, 0x01, 0x18, 0x40, 0x78, 0x01, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x8c, 0x01, 0x18, 0x40, 0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, +0x24, 0xab, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00, 0x18, 0x00, 0x12, 0x00, +0x0c, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x24, 0xa8, 0x20, 0x40, +0xa4, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, +0x00, 0x00, 0x00, 0x00, 0x11, 0xb2, 0x21, 0x40, 0x6d, 0xb3, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0x91, 0x73, 0x21, 0x40, 0x89, 0xaa, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x67, 0x92, 0x21, 0x40, 0x11, 0xb2, 0x21, 0x40, +0x39, 0x2f, 0xff, 0xff, 0xad, 0x20, 0xff, 0xff, 0x97, 0x20, 0xff, 0xff, +0xe9, 0xb0, 0x21, 0x40, 0xa0, 0x2d, 0x00, 0x80, 0xb4, 0x2d, 0x00, 0x80, +0xc8, 0x2d, 0x00, 0x80, 0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, +0x00, 0x30, 0x37, 0x2f, 0x32, 0x33, 0x2f, 0x30, +0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35, 0x36, 0x39, 0x00, 0x43, +0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, +0x20, 0x32, 0x30, 0x30, 0x31, 0x20, 0x33, 0x43, 0x6f, 0x6d, 0x20, 0x43, +0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, +0x17, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x0c, 0x53, 0xff, 0xff, 0x27, 0xf0, 0x7d, 0xfd, +0x00, 0x01, 0x00, 0x02, 0xda, 0x0e, 0x82, 0x00, 0x01, 0x40, 0x64, 0x04, +0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 0xe5, 0x3d, 0xff, 0xff, +0x49, 0x4f, 0xff, 0xff, 0x79, 0x24, 0xff, 0xff, 0x3d, 0x3b, 0xff, 0xff, +0x9d, 0x3b, 0xff, 0xff, 0xa1, 0x19, 0xff, 0xff, 0x19, 0x11, 0xff, 0xff, +0x4c, 0x53, 0xff, 0xff, 0x99, 0x3f, 0xff, 0xff, 0x91, 0x73, 0x21, 0x40, +0x51, 0x75, 0x21, 0x40, 0x51, 0x3f, 0xff, 0xff, 0x11, 0xa3, 0x21, 0x40, +0x29, 0x24, 0xff, 0xff, 0xe4, 0x52, 0xff, 0xff, 0x0c, 0x53, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, +0xb8, 0x60, 0x00, 0x00, 0x74, 0x6c, 0x00, 0x00, 0x00, 0x6e, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, +0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, +0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, +0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, +0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, +0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, +0xfd, 0x92, 0x21, 0x40, 0x9b, 0x92, 0x21, 0x40, 0xc1, 0x95, 0x21, 0x40, +0x21, 0x96, 0x21, 0x40, 0xe9, 0x96, 0x21, 0x40, 0xa7, 0x94, 0x21, 0x40, +0xc5, 0x97, 0x21, 0x40, 0x31, 0x98, 0x21, 0x40, 0x85, 0x94, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, +0xb5, 0xce, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xc3, 0x21, 0x40, +0x45, 0xc5, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcc, 0x21, 0x40, +0x59, 0xcd, 0x21, 0x40, 0xc5, 0xcd, 0x21, 0x40, 0x09, 0x29, 0x09, 0xd1, +0x20, 0x28, 0x07, 0xd2, 0x04, 0x48, 0x01, 0x78, 0x00, 0x29, 0x03, 0xd1, +0x01, 0x21, 0x01, 0x70, 0x02, 0x48, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, +0x00, 0x6e, 0x21, 0x40, 0x24, 0xab, 0x20, 0x40, 0x03, 0x49, 0x88, 0x42, +0x03, 0xd1, 0x00, 0x20, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x70, 0x70, 0x47, +0x24, 0xab, 0x20, 0x40, 0x00, 0x6e, 0x21, 0x40, +0x00, 0xb5, 0x00, 0x20, 0x0b, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, +0x2d, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x48, 0x61, 0x98, 0x60, 0x98, 0x63, +0x80, 0x32, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0x62, 0x05, 0x48, +0xc0, 0x46, 0x08, 0x60, 0x48, 0x60, 0x05, 0xf0, 0xc3, 0xf9, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xfe, 0x03, 0x00, 0x00, +0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x05, 0x1c, 0x00, 0x23, 0x00, 0x93, +0xff, 0xf7, 0xda, 0xff, 0x68, 0x49, 0x0b, 0x23, 0x1b, 0x02, 0xcf, 0x18, +0x38, 0x68, 0x28, 0x40, 0x00, 0x22, 0xb8, 0x60, 0xfa, 0x60, 0x7a, 0x68, +0x22, 0x40, 0x3a, 0x61, 0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, +0x01, 0xd2, 0x80, 0x0a, 0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, +0x01, 0x20, 0xb9, 0x68, 0x49, 0x09, 0x03, 0xd2, 0x39, 0x69, 0x49, 0x09, +0x00, 0xd2, 0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x03, 0xf0, 0xf8, 0xfd, +0xb8, 0x68, 0x00, 0x28, 0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, +0x54, 0x4a, 0x01, 0x23, 0x18, 0x43, 0xb8, 0x60, 0x00, 0x20, 0xd5, 0x1d, +0x79, 0x35, 0x03, 0x95, 0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xba, 0x68, +0x22, 0x40, 0x39, 0xd0, 0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, +0x9b, 0x5c, 0x1e, 0x1c, 0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, +0x5b, 0x78, 0x83, 0x42, 0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, +0x03, 0x9d, 0xad, 0x6a, 0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, +0xab, 0x62, 0x53, 0x68, 0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, +0x86, 0x42, 0x0a, 0xd1, 0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, +0x9b, 0x00, 0x3c, 0x4e, 0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, +0x5d, 0x61, 0x53, 0x78, 0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, +0x5d, 0x1c, 0x01, 0x95, 0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, +0x9b, 0x01, 0xeb, 0x18, 0x9a, 0x60, 0xfa, 0x68, 0x01, 0x32, 0xfa, 0x60, +0x64, 0x00, 0x01, 0x31, 0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, +0xb8, 0xd3, 0x00, 0x20, 0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, +0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0x48, 0x61, 0x01, 0x9b, 0x99, 0x00, +0x89, 0x18, 0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x60, 0x00, 0x9b, +0x00, 0x2b, 0x0c, 0xd1, 0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, +0xc9, 0x18, 0x8b, 0x69, 0xc0, 0x46, 0x4b, 0x61, 0x01, 0x30, 0x0b, 0x28, +0xf4, 0xd3, 0x08, 0xe0, 0x07, 0xe0, 0x03, 0x9d, 0xa8, 0x6a, 0x30, 0x28, +0x03, 0xd2, 0x30, 0x20, 0x03, 0x9d, 0xc0, 0x46, 0xa8, 0x62, 0x19, 0x4a, +0x38, 0x69, 0x00, 0x28, 0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, +0x38, 0x61, 0x00, 0x20, 0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x3b, 0x69, +0x23, 0x40, 0x10, 0xd0, 0x93, 0x00, 0x9b, 0x18, 0x9b, 0x00, 0x12, 0x4d, +0x5b, 0x19, 0x9d, 0x78, 0x85, 0x42, 0x08, 0xd1, 0x1d, 0x69, 0x0b, 0x1c, +0x9b, 0x00, 0x9e, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x9d, 0x63, +0x01, 0x31, 0x64, 0x00, 0x01, 0x32, 0x0b, 0x2a, 0xe6, 0xd3, 0x01, 0x30, +0x09, 0x28, 0xe1, 0xd3, 0x00, 0x20, 0x89, 0x00, 0x04, 0x4a, 0x89, 0x18, +0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x63, 0x04, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xb0, 0x52, 0xff, 0xff, +0x80, 0x00, 0x00, 0x80, 0x00, 0x47, 0x08, 0x47, +0x10, 0x47, 0x18, 0x47, 0x78, 0x47, 0xc0, 0x46, 0x34, 0xc0, 0x9f, 0xe5, +0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x2c, 0xc0, 0x9f, 0xe5, +0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x24, 0xc0, 0x9f, 0xe5, +0x1c, 0xff, 0x2f, 0xe1, 0xc0, 0x46, 0xff, 0xb4, 0x75, 0x46, 0x20, 0xb4, +0x01, 0x21, 0x08, 0x43, 0x01, 0xa4, 0xa6, 0x46, 0x00, 0x47, 0xc0, 0x46, +0x20, 0xbc, 0xae, 0x46, 0xff, 0xbc, 0xf7, 0x46, 0xb8, 0x51, 0xff, 0xff, +0x08, 0x51, 0xff, 0xff, 0xd7, 0xb7, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20, +0x1a, 0x49, 0x01, 0x25, 0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01, +0xf8, 0x18, 0x05, 0x72, 0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20, +0x7a, 0x6e, 0x17, 0x4b, 0x8a, 0x42, 0x1d, 0xd0, 0x19, 0x7b, 0x00, 0x29, +0x17, 0xd1, 0xd9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x1e, 0x1c, +0x00, 0x29, 0x10, 0xd1, 0xb0, 0x60, 0x10, 0x20, 0x70, 0x60, 0x10, 0x4a, +0x10, 0x49, 0xff, 0xf7, 0xb5, 0xff, 0x00, 0x28, 0x07, 0xd0, 0x35, 0x73, +0x04, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x20, 0x61, 0x00, 0xf0, +0x17, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x18, 0x73, 0x04, 0x23, +0xb8, 0x69, 0x98, 0x43, 0xb8, 0x61, 0x20, 0x61, 0xf5, 0xe7, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, +0xa8, 0x04, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, +0xf8, 0xb5, 0x15, 0x4f, 0x39, 0x6c, 0x15, 0x48, 0x40, 0x6e, 0x0c, 0x1a, +0x14, 0x4e, 0x71, 0x68, 0x14, 0x4d, 0xa1, 0x42, 0x06, 0xd8, 0x14, 0x4a, +0x0a, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 0xfa, 0x6b, 0x11, 0xe0, +0x11, 0x22, 0x52, 0x05, 0x22, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, +0x00, 0x20, 0xfa, 0x6b, 0x2b, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x70, 0x68, +0x00, 0x1b, 0x0a, 0x4a, 0x02, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0xfa, 0x6b, +0x00, 0x20, 0x2b, 0x1c, 0xff, 0xf7, 0x74, 0xff, 0xf8, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, +0xa8, 0x04, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x37, 0x02, +0xf0, 0xb5, 0x2b, 0x4f, 0xb8, 0x68, 0x79, 0x68, 0xc0, 0x19, 0x20, 0x30, +0x29, 0x4a, 0xff, 0xf7, 0x55, 0xff, 0x01, 0x20, 0xc0, 0x02, 0x28, 0x49, +0xc0, 0x46, 0x08, 0x60, 0xb9, 0x68, 0x38, 0x1c, 0x26, 0x4d, 0x00, 0x24, +0x26, 0x4e, 0xef, 0x1d, 0x79, 0x37, 0x00, 0x29, 0x31, 0xd1, 0x31, 0x68, +0x0a, 0x78, 0x12, 0x0a, 0x03, 0xd2, 0x04, 0x73, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x49, 0x78, 0x00, 0x29, 0x0c, 0xd1, 0x05, 0x1c, 0x40, 0x68, +0x00, 0xf0, 0x3e, 0xf9, 0x30, 0x68, 0x00, 0xf0, 0x67, 0xf8, 0x00, 0x28, +0x26, 0xd1, 0x2c, 0x73, 0xff, 0xf7, 0x58, 0xff, 0x22, 0xe0, 0x09, 0x01, +0x07, 0x1c, 0x41, 0x60, 0x08, 0x1c, 0x17, 0x4a, 0x17, 0x49, 0xff, 0xf7, +0x27, 0xff, 0x00, 0x28, 0x07, 0xd1, 0x3c, 0x73, 0x04, 0x23, 0xa8, 0x69, +0x98, 0x43, 0x99, 0x04, 0xa8, 0x61, 0x08, 0x61, 0xda, 0xe7, 0x10, 0x20, +0x00, 0xf0, 0x20, 0xf9, 0x10, 0x20, 0xb8, 0x60, 0xff, 0xf7, 0x82, 0xff, +0xd2, 0xe7, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x17, 0xf9, 0x30, 0x68, +0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0, 0x02, 0x23, 0xb8, 0x6b, +0x18, 0x43, 0xb8, 0x63, 0xc4, 0xe7, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, +0x25, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0, +0xe8, 0x0d, 0x00, 0x80, 0x64, 0x01, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, +0x85, 0x74, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49, +0x00, 0x27, 0x08, 0x60, 0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, +0x47, 0x70, 0xe0, 0x69, 0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0, +0xd7, 0xf8, 0xe0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0, +0x01, 0x20, 0xe0, 0x61, 0x07, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, +0x81, 0x63, 0x27, 0x73, 0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x04, 0x00, 0x80, +0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88, +0x6d, 0x28, 0x03, 0xdb, 0x38, 0x1c, 0x00, 0xf0, 0xf7, 0xf8, 0x17, 0xe0, +0x80, 0x00, 0x0d, 0x49, 0x09, 0x58, 0x38, 0x1c, 0xff, 0xf7, 0xbd, 0xfe, +0x00, 0x28, 0x0f, 0xd1, 0x39, 0x78, 0xc9, 0x09, 0x0c, 0xd3, 0x69, 0x46, +0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xf8, 0x68, 0x46, 0x00, 0x21, 0x00, 0xf0, +0x0b, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, +0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x01, 0x00, 0x80, +0xf0, 0xb5, 0x82, 0xb0, 0x02, 0x1c, 0x41, 0x4b, 0xdd, 0x1d, 0xff, 0x35, +0x3a, 0x35, 0x2f, 0x78, 0x00, 0x2f, 0x01, 0xd0, 0x00, 0x27, 0x00, 0xe0, +0x01, 0x27, 0x2f, 0x70, 0x2f, 0x78, 0xfb, 0x00, 0xdb, 0x19, 0x5b, 0x01, +0x3a, 0x4f, 0xdc, 0x19, 0x40, 0x78, 0x00, 0x01, 0xc7, 0x1d, 0x09, 0x37, +0x00, 0x20, 0x83, 0x00, 0xd6, 0x58, 0xc0, 0x46, 0xe6, 0x50, 0x01, 0x30, +0x04, 0x28, 0xf8, 0xd3, 0x00, 0x29, 0x0f, 0xd0, 0x00, 0x22, 0xbb, 0x08, +0x01, 0x93, 0x83, 0x42, 0x0b, 0xd9, 0x13, 0x1c, 0x9b, 0x00, 0xcb, 0x58, +0x86, 0x00, 0xa3, 0x51, 0x01, 0x9b, 0x01, 0x30, 0x01, 0x32, 0x83, 0x42, +0xf5, 0xd8, 0x00, 0xe0, 0x10, 0x27, 0x2b, 0x48, 0x02, 0x6d, 0x80, 0x6e, +0x2a, 0x49, 0x82, 0x42, 0x03, 0xd8, 0x82, 0x1a, 0xcb, 0x6c, 0x9a, 0x1a, +0x00, 0xe0, 0x12, 0x1a, 0xba, 0x42, 0x05, 0xd8, 0x26, 0x48, 0x81, 0x6b, +0x01, 0x31, 0x81, 0x63, 0x01, 0x20, 0x37, 0xe0, 0xc3, 0x19, 0xca, 0x6c, +0x93, 0x42, 0x08, 0xd8, 0x22, 0x4a, 0x3a, 0x43, 0x00, 0x92, 0x0a, 0x1c, +0x49, 0x6c, 0x09, 0x18, 0x92, 0x6c, 0x23, 0x1c, 0x12, 0xe0, 0x16, 0x1a, +0x00, 0x96, 0x1b, 0x49, 0x49, 0x6c, 0x09, 0x18, 0x19, 0x48, 0x82, 0x6c, +0x03, 0x20, 0x23, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0xb8, 0x1b, 0x18, 0x4a, +0x02, 0x43, 0x00, 0x92, 0xa3, 0x19, 0x14, 0x48, 0x82, 0x6c, 0x41, 0x6c, +0x03, 0x20, 0xff, 0xf7, 0x45, 0xfe, 0x01, 0x20, 0x0d, 0x49, 0xc0, 0x46, +0x68, 0x70, 0x8a, 0x69, 0x92, 0x00, 0x52, 0x18, 0x17, 0x61, 0x8a, 0x69, +0x00, 0x2a, 0x02, 0xd0, 0x00, 0x27, 0x8f, 0x61, 0x00, 0xe0, 0x88, 0x61, +0x0c, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x00, 0x20, +0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x72, 0x02, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xa8, 0x04, 0x00, 0x80, 0xfc, 0xba, 0x20, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x00, 0x00, 0x19, 0x02, 0x68, 0x0e, 0x00, 0x80, 0x98, 0x19, 0x00, 0x80, +0x07, 0x49, 0x8a, 0x6e, 0x10, 0x18, 0x07, 0x4a, 0xd2, 0x6c, 0x13, 0x04, +0x1b, 0x0c, 0x83, 0x42, 0x00, 0xd8, 0x80, 0x1a, 0x88, 0x66, 0x88, 0x6e, +0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47, +0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, +0x06, 0x49, 0x4a, 0x6e, 0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42, +0x00, 0xd8, 0x80, 0x1a, 0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46, +0x08, 0x61, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, +0x3c, 0xef, 0x20, 0x40, 0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46, +0x8a, 0x80, 0x00, 0x22, 0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80, +0xca, 0x80, 0x8a, 0x60, 0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60, +0x00, 0x22, 0x82, 0x80, 0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60, +0xc2, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48, +0x41, 0x6b, 0x01, 0x31, 0x41, 0x63, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, +0xdd, 0xff, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x45, 0x20, 0x00, 0xab, +0x18, 0x70, 0x01, 0x27, 0xdf, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0x11, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c, 0x00, 0xe0, 0x00, 0x20, +0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xa0, 0x82, 0x20, 0x40, +0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x09, 0x4a, 0xc0, 0x46, 0x11, 0x81, +0x69, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x01, 0x20, 0x40, 0x02, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xf5, 0xfe, 0x01, 0x20, +0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, +0x00, 0xb5, 0xff, 0xf7, 0xc3, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, +0x03, 0x49, 0xc0, 0x46, 0x08, 0x70, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, +0x00, 0x20, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x00, 0x20, 0x04, 0x49, +0xc0, 0x46, 0x08, 0x70, 0xff, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x01, 0x31, +0x91, 0x60, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x02, 0x20, 0xa1, 0x21, +0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x40, 0x02, +0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x88, +0xc0, 0x06, 0xc0, 0x0e, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x61, 0x02, 0x49, +0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x70, 0x47, 0x68, 0x1a, 0x00, 0x80, +0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0x0f, 0x6b, 0x69, 0x46, 0xff, 0xf7, +0x71, 0xff, 0xf8, 0x06, 0xc0, 0x0e, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xff, 0xf7, 0xa9, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x80, 0x00, 0x14, 0x40, 0x80, 0xb5, 0x85, 0xb0, +0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x5b, 0xff, 0xf8, 0x88, +0x04, 0xa9, 0x04, 0xf0, 0xef, 0xfd, 0x01, 0xab, 0x58, 0x80, 0x01, 0xa8, +0x40, 0x88, 0x00, 0x28, 0x0f, 0xd0, 0x01, 0xa8, 0x40, 0x88, 0x80, 0x08, +0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x04, 0x3b, 0x58, 0x70, 0x04, 0x98, +0x01, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x40, 0x68, 0xc0, 0x46, 0x03, 0x90, +0x05, 0xe0, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, +0x18, 0x70, 0x04, 0x98, 0xc1, 0x1d, 0x01, 0x31, 0x68, 0x46, 0xff, 0xf7, +0x75, 0xfe, 0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x90, 0xb5, 0x84, 0xb0, 0x14, 0x4f, 0x39, 0x7b, 0x00, 0x29, 0x20, 0xd1, +0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x00, 0x29, 0x1a, 0xd1, +0x10, 0x49, 0x05, 0x22, 0x00, 0x92, 0x08, 0x22, 0x00, 0xab, 0x5a, 0x80, +0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70, +0x00, 0x24, 0xdc, 0x80, 0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68, +0xc0, 0x46, 0x03, 0x90, 0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31, +0xff, 0xf7, 0x4c, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, +0x10, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, +0x38, 0x1c, 0xff, 0xf7, 0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48, +0x00, 0x2a, 0x05, 0xd1, 0x0d, 0x49, 0xff, 0xf7, 0xd6, 0xfc, 0x00, 0x28, +0x0c, 0xda, 0x05, 0xe0, 0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xd1, 0xfc, +0x00, 0x28, 0x05, 0xda, 0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21, +0xff, 0xf7, 0x22, 0xfe, 0x00, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x15, 0x79, 0x21, 0x40, +0x59, 0xcd, 0x21, 0x40, 0xf1, 0xcc, 0x21, 0x40, 0x00, 0xb5, 0xc0, 0x88, +0x04, 0xf0, 0x54, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xff, 0xf7, 0xe2, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, +0xdd, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, +0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, +0x04, 0x1c, 0x08, 0x1c, 0x69, 0x46, 0xff, 0xf7, 0xb5, 0xfe, 0x1b, 0x48, +0xff, 0xf7, 0x96, 0xfc, 0x07, 0x1c, 0x00, 0x21, 0x20, 0x1c, 0x03, 0xf0, +0x4f, 0xff, 0x00, 0x28, 0x1c, 0xd0, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, +0x2d, 0xfe, 0x04, 0x98, 0x04, 0x28, 0x05, 0xd9, 0x04, 0x98, 0x80, 0x08, +0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x00, 0xe0, 0x00, 0x20, 0x00, 0xab, +0x58, 0x70, 0x06, 0xa8, 0x00, 0x78, 0xc0, 0x46, 0xd8, 0x80, 0x04, 0x98, +0xc0, 0x46, 0x02, 0x90, 0x07, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x04, 0x33, +0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, +0x38, 0x1c, 0xff, 0xf7, 0x6c, 0xfc, 0x68, 0x46, 0x29, 0x1c, 0xff, 0xf7, +0xc3, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c, +0x02, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0x01, 0x1c, 0x01, 0x20, 0xff, 0xf7, 0xb2, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, +0x18, 0x47, 0xf3, 0xb5, 0xc6, 0xb0, 0x0f, 0x1c, 0x69, 0x46, 0x38, 0x1c, +0xff, 0xf7, 0x5e, 0xfe, 0x1c, 0x48, 0xff, 0xf7, 0x3f, 0xfc, 0xba, 0x68, +0x04, 0x1c, 0xfc, 0x2a, 0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 0xc0, 0x46, +0x04, 0x90, 0xf9, 0x1d, 0x09, 0x31, 0x05, 0xab, 0x00, 0x20, 0x7e, 0x78, +0x00, 0x2e, 0x0d, 0xdd, 0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, +0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 0x01, 0x30, 0x00, 0x04, +0x00, 0x0c, 0x7e, 0x78, 0x86, 0x42, 0xf1, 0xdc, 0x46, 0x98, 0x04, 0xa9, +0x2b, 0x1c, 0xff, 0xf7, 0x2d, 0xfc, 0x00, 0x28, 0x05, 0xd0, 0x00, 0xa8, +0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, +0x20, 0x1c, 0xff, 0xf7, 0x12, 0xfc, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0x69, 0xfd, 0x01, 0x20, 0x48, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, +0x35, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, +0xc6, 0xb0, 0x07, 0x1c, 0xfc, 0x88, 0x25, 0x4d, 0x68, 0x68, 0x01, 0x30, +0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x0f, 0xfe, 0x10, 0x2c, +0x08, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, +0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x17, 0xe0, 0x78, 0x78, 0x82, 0x00, +0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 0xb9, 0x68, 0x00, 0x2a, 0x15, 0xd9, +0x40, 0xcb, 0x0f, 0x1c, 0x01, 0x31, 0xbe, 0x42, 0x0d, 0xd0, 0x00, 0xaa, +0x12, 0x78, 0x40, 0x23, 0x1a, 0x43, 0x00, 0xab, 0x1a, 0x70, 0x04, 0x22, +0xda, 0x80, 0x02, 0x90, 0x03, 0x91, 0x04, 0x33, 0x68, 0x46, 0x00, 0x21, +0x15, 0xe0, 0x01, 0x30, 0x90, 0x42, 0xe9, 0xd3, 0x00, 0xab, 0x5c, 0x70, +0x02, 0x94, 0x69, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa2, 0x00, 0x00, 0x20, +0x10, 0x33, 0x00, 0x2a, 0x05, 0xd9, 0x0f, 0x1c, 0x80, 0xc3, 0x01, 0x30, +0x01, 0x31, 0x90, 0x42, 0xf9, 0xd3, 0x68, 0x46, 0x04, 0xa9, 0xff, 0xf7, +0x11, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x1c, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x22, 0x48, 0x00, 0x68, 0x01, 0x21, +0x42, 0x09, 0x00, 0xd3, 0x00, 0x21, 0x00, 0x27, 0x3a, 0x1c, 0x43, 0x0b, +0x00, 0xd2, 0x02, 0x22, 0x11, 0x43, 0x1d, 0x4a, 0x20, 0x24, 0xd3, 0x68, +0x01, 0x2b, 0x2c, 0xd1, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, +0x20, 0x1c, 0x1b, 0x23, 0xdb, 0x01, 0xd1, 0x18, 0x09, 0x8b, 0x09, 0x0b, +0x00, 0xd2, 0x04, 0x27, 0x38, 0x43, 0xd1, 0x6f, 0x09, 0x0a, 0x06, 0xd2, +0xd1, 0x1d, 0x79, 0x31, 0x09, 0x68, 0x09, 0x0a, 0x01, 0xd3, 0x08, 0x23, +0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x89, 0x78, 0x03, 0x29, +0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 0x0b, 0x49, 0x09, 0x6a, +0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x89, 0x07, +0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 0x70, 0x47, 0x40, 0x0c, +0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0xec, 0xe7, 0x00, 0x00, +0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, +0xf0, 0xb5, 0x33, 0x4d, 0x28, 0x1c, 0x05, 0xf0, 0x6b, 0xf8, 0x32, 0x49, +0xe3, 0x23, 0x1b, 0x01, 0xcf, 0x18, 0xba, 0x78, 0x30, 0x4e, 0x00, 0x20, +0xcc, 0x1d, 0x79, 0x34, 0x05, 0x2a, 0x53, 0xd2, 0x01, 0xa3, 0x9b, 0x5c, +0x5b, 0x00, 0x9f, 0x44, 0x02, 0x0e, 0x23, 0x3c, 0x3e, 0x00, 0x01, 0x21, +0xb9, 0x70, 0xb0, 0x60, 0xff, 0xf7, 0x98, 0xff, 0x04, 0x23, 0x98, 0x43, +0x00, 0xf0, 0x62, 0xf8, 0x14, 0x22, 0x28, 0x1c, 0x0e, 0xe0, 0xff, 0xf7, +0x8f, 0xff, 0xc0, 0x08, 0x06, 0xd3, 0xb1, 0x68, 0x48, 0x1c, 0xb0, 0x60, +0x0a, 0x29, 0x03, 0xd9, 0x04, 0x20, 0x00, 0xe0, 0x02, 0x20, 0xb8, 0x70, +0x02, 0x22, 0x28, 0x1c, 0x00, 0x21, 0x05, 0xf0, 0x07, 0xf8, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0xc8, 0x6f, 0x18, 0x43, 0xc8, 0x67, +0x18, 0x4e, 0xc0, 0x46, 0x30, 0x60, 0x03, 0x20, 0xb8, 0x70, 0x28, 0x1c, +0x16, 0x4a, 0x00, 0x21, 0x04, 0xf0, 0xf6, 0xff, 0x11, 0x48, 0x04, 0x23, +0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x31, 0x60, 0x20, 0x68, 0x18, 0x43, +0x20, 0x60, 0x70, 0x60, 0xe3, 0xe7, 0x05, 0x21, 0xb9, 0x70, 0x51, 0x21, +0x89, 0x03, 0x08, 0x62, 0x04, 0x23, 0x20, 0x68, 0x98, 0x43, 0x20, 0x60, +0x09, 0x4e, 0xc0, 0x46, 0x70, 0x60, 0xff, 0xf7, 0x55, 0xff, 0x04, 0x23, +0x18, 0x43, 0x00, 0xf0, 0x1f, 0xf8, 0xd0, 0xe7, +0x06, 0x20, 0xb8, 0x70, 0xcd, 0xe7, 0x00, 0x00, 0x79, 0x7c, 0x21, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0x1c, 0x03, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, +0x88, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, +0x88, 0x70, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21, 0x04, 0xf0, 0xc0, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x18, 0x1c, 0x00, 0x80, 0x79, 0x7c, 0x21, 0x40, +0x90, 0xb5, 0x07, 0x1c, 0x30, 0x48, 0x00, 0x68, 0x01, 0x1c, 0x7a, 0x08, +0x02, 0xd3, 0x10, 0x23, 0x98, 0x43, 0x01, 0xe0, 0x10, 0x23, 0x18, 0x43, +0xba, 0x08, 0x03, 0xd3, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, 0x02, 0xe0, +0x01, 0x23, 0x1b, 0x03, 0x18, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x01, 0x21, +0x09, 0x05, 0x08, 0x60, 0x25, 0x4c, 0xe0, 0x68, 0x01, 0x28, 0x1e, 0xd1, +0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0x00, 0x8b, 0xf9, 0x08, 0x04, 0xd3, +0x01, 0x23, 0xdb, 0x02, 0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0, 0x01, 0x21, +0xc9, 0x02, 0x81, 0x42, 0x02, 0xd0, 0x00, 0x20, 0x02, 0xf0, 0x20, 0xfe, +0x08, 0x21, 0x39, 0x40, 0x1a, 0x48, 0x03, 0xd0, 0x80, 0x23, 0xe1, 0x6f, +0x99, 0x43, 0x02, 0xe0, 0x80, 0x23, 0xe1, 0x6f, 0x19, 0x43, 0xe1, 0x67, +0x01, 0x60, 0x16, 0x48, 0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, +0x01, 0x30, 0x08, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x08, 0x1c, 0x01, 0x33, +0x98, 0x43, 0x80, 0x08, 0x80, 0x00, 0xba, 0x09, 0x92, 0x07, 0x92, 0x0f, +0x10, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x62, +0xe1, 0x68, 0x01, 0x29, 0x08, 0xd1, 0x79, 0x0a, 0x06, 0xd3, 0xff, 0x23, +0x04, 0x33, 0x18, 0x40, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x90, 0xff, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x40, +0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xff, 0xf7, 0xc1, 0xfe, 0x80, 0x09, +0x12, 0xd2, 0x0b, 0x48, 0x41, 0x78, 0x00, 0x29, 0x0e, 0xd1, 0x01, 0x21, +0x41, 0x70, 0x00, 0x27, 0x08, 0x48, 0x06, 0xe0, 0x02, 0x20, 0x03, 0xf0, +0x03, 0xf8, 0x07, 0x20, 0x02, 0xf0, 0xd2, 0xff, 0x38, 0x1c, 0xff, 0xf7, +0x5b, 0xfa, 0xf5, 0xe7, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x18, 0x1c, 0x00, 0x80, 0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, +0x69, 0x46, 0xff, 0xf7, 0x69, 0xfc, 0xff, 0xf7, 0x9d, 0xfe, 0x01, 0xab, +0x58, 0x80, 0x08, 0x48, 0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x48, +0x00, 0x6a, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0x99, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x80, 0xb5, 0x84, 0xb0, +0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x49, 0xfc, 0xf8, 0x88, +0xff, 0xf7, 0x4a, 0xff, 0xff, 0xf7, 0x7a, 0xfe, 0x01, 0xab, 0x58, 0x80, +0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7e, 0xfb, 0x01, 0x20, 0x04, 0xb0, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0xc7, 0x88, +0x69, 0x46, 0xff, 0xf7, 0x33, 0xfc, 0x01, 0x24, 0x63, 0x02, 0x9f, 0x42, +0x0a, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, +0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x16, 0xe0, +0x0e, 0x48, 0xff, 0xf7, 0x05, 0xfa, 0x05, 0x1c, 0x38, 0x1c, 0x04, 0xa9, +0x03, 0xf0, 0xa2, 0xfb, 0x0b, 0x49, 0x28, 0x1c, +0xff, 0xf7, 0xfd, 0xf9, 0x10, 0x20, 0x00, 0xab, 0x58, 0x70, 0x04, 0x98, +0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, +0x06, 0xa9, 0xff, 0xf7, 0x4b, 0xfb, 0x20, 0x1c, 0x46, 0xb0, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, +0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, +0xfb, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x02, 0xd1, +0x43, 0x01, 0x9c, 0x42, 0x09, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, +0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x04, 0x33, +0x2c, 0xe0, 0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, +0x05, 0x90, 0x06, 0xaa, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x21, 0x78, 0x78, +0x00, 0x28, 0x0d, 0xdd, 0x00, 0x20, 0x40, 0xcb, 0x40, 0xc2, 0x01, 0x30, +0x00, 0x04, 0x00, 0x0c, 0x04, 0x28, 0xf8, 0xdb, 0x48, 0x1c, 0x01, 0x04, +0x09, 0x0c, 0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0d, 0x48, 0xff, 0xf7, +0xaf, 0xf9, 0x06, 0x1c, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, 0x76, 0xfb, +0x0a, 0x49, 0x30, 0x1c, 0xff, 0xf7, 0xa7, 0xf9, 0x38, 0x68, 0xc0, 0x46, +0x00, 0x90, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x68, 0x46, 0x00, 0x21, +0xff, 0xf7, 0xf8, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, +0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27, 0xe6, 0x88, 0xa2, 0x68, +0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x2e, 0x01, 0xd0, +0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0, 0x04, 0x2e, 0x00, 0xd1, +0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e, 0x66, 0xd2, 0x02, 0xa3, +0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x03, 0x06, 0x08, 0x0c, +0x10, 0x00, 0x85, 0x83, 0x00, 0x23, 0x03, 0xe0, 0x85, 0x83, 0x05, 0xe0, +0x00, 0x23, 0x83, 0x83, 0xc3, 0x83, 0x06, 0xe0, 0x00, 0x23, 0x83, 0x83, +0xc5, 0x83, 0x02, 0xe0, 0xff, 0x23, 0x01, 0x33, 0x83, 0x83, 0xcb, 0x1d, +0x79, 0x33, 0x1e, 0x89, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x02, 0xdb, +0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xe0, 0x01, 0x22, 0x6d, 0x23, 0x5b, 0x01, +0xc9, 0x18, 0x09, 0x88, 0xff, 0x23, 0xe1, 0x33, 0x99, 0x43, 0x01, 0x23, +0x19, 0x43, 0x86, 0x8b, 0xff, 0x33, 0x9e, 0x42, 0x0d, 0xd1, 0xff, 0x20, +0xe1, 0x30, 0x08, 0x43, 0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0x9b, 0x02, +0x98, 0x43, 0x01, 0x1c, 0x20, 0xe0, 0x01, 0x21, 0x89, 0x02, 0x01, 0x43, +0x1c, 0xe0, 0x01, 0x2e, 0x0a, 0xd1, 0xc0, 0x8b, 0x01, 0x28, 0x04, 0xd1, +0x60, 0x23, 0x19, 0x43, 0x00, 0x2a, 0x13, 0xd0, 0x0c, 0xe0, 0x20, 0x23, +0x19, 0x43, 0x0f, 0xe0, 0x00, 0x2e, 0x0d, 0xd1, 0xc0, 0x8b, 0x01, 0x28, +0x08, 0xd1, 0xff, 0x23, 0x81, 0x33, 0x19, 0x43, 0x00, 0x2a, 0x05, 0xd0, +0x01, 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, +0x04, 0x20, 0x02, 0xf0, 0x8d, 0xfc, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, +0x02, 0xf0, 0x88, 0xfc, 0x00, 0x2f, 0x02, 0xd1, 0x00, 0x20, 0x12, 0xe0, +0xff, 0xe7, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x2b, 0xfb, 0x00, 0xa8, +0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, +0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0x5e, 0xfa, +0x28, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, +0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, +0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x07, 0xd1, 0x37, 0x23, +0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x21, 0x01, 0x43, 0x1b, 0x20, +0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x21, +0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0, 0x4b, 0xfc, 0x01, 0x20, +0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x88, 0x83, 0xc8, 0x83, 0x1b, 0x23, +0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, +0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0x38, 0xfc, +0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x37, 0x23, +0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x23, 0x98, 0x43, 0x01, 0x1c, +0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, +0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c, 0x10, 0x20, 0x02, 0xf0, +0x19, 0xfc, 0xff, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x01, 0x30, +0x88, 0x83, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x41, 0x23, +0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02, 0x01, 0x43, 0x00, 0x20, +0x02, 0xf0, 0x06, 0xfc, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0xcf, 0x6a, +0x69, 0x46, 0xff, 0xf7, 0xa5, 0xfa, 0xb8, 0x05, 0x80, 0x0d, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xdd, 0xf9, 0x01, 0x20, +0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, +0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49, 0xc9, 0x6a, 0x1b, 0x23, +0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49, 0xc0, 0x46, 0xc8, 0x62, +0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x00, +0x80, 0xb5, 0x84, 0xb0, 0x0d, 0x49, 0x0f, 0x6a, 0x01, 0x2f, 0x01, 0xd1, +0xff, 0x03, 0x07, 0xe0, 0x02, 0x2f, 0x01, 0xd1, 0x3f, 0x03, 0x03, 0xe0, +0x00, 0x2f, 0x01, 0xd1, 0x01, 0x27, 0xff, 0x02, 0x69, 0x46, 0xff, 0xf7, +0x71, 0xfa, 0x01, 0xab, 0x5f, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0xab, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x20, 0x14, 0x40, 0xc2, 0x88, 0xa1, 0x20, 0x40, 0x03, 0x00, 0x21, +0x01, 0x23, 0x5b, 0x03, 0x9a, 0x42, 0x01, 0xd1, 0x02, 0x22, 0x04, 0xe0, +0x01, 0x23, 0xdb, 0x03, 0x9a, 0x42, 0x02, 0xd1, 0x01, 0x22, 0x02, 0x62, +0x00, 0xe0, 0x01, 0x62, 0x08, 0x1c, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, +0x07, 0x1c, 0x02, 0xf0, 0xb7, 0xfb, 0x69, 0x46, 0x04, 0x1c, 0x38, 0x1c, +0xff, 0xf7, 0x46, 0xfa, 0x01, 0xab, 0x5c, 0x80, 0x09, 0x4f, 0xf8, 0x6d, +0xc0, 0x46, 0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7c, 0xf9, +0xf8, 0x6d, 0xc0, 0x07, 0xc0, 0x0f, 0x05, 0x49, 0xc0, 0x46, 0x88, 0x62, +0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x10, 0x2a, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 0xc0, 0x88, 0x02, 0x49, +0xc0, 0x46, 0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, +0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 0x1f, 0xfa, 0x06, 0x48, +0xc0, 0x68, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xff, 0xf7, 0x57, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, +0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, +0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68, 0xff, 0xf7, 0x02, 0xfa, +0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49, 0x40, 0x18, 0x1b, 0x23, +0xdb, 0x01, 0xc0, 0x18, 0x00, 0x8b, 0x06, 0xe0, 0x00, 0xa8, 0x00, 0x78, +0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x2b, 0xf9, 0x01, 0x20, +0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68, 0x20, 0x2a, 0x04, 0xd2, +0x10, 0x1c, 0x02, 0xf0, 0x2f, 0xfb, 0x00, 0x20, 0x10, 0xe0, 0x69, 0x46, +0xff, 0xf7, 0xd6, 0xf9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, +0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, +0x04, 0x33, 0xff, 0xf7, 0x09, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7, +0xbf, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0xa0, 0xff, 0x02, 0x20, 0x39, 0x1c, +0x03, 0xf0, 0x5a, 0xfa, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x20, 0x39, 0x1c, +0x03, 0xf0, 0x94, 0xf9, 0x01, 0xab, 0x58, 0x80, 0x02, 0xe0, 0x45, 0x20, +0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c, 0xfe, 0xf7, 0x8d, 0xff, +0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xe4, 0xf8, 0x01, 0x20, 0x04, 0xb0, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, +0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, +0x84, 0x68, 0xff, 0xf7, 0x93, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x74, 0xff, +0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7, 0x71, 0xff, 0x00, 0x28, +0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c, 0x22, 0x1c, 0xfe, 0xf7, +0x6a, 0xff, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, +0x28, 0x1c, 0xfe, 0xf7, 0x60, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0xb7, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x24, 0x02, 0xff, 0xff, 0xb9, 0xb8, 0x21, 0x40, 0x7b, 0xb7, 0x21, 0x40, +0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0x7f, 0xf9, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x80, 0xb4, 0xc2, 0x88, 0x19, 0x4b, +0xa1, 0x21, 0x49, 0x03, 0x00, 0x2a, 0x03, 0xd1, 0x18, 0x6b, 0x10, 0x23, +0x98, 0x43, 0x04, 0xe0, 0x01, 0x2a, 0x04, 0xd1, 0x18, 0x6b, 0x10, 0x23, +0x18, 0x43, 0x48, 0x61, 0x1f, 0xe0, 0x02, 0x2a, 0x1d, 0xd1, 0xc2, 0x68, +0x87, 0x68, 0x00, 0x20, 0x3b, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, +0x9b, 0x02, 0x03, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, +0x20, 0x28, 0xf3, 0xdb, 0x00, 0x20, 0x13, 0x1c, 0xc3, 0x40, 0xdb, 0x07, +0xdb, 0x0f, 0x9b, 0x02, 0xc7, 0x1d, 0x19, 0x37, 0x3b, 0x43, 0x0b, 0x61, +0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf1, 0xdb, 0x00, 0x20, +0x80, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x40, 0x90, 0xb4, 0xc2, 0x88, +0x81, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x10, 0x43, 0x02, 0x04, 0x12, 0x0c, +0x0f, 0x48, 0xc0, 0x46, 0x02, 0x60, 0x0f, 0x4f, 0x65, 0x23, 0x5b, 0x01, +0xfb, 0x18, 0x9a, 0x83, 0x0a, 0x0c, 0x14, 0x02, +0x12, 0x12, 0x22, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0xda, 0x83, +0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x0a, 0x11, 0x43, 0x09, 0x04, +0x09, 0x0c, 0x81, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x01, 0x80, +0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, +0xe8, 0x0d, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0, 0x13, 0x49, 0x0a, 0x68, +0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, 0x4a, 0x68, +0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, +0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, +0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c, 0xff, 0xf7, 0xe4, 0xf8, +0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43, 0x02, 0x90, 0x68, 0x46, +0x00, 0x21, 0xff, 0xf7, 0x1b, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 0xc1, 0x88, 0x82, 0x68, +0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x0a, 0x49, +0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02, 0x00, 0x12, 0x18, 0x43, +0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04, 0x00, 0x0c, 0x02, 0x02, +0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x48, 0x61, 0x00, 0x20, +0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb5, 0x84, 0xb0, +0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, +0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c, 0x17, 0x02, 0x12, 0x12, +0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c, 0x1f, 0x02, 0x1b, 0x12, +0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23, 0x00, 0x93, 0x84, 0x88, +0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b, 0x5c, 0x70, 0x40, 0x88, +0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04, 0x38, 0x43, 0x02, 0x90, +0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xcb, 0xff, 0x01, 0x20, +0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, +0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a, 0x05, 0x21, 0x00, 0x91, +0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, +0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, +0x68, 0x46, 0xfe, 0xf7, 0xaf, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, +0xc0, 0x46, 0x88, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, +0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x0a, 0x6a, 0x05, 0x21, 0x00, 0x91, +0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, +0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, +0x68, 0x46, 0xfe, 0xf7, 0x8b, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, +0xc0, 0x46, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, +0x00, 0xb5, 0xc0, 0x88, 0x02, 0x49, 0xfe, 0xf7, 0x1c, 0xfe, 0x00, 0x20, +0x08, 0xbc, 0x18, 0x47, 0x75, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, +0x69, 0x46, 0xff, 0xf7, 0x2d, 0xf8, 0x06, 0x48, 0x00, 0x6b, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x65, 0xff, 0x01, 0x20, +0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0xb5, 0xff, 0xf7, 0x33, 0xf8, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x2e, 0xf8, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xff, 0xf7, 0x29, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, +0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x71, +0x12, 0x48, 0xfe, 0xf7, 0xe9, 0xfd, 0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, +0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, 0x08, 0x70, +0x0d, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, 0x12, 0x21, +0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 0x12, 0x68, +0x92, 0x0a, 0x05, 0xd3, 0x07, 0x4a, 0xc0, 0x46, 0xd1, 0x60, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x05, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0xf8, 0xe7, +0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, 0x00, 0x00, 0x10, 0x40, +0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x02, 0xf0, +0x83, 0xfb, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, +0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0x88, 0xfc, 0x00, 0x28, 0x0c, 0xd1, +0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xc8, 0xff, 0x06, 0x48, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x01, 0xff, 0x01, 0x20, +0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, +0xb3, 0xff, 0x03, 0xf0, 0x71, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x09, 0x48, +0x81, 0x89, 0x09, 0x04, 0xc2, 0x89, 0x11, 0x43, 0x02, 0x91, 0x81, 0x88, +0x09, 0x04, 0xc0, 0x88, 0x08, 0x43, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, +0xfe, 0xf7, 0xe0, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, +0xc8, 0x29, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0xaf, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xaa, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0xa5, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xfe, 0xf7, 0xa0, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, +0x9b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x96, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x91, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x8c, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0x87, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xfe, 0xf7, 0x82, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, +0x7d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x78, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x73, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 0x08, 0xa9, 0xfe, 0xf7, 0x54, 0xff, +0x69, 0x46, 0x08, 0xa8, 0x03, 0xf0, 0xba, 0xfe, 0x02, 0x20, 0x08, 0xab, +0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 0xfe, 0xf7, 0x89, 0xfe, 0x01, 0x20, +0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x5a, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, +0x38, 0x1c, 0xfe, 0xf7, 0x39, 0xff, 0xf9, 0x88, 0x10, 0x48, 0x01, 0x24, +0x00, 0x29, 0x0e, 0xd0, 0x04, 0x73, 0x44, 0x73, 0xb9, 0x68, 0x09, 0x0c, +0x41, 0x82, 0xb9, 0x68, 0xc0, 0x46, 0x81, 0x82, 0xf9, 0x68, 0x09, 0x0c, +0xc1, 0x82, 0xf9, 0x68, 0xc0, 0x46, 0x01, 0x83, 0x02, 0xe0, 0x00, 0x21, +0x01, 0x73, 0x41, 0x73, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xfe, 0xf7, 0x5b, 0xfe, 0x20, 0x1c, +0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, +0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0xfe, 0xf7, 0x27, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x22, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xfe, 0xf7, 0x18, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, +0x13, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, +0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xf2, 0xfe, 0xf8, 0x88, 0x03, 0x24, +0xe4, 0x04, 0x04, 0x43, 0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, +0x0f, 0x4b, 0x9c, 0x42, 0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, +0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x20, 0xfe, 0x01, 0x20, 0x80, 0x07, +0x20, 0x43, 0x00, 0x68, 0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, +0xc0, 0x46, 0xda, 0x80, 0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, +0xfe, 0xf7, 0x10, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, +0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, +0xbf, 0xfe, 0xf8, 0x88, 0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, +0x02, 0xd3, 0x0a, 0x4b, 0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xef, 0xfd, 0x01, 0x20, +0x03, 0xe0, 0xb9, 0x68, 0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, +0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x03, 0xf0, +0x5b, 0xfd, 0x38, 0x1c, 0x02, 0xa9, 0xfe, 0xf7, 0x97, 0xfe, 0x01, 0x27, +0x02, 0xab, 0x5f, 0x70, 0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x01, 0x68, +0xc0, 0x46, 0x04, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x05, 0x91, 0x81, 0x68, +0xc0, 0x46, 0x00, 0x91, 0x00, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46, +0x02, 0xa8, 0xfe, 0xf7, 0xc1, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68, +0x80, 0x68, 0xfe, 0xf7, 0x79, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, +0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x76, 0xfe, 0x01, 0xab, 0x5c, 0x80, +0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa1, 0xfd, 0x04, 0xb0, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, +0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x64, 0xfe, 0x01, 0xab, 0x5f, 0x80, +0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x90, 0xfd, 0x04, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, +0x90, 0xb5, 0x84, 0xb0, 0x00, 0x27, 0x12, 0x49, 0x09, 0x68, 0x12, 0x4a, +0x12, 0x6b, 0x10, 0x23, 0x1a, 0x40, 0x01, 0x24, 0x00, 0x2a, 0x00, 0xd0, +0x01, 0x27, 0x8a, 0x0c, 0x03, 0xd3, 0x3a, 0x04, 0x12, 0x0c, 0x02, 0x27, +0x17, 0x43, 0xc9, 0x0c, 0x03, 0xd3, 0x39, 0x04, 0x09, 0x0c, 0x04, 0x27, +0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0x2c, 0xfe, 0x01, 0xab, 0x5f, 0x80, +0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x66, 0xfd, 0x20, 0x1c, 0x04, 0xb0, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, +0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0, +0x69, 0x46, 0xfe, 0xf7, 0x17, 0xfe, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x4f, 0xfd, 0x01, 0x20, +0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, +0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, +0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, +0x80, 0xb5, 0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, +0x48, 0x71, 0x13, 0x48, 0xfe, 0xf7, 0xd6, 0xfb, 0x01, 0x20, 0x40, 0x02, +0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, +0x08, 0x70, 0x0e, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, +0x15, 0x21, 0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, +0x12, 0x68, 0x92, 0x0a, 0x05, 0xd3, 0x08, 0x4a, 0xc0, 0x46, 0xd1, 0x60, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, +0xf8, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, +0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, +0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, +0x80, 0xb5, 0x85, 0xb0, 0x01, 0xa9, 0xfe, 0xf7, 0xbb, 0xfd, 0x00, 0x20, +0x01, 0xab, 0x58, 0x70, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29, +0x0a, 0xd1, 0x03, 0xf0, 0xb9, 0xfc, 0x03, 0x90, 0x04, 0x97, 0x03, 0x98, +0x00, 0x28, 0x06, 0xd0, 0x68, 0x46, 0x02, 0xf0, 0x15, 0xf8, 0x04, 0xe0, +0x03, 0x97, 0x04, 0x90, 0xf8, 0xe7, 0x00, 0x20, 0x00, 0x90, 0x02, 0xab, +0x00, 0x98, 0xc0, 0x46, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, +0xdb, 0xfc, 0x38, 0x1c, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, +0x38, 0x1c, 0xfe, 0xf7, 0x8d, 0xfd, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, +0x01, 0x24, 0x20, 0x1c, 0x12, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, +0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x13, 0xd0, 0xf8, 0x88, 0x0f, 0x4a, +0x90, 0x42, 0x02, 0xd0, 0x0e, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0xb9, 0x68, +0x27, 0x1c, 0x90, 0x42, 0x00, 0xd0, 0x00, 0x27, 0x38, 0x06, 0x00, 0x0e, +0x03, 0xf0, 0xa0, 0xfc, 0x03, 0xf0, 0x76, 0xfc, 0x02, 0x90, 0x00, 0xe0, +0x02, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa7, 0xfc, 0x20, 0x1c, +0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0xed, 0xfe, 0x00, 0x00, 0xfe, 0xca, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, +0x00, 0x24, 0x00, 0x2f, 0x04, 0xd3, 0x04, 0xf0, 0x9b, 0xf8, 0x01, 0x34, +0xbc, 0x42, 0xfa, 0xd9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, +0x14, 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x1f, 0x1c, 0x1b, 0x4b, 0x32, 0x04, +0x12, 0x0c, 0x3c, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x2a, 0xfb, 0x32, 0x0c, +0x17, 0x4b, 0x3e, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x24, 0xfb, 0x15, 0x4b, +0x2a, 0x04, 0x12, 0x0c, 0x40, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x1d, 0xfb, +0x2a, 0x0c, 0x11, 0x4b, 0x42, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x17, 0xfb, +0x0e, 0x4b, 0x22, 0x04, 0x12, 0x0c, 0x44, 0x21, 0x02, 0x20, 0xfe, 0xf7, +0x10, 0xfb, 0x22, 0x0c, 0x0a, 0x4b, 0x46, 0x21, 0x02, 0x20, 0xfe, 0xf7, +0x0a, 0xfb, 0x08, 0x4b, 0x3a, 0x04, 0x12, 0x0c, 0x48, 0x21, 0x02, 0x20, +0xfe, 0xf7, 0x03, 0xfb, 0x3a, 0x0c, 0x04, 0x4b, +0x4a, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0xfd, 0xfa, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x7b, 0xb7, 0x21, 0x40, 0x88, 0xb5, 0x11, 0x27, +0x3f, 0x04, 0x38, 0x62, 0x79, 0x62, 0xba, 0x62, 0xfb, 0x62, 0x04, 0x20, +0xff, 0xf7, 0xaa, 0xff, 0x07, 0x48, 0x40, 0x6b, 0xc0, 0x46, 0x00, 0x90, +0x00, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x01, 0xd1, 0x01, 0x20, +0x00, 0xe0, 0x00, 0x20, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x11, 0x40, 0xf0, 0xb5, 0x8a, 0xb0, 0x00, 0x24, 0x05, 0x94, +0x69, 0x49, 0xc9, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x68, 0x4a, 0x11, 0x68, +0x01, 0x22, 0x12, 0x04, 0x0a, 0x40, 0x17, 0x21, 0x66, 0x4e, 0x00, 0x2a, +0x06, 0xd1, 0x64, 0x4a, 0x13, 0x68, 0x1b, 0x0c, 0x04, 0xd1, 0x12, 0x68, +0x92, 0x0a, 0x01, 0xd3, 0xf1, 0x60, 0x02, 0xe0, 0x61, 0x4a, 0xc0, 0x46, +0x11, 0x64, 0x61, 0x49, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x03, 0x29, +0x54, 0xd1, 0xe9, 0x21, 0x01, 0x91, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, +0x06, 0x94, 0x06, 0x99, 0x8a, 0x00, 0x5b, 0x49, 0x8a, 0x58, 0x00, 0x2a, +0x73, 0xd0, 0x80, 0x20, 0x02, 0x90, 0x06, 0x98, 0x81, 0x00, 0x57, 0x48, +0x41, 0x58, 0x02, 0x9a, 0x11, 0x43, 0x02, 0x91, 0x00, 0x24, 0x00, 0x27, +0x25, 0x02, 0x28, 0x1c, 0x38, 0x43, 0x09, 0x90, 0x09, 0x98, 0x00, 0x04, +0x51, 0x4b, 0x18, 0x43, 0x04, 0x90, 0x09, 0x98, 0xef, 0x23, 0xdb, 0x05, +0x18, 0x43, 0x03, 0x90, 0x06, 0x98, 0x80, 0x00, 0x4b, 0x49, 0x08, 0x58, +0x00, 0x04, 0x03, 0x99, 0x08, 0x43, 0x03, 0x90, 0x00, 0x2f, 0x02, 0xd1, +0x03, 0x98, 0xc0, 0x46, 0x70, 0x60, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, +0x04, 0x98, 0xff, 0xf7, 0x89, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x99, +0xc0, 0x46, 0xb1, 0x60, 0x03, 0x99, 0xc0, 0x46, 0x71, 0x60, 0x5c, 0xe0, +0x79, 0x1c, 0x0f, 0x04, 0x3f, 0x0c, 0x17, 0x2f, 0xd1, 0xdd, 0x61, 0x1c, +0x0c, 0x04, 0x24, 0x0c, 0x16, 0x2c, 0xca, 0xdd, 0x06, 0x99, 0x01, 0x31, +0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 0x37, 0x4a, 0x51, 0x58, 0x00, 0x29, +0xb7, 0xd1, 0x48, 0xe0, 0xbf, 0x21, 0xc9, 0x43, 0x04, 0x91, 0xff, 0x21, +0x02, 0x91, 0x97, 0x21, 0x01, 0x91, 0x06, 0x94, 0x06, 0x99, 0x89, 0x00, +0x31, 0x4f, 0x79, 0x58, 0x00, 0x29, 0x1c, 0xd0, 0x09, 0x94, 0x08, 0x94, +0x06, 0x98, 0x80, 0x00, 0x38, 0x58, 0xc0, 0x46, 0x07, 0x90, 0x07, 0x98, +0x00, 0x04, 0x26, 0xe0, 0x05, 0x98, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, +0x03, 0x90, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, +0x49, 0xff, 0x00, 0x28, 0x23, 0xd1, 0x09, 0x99, 0x01, 0x31, 0x09, 0x91, +0x17, 0x29, 0x06, 0xd8, 0x00, 0xe0, 0x1c, 0xe0, 0x08, 0x98, 0x00, 0x02, +0x09, 0x99, 0x08, 0x43, 0x07, 0xe0, 0x08, 0x99, 0x01, 0x31, 0x08, 0x91, +0x17, 0x29, 0x0a, 0xd8, 0x09, 0x94, 0x08, 0x98, 0x00, 0x02, 0x07, 0x99, +0x09, 0x04, 0x08, 0x43, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x05, 0x90, +0xd6, 0xe7, 0x06, 0x99, 0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 0x89, 0x00, +0x79, 0x58, 0x00, 0x29, 0xc4, 0xd1, 0x0c, 0x4a, 0x11, 0x68, 0x49, 0x0c, +0x05, 0xd2, 0x11, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x11, 0x68, 0x89, 0x0a, +0x03, 0xd3, 0x00, 0x99, 0xc0, 0x46, 0xf1, 0x60, 0x03, 0xe0, 0x00, 0x99, +0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x40, 0x01, 0x18, 0x40, +0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, +0x00, 0x00, 0x18, 0x40, 0x30, 0x6e, 0x21, 0x40, 0x43, 0xff, 0x00, 0x00, +0x0c, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x82, 0xb0, 0x00, 0x20, 0x01, 0x90, +0x1e, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x1b, 0xd1, 0x40, 0x88, 0x00, 0x28, +0x18, 0xd1, 0x68, 0x46, 0x01, 0xf0, 0x6a, 0xfe, 0x00, 0x28, 0x13, 0xd1, +0xa8, 0x20, 0x01, 0xf0, 0xab, 0xfe, 0x18, 0x4f, 0x00, 0x28, 0x11, 0xd0, +0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0x78, 0x6b, 0xc0, 0x46, 0x01, 0x90, +0x01, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x06, 0xd1, 0x00, 0x20, +0x01, 0xf0, 0x9a, 0xfe, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfe, +0x00, 0x23, 0xdb, 0x43, 0x18, 0x1c, 0x19, 0x1c, 0x1a, 0x1c, 0xff, 0xf7, +0xc7, 0xfe, 0x00, 0x28, 0x03, 0xd1, 0xff, 0xf7, 0xdf, 0xfe, 0x00, 0x28, +0xe5, 0xd0, 0x38, 0x6a, 0x79, 0x6a, 0xba, 0x6a, 0xfb, 0x6a, 0xff, 0xf7, +0x7c, 0xfe, 0xde, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x11, 0x40, +0xff, 0xb5, 0x85, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, +0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x82, 0xe0, +0x26, 0x1c, 0x43, 0x4d, 0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, +0x09, 0x05, 0x41, 0x48, 0x41, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, +0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, 0x3e, 0x4a, 0x51, 0x69, +0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0xff, 0x23, +0x01, 0x33, 0x19, 0x43, 0x39, 0x4b, 0xc0, 0x46, 0x59, 0x61, 0xff, 0x23, +0x01, 0x33, 0x9a, 0x43, 0x36, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, +0x12, 0x05, 0xd1, 0x60, 0x33, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, +0x11, 0x61, 0x31, 0x4a, 0xff, 0x23, 0x01, 0x33, 0x91, 0x69, 0x19, 0x43, +0x91, 0x61, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x85, 0x21, 0x89, 0x04, +0x04, 0x91, 0x00, 0x2f, 0x34, 0xd0, 0x28, 0x48, 0x86, 0x42, 0x04, 0xd1, +0x30, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0xd5, 0xfe, 0x2a, 0x1c, +0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x01, 0x20, 0x06, 0x99, 0x05, 0x9a, +0x33, 0x1c, 0xfe, 0xf7, 0x5d, 0xf9, 0x22, 0x48, 0x22, 0x49, 0x4a, 0x68, +0x52, 0x0a, 0x09, 0xd3, 0xff, 0x21, 0x01, 0x31, 0x20, 0x4a, 0xc0, 0x46, +0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x13, 0xe0, +0x01, 0x38, 0xf0, 0xd1, 0xf9, 0xe7, 0x7f, 0x1b, 0x0e, 0xd0, 0x15, 0x48, +0x86, 0x42, 0x01, 0xd1, 0x64, 0x19, 0x00, 0xe0, 0x76, 0x19, 0x06, 0x99, +0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, +0x05, 0x1c, 0xca, 0xe7, 0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, +0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, +0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, +0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, +0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, +0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0xb0, +0xff, 0xb5, 0x85, 0xb0, 0x04, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, +0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, +0x0f, 0x20, 0x7d, 0xe0, 0x26, 0x1c, 0x40, 0x4d, 0xaf, 0x42, 0x00, 0xd2, +0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x3e, 0x48, 0x3e, 0x4b, 0x99, 0x42, +0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, +0x3b, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, +0x02, 0x92, 0x10, 0x23, 0x19, 0x43, 0x37, 0x4b, 0xc0, 0x46, 0x59, 0x61, +0x10, 0x23, 0x9a, 0x43, 0x34, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, +0x12, 0x05, 0xd1, 0x60, 0x31, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, +0x11, 0x61, 0x2f, 0x4a, 0x10, 0x23, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, +0x1a, 0x04, 0x11, 0x61, 0x21, 0x21, 0x09, 0x05, 0x04, 0x91, 0x00, 0x2f, +0x33, 0xd0, 0x2a, 0x1c, 0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x00, 0x20, +0x06, 0x99, 0x07, 0x9a, 0x33, 0x1c, 0xfe, 0xf7, 0xc7, 0xf8, 0x25, 0x48, +0x25, 0x49, 0x4a, 0x68, 0x52, 0x09, 0x08, 0xd3, 0x10, 0x21, 0x24, 0x4a, +0xc0, 0x46, 0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, +0x1b, 0xe0, 0x01, 0x38, 0xf1, 0xd1, 0xf9, 0xe7, 0x19, 0x48, 0x86, 0x42, +0x04, 0xd1, 0x20, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0x1c, 0xfe, +0x7f, 0x1b, 0x0e, 0xd0, 0x14, 0x48, 0x86, 0x42, 0x01, 0xd0, 0x76, 0x19, +0x00, 0xe0, 0x64, 0x19, 0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, +0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 0x05, 0x1c, 0xcb, 0xe7, 0x0f, 0x48, +0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, +0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, +0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, +0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xf0, 0xff, 0x00, 0x00, 0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, +0x00, 0x00, 0x00, 0xb0, 0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, +0x0a, 0x70, 0x01, 0x30, 0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, +0xa0, 0x82, 0x20, 0x40, 0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, +0x01, 0x32, 0x88, 0x42, 0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, +0x02, 0xd3, 0x40, 0x1a, 0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, +0x01, 0x1c, 0xff, 0x27, 0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, +0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, +0x4b, 0x00, 0x59, 0x18, 0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, +0xdb, 0x00, 0xd7, 0x50, 0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, +0x57, 0x60, 0x8b, 0x68, 0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, +0x13, 0x61, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, +0xd1, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, +0x04, 0x28, 0xd9, 0xdb, 0x38, 0x1c, 0xf6, 0xe7, 0xd0, 0xab, 0x20, 0x40, +0xf7, 0xb5, 0xc5, 0xb0, 0x14, 0x1c, 0x00, 0x20, 0x11, 0x21, 0x21, 0x40, +0x5f, 0xd0, 0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x5b, 0x4a, +0x51, 0x58, 0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, +0x04, 0xe0, 0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, +0x00, 0x28, 0x4c, 0xd0, 0x00, 0x22, 0x01, 0x92, 0x00, 0x92, 0x40, 0x23, +0x00, 0x21, 0x00, 0x20, 0x03, 0xaa, 0x00, 0xf0, +0x8f, 0xfa, 0x05, 0xa9, 0x00, 0x20, 0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, +0x12, 0x0e, 0x45, 0x9b, 0x9a, 0x42, 0x05, 0xd1, 0x01, 0x9a, 0x01, 0x32, +0x12, 0x06, 0x12, 0x0e, 0x01, 0x92, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06, +0x00, 0x0e, 0x10, 0x28, 0xed, 0xdb, 0x01, 0x9a, 0x00, 0x2a, 0x4f, 0xd0, +0x45, 0x9b, 0x04, 0x2b, 0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, +0x80, 0x0d, 0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x03, 0xaa, +0x00, 0xf0, 0x6a, 0xfa, 0x00, 0x21, 0x01, 0x91, 0x03, 0xa8, 0x06, 0x99, +0x49, 0x0c, 0x89, 0x05, 0x2a, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, +0x46, 0x9b, 0x9a, 0x42, 0x12, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, +0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, +0x00, 0xf0, 0x52, 0xfa, 0x01, 0x99, 0x03, 0x9d, 0x48, 0x1c, 0x01, 0x06, +0x09, 0x0e, 0x01, 0x91, 0x0f, 0xe0, 0x57, 0xe0, 0x48, 0x01, 0x86, 0x0d, +0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, +0x00, 0xf0, 0x40, 0xfa, 0x03, 0xa8, 0x06, 0x99, 0x49, 0x0c, 0x89, 0x05, +0xd7, 0xd1, 0x01, 0x99, 0x00, 0x29, 0x11, 0xd1, 0xff, 0x20, 0x3f, 0xe0, +0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92, +0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 0x00, 0xf0, 0x2a, 0xfa, +0x03, 0x9d, 0x01, 0xe0, 0x20, 0x0a, 0xed, 0xd2, 0x01, 0x20, 0x00, 0x04, +0x20, 0x43, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, +0x50, 0x50, 0x30, 0x1c, 0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x45, 0x9b, +0x04, 0x2b, 0x00, 0xd0, 0x0c, 0x20, 0x02, 0x90, 0xb0, 0x60, 0x00, 0x20, +0x20, 0x21, 0x21, 0x40, 0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, +0x02, 0x98, 0x28, 0x18, 0xff, 0x21, 0xff, 0x30, 0x08, 0x30, 0x09, 0x31, +0xff, 0xf7, 0x12, 0xff, 0x43, 0x01, 0x18, 0x18, 0xc0, 0x00, 0x02, 0x99, +0x40, 0x1a, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21, 0x21, 0x40, 0x50, 0x29, +0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60, 0x38, 0x1c, 0x48, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xff, 0x20, 0xf9, 0xe7, 0xd0, 0xab, 0x20, 0x40, +0x80, 0xb4, 0x00, 0x23, 0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, +0x7b, 0x40, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, +0xd8, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, +0xc6, 0xb0, 0x04, 0x28, 0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, +0x45, 0x91, 0x41, 0x4a, 0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, +0xc0, 0x43, 0x76, 0xe0, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, +0x18, 0x18, 0xc0, 0x00, 0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, +0x00, 0x21, 0x02, 0x91, 0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, +0xff, 0x21, 0x68, 0x1e, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe, 0x61, 0x68, +0x40, 0x18, 0x01, 0x90, 0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, +0xaf, 0x1b, 0x09, 0xe0, 0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, +0xff, 0xf7, 0xc1, 0xfe, 0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, +0x00, 0x22, 0x00, 0x92, 0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, +0x00, 0xf0, 0x9e, 0xf9, 0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, +0xc0, 0x43, 0x02, 0x99, 0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, +0xed, 0x1b, 0xa0, 0x68, 0xa8, 0x42, 0x00, 0xd1, +0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99, 0xcf, 0x43, 0x00, 0x22, +0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, +0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90, 0x05, 0x98, 0x00, 0x0a, +0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x05, 0x90, 0xff, 0x23, +0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21, 0x03, 0xa8, 0xff, 0xf7, +0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99, 0x99, 0x43, 0x00, 0x06, +0x00, 0x0e, 0x00, 0x02, 0x08, 0x43, 0x05, 0x90, 0x0c, 0x23, 0x00, 0x21, +0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 0xbb, 0xf9, 0x00, 0x20, 0x45, 0x99, +0x06, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0xc1, 0x43, 0x61, 0x60, 0xa1, 0x60, +0xe1, 0x60, 0x21, 0x61, 0x61, 0x61, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb4, 0x4c, 0x42, +0x00, 0x29, 0x00, 0xdb, 0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, +0x21, 0xda, 0x12, 0x4d, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, +0x01, 0x2a, 0x05, 0xd0, 0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, +0x01, 0x69, 0x0b, 0xe0, 0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, +0x0f, 0xd3, 0x05, 0xe0, 0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, +0x09, 0xd3, 0x09, 0x1b, 0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, +0xc1, 0x68, 0x09, 0x19, 0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, +0xf6, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, +0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, +0xd2, 0x00, 0x2c, 0x49, 0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, +0x00, 0x23, 0xdb, 0x43, 0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, +0x01, 0xd2, 0x18, 0x1c, 0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, +0x21, 0x69, 0x8a, 0x42, 0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, +0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, +0x07, 0xfe, 0x61, 0x68, 0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, +0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x07, 0xfe, 0xc2, 0x19, 0xff, 0x21, +0x09, 0x31, 0x8a, 0x42, 0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, +0x0b, 0x1a, 0x03, 0x93, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, +0xe1, 0xf8, 0xe0, 0x68, 0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, +0x5d, 0x19, 0xff, 0x1a, 0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, +0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, +0x3b, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, +0xe0, 0x60, 0x02, 0x98, 0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, +0xc2, 0xd8, 0x02, 0x98, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, +0x00, 0x21, 0x01, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, +0x30, 0x49, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, +0x04, 0x28, 0x01, 0xda, 0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, +0x02, 0x9a, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, +0x01, 0xd9, 0x22, 0x69, 0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, +0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, +0xa1, 0xfd, 0x61, 0x68, 0x40, 0x18, 0x00, 0x90, +0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, +0xa0, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x43, +0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32, 0x91, 0x42, 0x13, 0xd9, +0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c, 0x1e, 0x1c, 0x00, 0xf0, +0xd0, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19, 0xe0, 0x60, 0x21, 0x69, +0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b, 0x01, 0x98, 0x30, 0x18, +0x01, 0x90, 0x12, 0xe0, 0x01, 0x1c, 0x00, 0x9e, 0x30, 0x1c, 0x2a, 0x1c, +0x3b, 0x1c, 0x00, 0xf0, 0xbc, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, +0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0x01, 0x98, +0xc0, 0x19, 0x01, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xb9, 0xd8, 0x01, 0x98, +0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, +0xb0, 0xb5, 0xc3, 0xb0, 0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, +0x06, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, +0x6b, 0x0c, 0x04, 0xd2, 0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x62, 0x09, 0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, +0x40, 0x68, 0x0c, 0x23, 0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, +0x11, 0x2c, 0x0d, 0xd0, 0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, +0x14, 0x2c, 0x0a, 0xd1, 0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, +0x03, 0x98, 0x07, 0x06, 0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, +0x02, 0x9f, 0x38, 0x1c, 0xdb, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, +0x03, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, +0xfb, 0xd3, 0x70, 0x47, 0xd0, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, +0x9f, 0xf9, 0x57, 0x20, 0x02, 0xf0, 0xfc, 0xf8, 0x02, 0xf0, 0x70, 0xf8, +0x00, 0x0a, 0xfb, 0xd3, 0x02, 0xf0, 0x7e, 0xf9, 0x08, 0xbc, 0x18, 0x47, +0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x07, 0x9a, 0x1f, 0x1c, 0xff, 0x23, +0x01, 0x33, 0x1a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, +0x00, 0x0c, 0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0x82, 0xf9, +0x53, 0x20, 0x02, 0xf0, 0xdf, 0xf8, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, +0x02, 0xf0, 0xda, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xd7, 0xf8, 0x30, 0x1c, +0x02, 0xf0, 0xd4, 0xf8, 0x02, 0xf0, 0x5a, 0xf9, 0xff, 0xf7, 0xce, 0xff, +0x02, 0xf0, 0x6e, 0xf9, 0x54, 0x20, 0x02, 0xf0, 0xcb, 0xf8, 0x00, 0x98, +0x02, 0xf0, 0xc8, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xc5, 0xf8, 0x30, 0x1c, +0x14, 0xe0, 0x02, 0xf0, 0x61, 0xf9, 0x52, 0x20, 0x02, 0xf0, 0xbe, 0xf8, +0x01, 0x98, 0x02, 0xf0, 0xbb, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xb8, 0xf8, +0x30, 0x1c, 0x02, 0xf0, 0xb5, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xb2, 0xf8, +0x00, 0x20, 0x02, 0xf0, 0xaf, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xac, 0xf8, +0x00, 0x20, 0x02, 0xf0, 0xa9, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, +0x1b, 0xf8, 0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, +0x27, 0xf9, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, +0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x40, 0x02, 0x08, 0x43, 0x05, 0x1c, +0x02, 0xf0, 0x32, 0xf9, 0x53, 0x20, 0x02, 0xf0, 0x8f, 0xf8, 0x28, 0x0c, +0x06, 0x1c, 0x02, 0xf0, 0x8b, 0xf8, 0x28, 0x0a, 0x01, 0x90, 0x00, 0x90, +0x02, 0xf0, 0x86, 0xf8, 0x28, 0x1c, 0x02, 0xf0, +0x83, 0xf8, 0x02, 0xf0, 0x09, 0xf9, 0xff, 0xf7, 0x7d, 0xff, 0x02, 0xf0, +0x1d, 0xf9, 0x84, 0x20, 0x02, 0xf0, 0x7a, 0xf8, 0x30, 0x1c, 0x02, 0xf0, +0x77, 0xf8, 0x00, 0x98, 0x02, 0xf0, 0x74, 0xf8, 0x28, 0x1c, 0x02, 0xf0, +0x71, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0, +0x6b, 0xf8, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xef, 0xf8, 0x02, 0xf0, +0x05, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0x62, 0xf8, 0x30, 0x1c, 0x02, 0xf0, +0x5f, 0xf8, 0x01, 0x98, 0x02, 0xf0, 0x5c, 0xf8, 0x28, 0x1c, 0x02, 0xf0, +0x59, 0xf8, 0x02, 0xf0, 0xdf, 0xf8, 0xff, 0xf7, 0x53, 0xff, 0x02, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, +0x80, 0xb5, 0x01, 0xf0, 0x89, 0xf8, 0x06, 0x4f, 0xc0, 0x46, 0xf8, 0x60, +0x01, 0xf0, 0xe4, 0xf8, 0x78, 0x80, 0x01, 0xf0, 0xa5, 0xf8, 0x38, 0x71, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0xb5, 0x01, 0xf0, 0xf7, 0xf8, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x80, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0xc1, 0x68, +0x01, 0x29, 0x11, 0xd1, 0x02, 0x22, 0xc1, 0x6f, 0x0a, 0x43, 0xc2, 0x67, +0x08, 0x49, 0xc0, 0x46, 0x0a, 0x60, 0x80, 0x23, 0xc2, 0x6f, 0x1a, 0x43, +0xc2, 0x67, 0x0a, 0x60, 0x82, 0x22, 0x80, 0x30, 0x02, 0x60, 0x4a, 0x60, +0x00, 0x21, 0x81, 0x80, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x01, 0x11, 0x00, 0xf0, 0xb4, 0x49, 0x49, 0xca, 0x1d, 0x99, 0x32, +0x00, 0x20, 0x00, 0x27, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28, +0xfa, 0xd3, 0x45, 0x4c, 0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30, +0x20, 0x28, 0xfa, 0xd3, 0x42, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50, +0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65, +0x8f, 0x65, 0x3e, 0x4d, 0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60, +0xaf, 0x61, 0xef, 0x60, 0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00, +0x09, 0x18, 0x49, 0x01, 0x34, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d, +0xf5, 0x33, 0x33, 0x4c, 0x34, 0x19, 0xe3, 0x63, 0x87, 0x23, 0x9b, 0x00, +0xcb, 0x18, 0x63, 0x63, 0xcf, 0x23, 0x9b, 0x00, 0xcb, 0x18, 0xb4, 0x18, +0xe3, 0x63, 0x30, 0x4b, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30, 0x02, 0x28, +0xe5, 0xdb, 0x29, 0x48, 0xc1, 0x1d, 0xf5, 0x31, 0x28, 0x4c, 0xc0, 0x46, +0xa1, 0x62, 0x61, 0x6b, 0xcf, 0x23, 0x9b, 0x00, 0xe1, 0x62, 0xc1, 0x18, +0x91, 0x62, 0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21, 0xe1, 0x64, +0x25, 0x49, 0xc0, 0x46, 0x21, 0x65, 0x25, 0x49, 0x0b, 0x69, 0xc0, 0x46, +0x63, 0x65, 0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66, 0x8b, 0x68, +0xc0, 0x46, 0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66, 0x1f, 0x4b, +0xc0, 0x46, 0xe3, 0x66, 0x27, 0x67, 0x67, 0x67, 0x1d, 0x4b, 0xc3, 0x18, +0x01, 0x26, 0xa3, 0x67, 0x66, 0x61, 0xe7, 0x61, 0xe3, 0x1d, 0x69, 0x33, +0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x19, 0x4b, 0xc0, 0x46, 0x13, 0x65, +0xcb, 0x69, 0xc0, 0x46, 0x53, 0x65, 0xc3, 0x1d, 0x51, 0x33, 0xd3, 0x65, +0x2b, 0x1d, 0x13, 0x66, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x66, 0x89, 0x69, +0xc0, 0x46, 0x91, 0x66, 0x11, 0x49, 0xc0, 0x46, 0xd1, 0x66, 0x16, 0x67, +0x56, 0x67, 0x10, 0x4b, 0xc0, 0x18, 0x90, 0x67, 0x56, 0x61, 0xd7, 0x61, +0xd0, 0x1d, 0x69, 0x30, 0x07, 0x73, 0xf0, 0xbc, +0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, +0xd0, 0x2c, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x5c, 0x04, 0x00, 0x00, +0x30, 0x01, 0x18, 0x00, 0xf8, 0x28, 0x00, 0x80, 0x80, 0x54, 0xff, 0xff, +0x7c, 0x05, 0x00, 0x00, 0x38, 0x01, 0x18, 0x00, 0x90, 0x54, 0xff, 0xff, +0x7c, 0x07, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x21, 0x1c, 0x4a, 0xbb, 0x23, +0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x72, 0x19, 0x23, 0xdb, 0x01, 0xd0, 0x18, +0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x81, 0x61, 0x59, 0x60, 0xb9, 0x72, +0x01, 0x27, 0x1f, 0x73, 0x19, 0x61, 0x17, 0x23, 0xdb, 0x01, 0xd3, 0x18, +0xd9, 0x63, 0x13, 0x4b, 0x51, 0x27, 0xbf, 0x03, 0xc3, 0x62, 0x3b, 0x60, +0x44, 0x69, 0xe4, 0x18, 0x04, 0x63, 0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, +0xe4, 0x02, 0x44, 0x63, 0x0d, 0x4c, 0xc0, 0x46, 0xbc, 0x60, 0xc4, 0x6a, +0xc0, 0x46, 0x04, 0x62, 0x44, 0x69, 0xe4, 0x18, 0x0a, 0x4b, 0xe3, 0x18, +0xfb, 0x60, 0xc3, 0x6a, 0xc0, 0x46, 0x43, 0x62, 0x03, 0x6a, 0xc0, 0x46, +0xc3, 0x61, 0x81, 0x63, 0x51, 0x64, 0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, +0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, +0xfc, 0x07, 0x00, 0x00, 0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22, +0x1c, 0x49, 0xc9, 0x23, 0x1b, 0x01, 0xc8, 0x18, 0x02, 0x70, 0x01, 0x20, +0xbb, 0x23, 0x1b, 0x01, 0xcb, 0x18, 0x58, 0x72, 0x18, 0x48, 0x03, 0x1c, +0x00, 0x27, 0xdc, 0x1d, 0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37, +0x3f, 0x2f, 0xf8, 0xd3, 0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18, +0x33, 0x23, 0x9b, 0x01, 0xcc, 0x18, 0xfa, 0x60, 0x60, 0x61, 0x40, 0x20, +0xb8, 0x60, 0xa2, 0x61, 0xe2, 0x61, 0xca, 0x64, 0x0a, 0x66, 0x0d, 0x48, +0xc0, 0x46, 0xc2, 0x60, 0x0c, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e, +0xb8, 0x63, 0x0b, 0x48, 0x65, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x02, 0x68, +0xc0, 0x46, 0x8a, 0x83, 0x42, 0x68, 0xc0, 0x46, 0xca, 0x83, 0x80, 0x68, +0xc0, 0x46, 0x20, 0x80, 0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0x3c, 0xbd, 0x20, 0x40, 0x3c, 0xef, 0x20, 0x40, 0x80, 0x00, 0x14, 0x40, +0x40, 0x00, 0x14, 0x40, 0x00, 0x20, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x73, +0xcb, 0x1d, 0xff, 0x33, 0x3a, 0x33, 0x88, 0x61, 0xc8, 0x61, 0x18, 0x70, +0x06, 0x4a, 0xc0, 0x46, 0x10, 0x65, 0x50, 0x66, 0x90, 0x66, 0x08, 0x70, +0x58, 0x70, 0xbb, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x08, 0x72, 0x70, 0x47, +0xa8, 0x04, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb4, 0x2f, 0x49, +0x2f, 0x4a, 0xc0, 0x46, 0x11, 0x61, 0x01, 0x23, 0x9b, 0x02, 0xc8, 0x18, +0x50, 0x61, 0x2d, 0x48, 0xc0, 0x46, 0x10, 0x62, 0xdb, 0x00, 0xc3, 0x18, +0x53, 0x62, 0x00, 0x23, 0x13, 0x63, 0x53, 0x63, 0x29, 0x4a, 0x2a, 0x4f, +0xd4, 0x1d, 0xff, 0x34, 0xfa, 0x34, 0x14, 0xc7, 0x08, 0x3f, 0x3b, 0x61, +0x1c, 0x1f, 0x7c, 0x61, 0x26, 0x4f, 0xc0, 0x46, 0x39, 0x60, 0xb8, 0x61, +0x79, 0x61, 0xf8, 0x62, 0x3b, 0x63, 0x7b, 0x64, 0xba, 0x64, 0xfa, 0x65, +0x22, 0x4f, 0xfe, 0x1d, 0xf9, 0x36, 0x22, 0x4d, 0xec, 0x1d, 0x79, 0x34, +0xe6, 0x61, 0x51, 0x26, 0xb6, 0x03, 0x37, 0x61, 0xe4, 0x69, 0xc0, 0x46, +0x74, 0x61, 0x2f, 0x67, 0x1d, 0x4d, 0x09, 0x27, 0x7f, 0x04, 0xec, 0x1d, +0x75, 0x34, 0x7c, 0x60, 0x3d, 0x60, 0x1b, 0x4c, 0xc0, 0x46, 0x3c, 0x61, +0xe6, 0x1d, 0x75, 0x36, 0x7e, 0x61, 0x19, 0x4f, +0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c, 0x00, 0x21, 0xff, 0x24, +0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50, 0x01, 0x31, 0xa1, 0x42, +0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27, 0xff, 0x02, 0x83, 0x00, +0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3, 0x00, 0x20, 0x81, 0x00, +0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3, 0xf0, 0xbc, 0x70, 0x47, +0x24, 0xa3, 0x20, 0x40, 0x40, 0x01, 0x18, 0x00, 0x24, 0x83, 0x20, 0x40, +0x24, 0xa9, 0x20, 0x40, 0x80, 0x01, 0x18, 0x00, 0x28, 0x03, 0x00, 0x80, +0x24, 0xa7, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0x24, 0xa8, 0x20, 0x40, +0xa4, 0xa8, 0x20, 0x40, 0x88, 0x03, 0x00, 0x80, 0xb8, 0xb5, 0x2d, 0x48, +0xfd, 0xf7, 0xc6, 0xfa, 0x01, 0x20, 0x2c, 0x49, 0x0a, 0x68, 0x52, 0x0c, +0x06, 0xd2, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x0a, 0x68, 0x92, 0x0a, +0x00, 0xd2, 0x00, 0x20, 0x04, 0x06, 0x24, 0x0e, 0x26, 0x4a, 0xd7, 0x1d, +0x0d, 0x37, 0x00, 0x23, 0x00, 0x20, 0x9d, 0x00, 0x78, 0x51, 0x01, 0x33, +0x04, 0x2b, 0xfa, 0xd3, 0x01, 0x27, 0x3f, 0x05, 0x50, 0x61, 0xf8, 0x60, +0xd0, 0x61, 0xf8, 0x61, 0x00, 0x23, 0xdb, 0x43, 0x93, 0x61, 0x3b, 0x61, +0x13, 0x62, 0x3b, 0x62, 0x00, 0x27, 0x1c, 0x4b, 0x8d, 0x68, 0xc0, 0x46, +0x00, 0x95, 0x8d, 0x69, 0xc0, 0x46, 0x00, 0x95, 0x00, 0x2c, 0x0b, 0xd0, +0xdd, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x9d, 0x6b, 0xc0, 0x46, 0x00, 0x95, +0x5d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x1d, 0x6b, 0xc0, 0x46, 0x00, 0x95, +0x01, 0x37, 0x40, 0x2f, 0xe8, 0xd3, 0x00, 0x27, 0x6c, 0x46, 0x01, 0x23, +0x5b, 0x07, 0x1c, 0x43, 0x01, 0xe0, 0x20, 0x60, 0x01, 0x37, 0x0d, 0x68, +0x2b, 0x09, 0x02, 0xd2, 0x80, 0x2f, 0xf8, 0xd3, 0x01, 0xe0, 0x80, 0x2f, +0x03, 0xd3, 0x09, 0x49, 0x4b, 0x6e, 0x01, 0x33, 0x4b, 0x66, 0xd0, 0x62, +0x07, 0x48, 0xfd, 0xf7, 0x71, 0xfa, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x04, 0x02, 0xff, 0xff, +0x90, 0xb4, 0x00, 0x21, 0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01, +0x64, 0x1a, 0xa4, 0x00, 0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64, +0x58, 0x64, 0x10, 0x53, 0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67, +0xdc, 0x62, 0x01, 0x31, 0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc, +0x70, 0x47, 0x00, 0x00, 0x58, 0x67, 0x21, 0x40, 0xc8, 0x2a, 0x00, 0x80, +0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x64, 0x21, 0x07, 0x48, 0xc0, 0x46, +0x01, 0x63, 0x00, 0x21, 0xc9, 0x43, 0x41, 0x63, 0x81, 0x63, 0x00, 0x21, +0xc1, 0x63, 0x01, 0x64, 0x03, 0x48, 0x28, 0x22, 0x02, 0xf0, 0x06, 0xff, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x59, 0x03, 0xff, 0xff, +0x80, 0xb4, 0x01, 0x20, 0x40, 0x02, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x60, +0x3c, 0x20, 0x48, 0x60, 0x88, 0x60, 0x08, 0x48, 0xc0, 0x46, 0xc8, 0x60, +0x00, 0x20, 0x07, 0x4a, 0x87, 0x00, 0xcb, 0x68, 0xc0, 0x46, 0xda, 0x51, +0x01, 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, +0x50, 0x2d, 0x00, 0x80, 0x60, 0x2d, 0x00, 0x80, 0xd5, 0x4b, 0xff, 0xff, +0x12, 0x49, 0x13, 0x48, 0x67, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, +0x08, 0x38, 0x11, 0x4b, 0xca, 0x18, 0xc1, 0x60, +0x82, 0x60, 0x01, 0x61, 0x0f, 0x49, 0x10, 0x48, 0xa7, 0x23, 0x9b, 0x01, +0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x0e, 0x4b, 0xca, 0x18, 0xc1, 0x60, +0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49, 0x67, 0x23, 0x9b, 0x01, +0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b, 0xc2, 0x18, 0xc8, 0x60, +0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, 0x58, 0x1f, 0x21, 0x40, +0xb4, 0x2d, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00, 0x58, 0xef, 0x20, 0x40, +0xa0, 0x2d, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00, 0x58, 0x3f, 0x21, 0x40, +0xc8, 0x2d, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, 0x40, 0x4c, 0x00, 0x20, +0x0a, 0x01, 0x12, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0xd0, 0x62, +0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, +0x3a, 0x49, 0xc0, 0x46, 0xc8, 0x62, 0x08, 0x63, 0x48, 0x63, 0x20, 0x60, +0x01, 0x21, 0xe3, 0x1d, 0x59, 0x33, 0x60, 0x60, 0x19, 0x71, 0x18, 0x72, +0x98, 0x71, 0x98, 0x72, 0x59, 0x71, 0x58, 0x72, 0xd8, 0x71, 0xd8, 0x72, +0xe2, 0x1d, 0x49, 0x32, 0x11, 0x73, 0x19, 0x70, 0x90, 0x73, 0x98, 0x70, +0x51, 0x73, 0x59, 0x70, 0xd0, 0x73, 0xd8, 0x70, 0x11, 0x71, 0x11, 0x72, +0x90, 0x71, 0x90, 0x72, 0x50, 0x71, 0x50, 0x72, 0xd0, 0x71, 0xd0, 0x72, +0x18, 0x73, 0x02, 0x22, 0xe7, 0x1d, 0x69, 0x37, 0x3a, 0x70, 0x99, 0x73, +0xba, 0x70, 0x58, 0x73, 0x78, 0x70, 0xd8, 0x73, 0xf8, 0x70, 0x39, 0x71, +0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, +0xf9, 0x72, 0x39, 0x73, 0xe3, 0x1d, 0x79, 0x33, 0x1a, 0x70, 0xb9, 0x73, +0x99, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xd9, 0x70, 0x1a, 0x71, +0x1a, 0x72, 0x99, 0x71, 0x9a, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, +0xda, 0x72, 0x19, 0x73, 0xe7, 0x1d, 0x89, 0x37, 0x3a, 0x70, 0x99, 0x73, +0xb9, 0x70, 0x58, 0x73, 0x7a, 0x70, 0xd9, 0x73, 0xf9, 0x70, 0x39, 0x71, +0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, +0xf9, 0x72, 0x3a, 0x73, 0xe3, 0x1d, 0x99, 0x33, 0x1a, 0x70, 0xb9, 0x73, +0x9a, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xda, 0x70, 0x19, 0x71, +0x1a, 0x72, 0x99, 0x71, 0x99, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, +0xd9, 0x72, 0x20, 0x61, 0xe0, 0x60, 0x60, 0x61, 0xa0, 0x60, 0x90, 0xbc, +0x70, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 0x68, 0x19, 0x00, 0x80, +0x81, 0x20, 0x00, 0x02, 0x01, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x70, 0x47, +0xc0, 0x00, 0x14, 0x00, 0x0a, 0x49, 0x13, 0x23, 0xdb, 0x01, 0xc8, 0x18, +0x25, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x63, 0x00, 0x21, 0xc2, 0x1d, +0x29, 0x32, 0xc2, 0x61, 0x10, 0x1c, 0x01, 0x31, 0x08, 0x29, 0xf8, 0xd3, +0xc1, 0x1f, 0x29, 0x39, 0x00, 0x20, 0xc8, 0x61, 0x70, 0x47, 0x00, 0x00, +0xe8, 0x0d, 0x00, 0x80, 0x06, 0x48, 0x07, 0x49, 0xc0, 0x46, 0x08, 0x80, +0x48, 0x80, 0x00, 0x20, 0x88, 0x80, 0xc8, 0x80, 0x88, 0x60, 0x04, 0x49, +0xc0, 0x46, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, 0xff, 0xff, 0x00, 0x00, +0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0x21, 0x06, 0x48, +0xc2, 0x1d, 0x19, 0x32, 0xc1, 0x60, 0x01, 0x61, 0xc1, 0x61, 0x01, 0x62, +0x11, 0x71, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, +0xec, 0x05, 0x00, 0x80, 0x09, 0x48, 0x0a, 0x4b, 0xc0, 0x46, 0x18, 0x60, +0x00, 0x21, 0xc2, 0x1d, 0x4d, 0x32, 0xc2, 0x60, +0x10, 0x1c, 0x01, 0x31, 0x14, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x4d, 0x39, +0x00, 0x20, 0xc8, 0x60, 0x58, 0x60, 0x98, 0x60, 0x70, 0x47, 0x00, 0x00, +0x58, 0x07, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x0c, 0x49, +0x0c, 0x48, 0xfd, 0xf7, 0xea, 0xf8, 0x0c, 0x48, 0x00, 0x6a, 0x01, 0x23, +0xdb, 0x03, 0x98, 0x43, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x0a, 0x48, +0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, 0xc1, 0x6f, 0x19, 0x43, +0xc1, 0x67, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47, +0x59, 0xcd, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, 0xc0, 0x00, 0x18, 0x40, +0xc0, 0x00, 0x18, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, +0x00, 0xb5, 0x10, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, +0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x0d, 0x48, 0xc0, 0x46, 0x01, 0x60, +0x0c, 0x4b, 0x0d, 0x48, 0x0d, 0x4a, 0x00, 0x21, 0xfd, 0xf7, 0xb9, 0xf8, +0x0c, 0x48, 0x41, 0x8d, 0x01, 0x31, 0x41, 0x85, 0x00, 0x21, 0xc1, 0x85, +0x0a, 0x48, 0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, 0x09, 0x49, +0xc0, 0x46, 0x08, 0x62, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x01, 0x11, 0x00, 0xf1, 0xcc, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, +0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, +0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0xfe, 0xf7, 0xa3, 0xfe, 0x19, 0x4c, +0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x05, 0xd1, 0x60, 0x88, 0x00, 0x28, +0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67, 0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, +0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18, 0xc1, 0x43, 0xa8, 0x61, 0x29, 0x62, +0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03, 0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, +0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x70, 0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, +0xb8, 0x60, 0x00, 0xf0, 0x47, 0xfa, 0x00, 0xf0, 0xd9, 0xfa, 0x04, 0x20, +0xb8, 0x60, 0x07, 0x20, 0x78, 0x61, 0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, +0xe0, 0x18, 0x40, 0x8b, 0x04, 0x23, 0x18, 0x40, 0xa8, 0x62, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb4, 0x02, 0x1c, +0x00, 0x20, 0xff, 0x23, 0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, +0x00, 0xd1, 0x01, 0x20, 0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, +0x80, 0xbc, 0x70, 0x47, 0x18, 0x49, 0xca, 0x68, 0x18, 0x4b, 0x01, 0x2a, +0x0b, 0xd1, 0x4a, 0x88, 0x00, 0x2a, 0x08, 0xd1, 0xd9, 0x8a, 0x0a, 0x09, +0x00, 0xd3, 0x02, 0x20, 0x49, 0x09, 0xef, 0xd3, 0x01, 0x23, 0x18, 0x43, +0xec, 0xe7, 0x0a, 0x79, 0x00, 0x2a, 0x03, 0xd0, 0x18, 0x8a, 0x80, 0x07, +0x80, 0x0f, 0xe5, 0xe7, 0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x0a, 0x88, +0xff, 0x27, 0x01, 0x37, 0x17, 0x40, 0x0b, 0x49, 0x49, 0x88, 0x03, 0xd0, +0x4b, 0x0a, 0x01, 0xd3, 0x03, 0x20, 0xd7, 0xe7, 0x13, 0x0a, 0x03, 0xd3, +0x0b, 0x0a, 0x01, 0xd3, 0x02, 0x20, 0xd1, 0xe7, 0xd2, 0x09, 0xcf, 0xd3, +0xc9, 0x09, 0xcd, 0xd3, 0x01, 0x20, 0xcb, 0xe7, 0xe8, 0x0d, 0x00, 0x80, +0xa8, 0x1b, 0x00, 0x80, 0x88, 0x1b, 0x00, 0x80, 0xf0, 0xb5, 0xc1, 0xb0, +0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x52, 0x48, +0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x60, 0x50, 0x48, +0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21, 0x03, 0x03, 0x1b, 0x0b, +0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b, +0xe7, 0x1d, 0x79, 0x37, 0xab, 0x42, 0x1c, 0xd0, 0xe3, 0x1d, 0x79, 0x33, +0xdb, 0x69, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43, +0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 0x01, 0x23, 0x9b, 0x07, +0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 0x63, 0x60, 0x08, 0x30, +0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 0x3f, 0x48, 0x03, 0x03, +0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 0x01, 0x23, 0x1b, 0x03, +0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x63, 0x62, +0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a, 0x01, 0x33, 0x23, 0x62, +0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34, 0x5c, 0x65, 0x00, 0x29, +0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c, 0x6b, 0x44, 0x5c, 0x68, +0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42, 0xf5, 0xd1, 0x30, 0x4c, +0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x08, 0xd1, +0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24, 0x2b, 0x4b, 0xc0, 0x46, +0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b, 0x23, 0x4c, 0x51, 0x26, +0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0xfd, 0x69, 0xc0, 0x46, 0x75, 0x61, +0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60, 0x01, 0x25, 0xb5, 0x60, +0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x70, 0x88, 0x42, 0x21, 0xd0, 0x25, 0x1c, +0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f, 0x6b, 0x44, 0x34, 0x60, +0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60, 0x2b, 0x6f, 0x08, 0x33, +0x2b, 0x67, 0xfc, 0x69, 0xa3, 0x42, 0x02, 0xd3, 0x12, 0x4b, 0xc0, 0x46, +0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, +0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03, 0x2b, 0x6f, 0xc0, 0x46, +0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b, 0x03, 0xd3, 0x0e, 0x49, +0x01, 0x20, 0xfc, 0xf7, 0x72, 0xff, 0x41, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x01, 0x14, 0x40, +0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, +0x24, 0xa7, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x49, 0x4f, 0xff, 0xff, +0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22, 0x06, 0x24, 0x47, 0x4f, +0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33, 0x20, 0x2b, 0xf9, 0xd3, +0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61, 0x3c, 0x61, 0x3a, 0x61, +0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x3f, 0x4d, 0xab, 0x6f, +0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, +0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x9e, 0x08, 0x02, 0x23, +0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, +0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, +0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x02, 0x23, +0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, +0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, +0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, +0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, +0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, +0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, +0x2b, 0x43, 0x3b, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, +0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x02, 0x25, +0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, +0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x04, 0x23, 0x03, 0x43, +0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 0x00, 0x25, 0x3d, 0x61, +0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x00, 0x20, 0x3d, 0x61, +0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 0x02, 0x23, 0x33, 0x40, +0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30, 0x10, 0x28, 0xf2, 0xd3, +0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61, 0x3c, 0x61, 0x3a, 0x61, +0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08, 0xf0, 0xbc, 0x70, 0x47, +0x80, 0x00, 0x14, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0x00, 0x14, 0x40, +0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27, 0x44, 0x4a, 0xc0, 0x46, +0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c, 0xf9, 0xd3, 0x04, 0x26, +0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, +0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61, 0x3c, 0x4b, 0x9b, 0x6f, +0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, +0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f, 0x9d, 0x08, 0x02, 0x23, +0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, +0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, +0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x2d, 0x4b, 0x9d, 0x6f, +0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, +0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, +0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0xc5, 0x08, +0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, +0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, +0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, +0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x02, 0x25, +0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, +0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c, 0x33, 0x43, 0x13, 0x61, +0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x16, 0x61, +0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21, 0x25, 0x1c, 0xcd, 0x40, +0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x05, 0x23, +0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39, 0x10, 0x28, 0xf1, 0xd3, +0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61, 0x13, 0x61, 0x03, 0x20, +0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x00, +0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb5, 0x47, 0x48, 0x01, 0x89, 0x47, 0x4d, +0x07, 0x23, 0x5b, 0x02, 0xef, 0x18, 0xb9, 0x83, 0x40, 0x8b, 0xc0, 0x46, +0xf8, 0x83, 0x28, 0x79, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xb8, 0x83, +0xe8, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x68, 0x88, 0x00, 0x28, 0x03, 0xd1, +0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x54, 0xff, 0x01, 0x21, 0xc9, 0x03, +0x00, 0x20, 0xff, 0xf7, 0x4f, 0xff, 0x00, 0x24, 0x7d, 0x26, 0xf6, 0x00, +0x00, 0xe0, 0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0xad, 0xfe, 0x00, 0x0c, +0x01, 0xd3, 0xb4, 0x42, 0xf7, 0xd3, 0x00, 0x24, +0x05, 0xe0, 0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3c, 0xff, +0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0x9e, 0xfe, 0x40, 0x0b, 0x01, 0xd2, +0xb4, 0x42, 0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0xff, 0x23, +0xe1, 0x33, 0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0xb8, 0x8b, 0xff, 0x23, +0x01, 0x33, 0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01, 0x19, 0x43, +0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, +0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23, 0x19, 0x43, +0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, +0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, +0x04, 0x20, 0xff, 0xf7, 0x09, 0xff, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, +0xff, 0xf7, 0x04, 0xff, 0xe8, 0x68, 0x00, 0x28, 0x0c, 0xd1, 0x00, 0x21, +0x1b, 0x20, 0xff, 0xf7, 0xfd, 0xfe, 0x1a, 0x20, 0xff, 0xf7, 0x60, 0xfe, +0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7, 0xf4, 0xfe, +0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f, 0x08, 0xd9, +0x38, 0x1c, 0xff, 0xf7, 0x51, 0xfe, 0x79, 0x00, 0x49, 0x19, 0x1b, 0x23, +0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, 0x01, 0x37, 0x20, 0x2f, 0xef, 0xd3, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0x81, 0xb0, 0x13, 0x48, 0x01, 0x68, 0xc0, 0x46, +0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x68, 0xc0, 0x46, +0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x69, 0xc0, 0x46, +0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x69, 0xc0, 0x46, +0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x6a, 0xc0, 0x46, +0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x6a, 0xc0, 0x46, +0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x01, 0xb0, 0x70, 0x47, +0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x66, 0x4e, 0x1b, 0x23, +0xdb, 0x01, 0xf7, 0x18, 0x78, 0x8b, 0x04, 0x22, 0x02, 0x40, 0x02, 0x92, +0x07, 0x23, 0x5b, 0x02, 0xf4, 0x18, 0xa0, 0x8b, 0xc0, 0x46, 0x01, 0x90, +0xe0, 0x8b, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x25, 0x03, 0xe0, 0x08, 0x2d, +0x01, 0xd3, 0x0f, 0x2d, 0x08, 0xd9, 0x28, 0x1c, 0xff, 0xf7, 0xfa, 0xfd, +0x69, 0x00, 0x89, 0x19, 0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, +0x01, 0x35, 0x20, 0x2d, 0xef, 0xd3, 0xa0, 0x69, 0x00, 0x28, 0x15, 0xd0, +0x54, 0x4e, 0x20, 0x25, 0x01, 0x3d, 0x52, 0x49, 0xa0, 0x69, 0x30, 0x40, +0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18, 0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, +0x01, 0x8b, 0x28, 0x1c, 0xff, 0xf7, 0x78, 0xfe, 0xa0, 0x69, 0xb0, 0x43, +0xa0, 0x61, 0x76, 0x08, 0x00, 0x2d, 0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, +0xd5, 0xfd, 0x01, 0x1c, 0x46, 0x48, 0xc0, 0x46, 0x79, 0x83, 0x79, 0x8b, +0xca, 0x08, 0x22, 0xd3, 0xc2, 0x68, 0x01, 0x2a, 0x10, 0xd1, 0x40, 0x88, +0x00, 0x28, 0x1c, 0xd1, 0x01, 0x98, 0x42, 0x4a, 0x00, 0x28, 0x05, 0xd0, +0x01, 0x28, 0x16, 0xd1, 0xd0, 0x8a, 0xc0, 0x08, 0x13, 0xd2, 0x0f, 0xe0, +0xd0, 0x8a, 0x00, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x02, 0x79, 0x00, 0x2a, +0x0b, 0xd1, 0x6d, 0x23, 0x5b, 0x01, 0xc0, 0x18, 0x02, 0x88, 0x40, 0x88, +0x10, 0x40, 0x40, 0x09, 0x00, 0x07, 0x02, 0xd1, 0x04, 0x23, 0x99, 0x43, +0x79, 0x83, 0x78, 0x8b, 0x04, 0x21, 0x01, 0x40, +0x02, 0x9a, 0x1f, 0xd0, 0x39, 0x8b, 0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, +0x25, 0xd3, 0xff, 0x23, 0x01, 0x98, 0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, +0x00, 0x25, 0x00, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, +0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, +0x13, 0xd0, 0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x25, 0xfe, 0x3d, 0x83, +0x00, 0x20, 0xc0, 0x43, 0x20, 0x62, 0x0a, 0xe0, 0x38, 0x8b, 0x40, 0x0b, +0x07, 0xd2, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x18, 0xfe, +0x09, 0x20, 0x40, 0x02, 0x38, 0x83, 0x78, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, +0x1b, 0x48, 0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x6a, 0xfc, +0xc2, 0x07, 0xd2, 0x0f, 0x18, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, +0x2b, 0x43, 0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, +0xcb, 0x65, 0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, +0x03, 0xe0, 0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, +0x21, 0x6a, 0x81, 0x42, 0x0c, 0xd0, 0x20, 0x62, 0x0c, 0x48, 0x00, 0x2a, +0x03, 0xd0, 0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, +0x21, 0x33, 0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0xa8, 0x1b, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, +0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22, 0x20, 0x28, 0x0f, 0xd2, +0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18, 0x37, 0x23, 0x9b, 0x01, +0xe3, 0x18, 0x1f, 0x83, 0x82, 0x40, 0x07, 0x23, 0x5b, 0x02, 0xc9, 0x18, +0x10, 0x1c, 0x8a, 0x69, 0x10, 0x43, 0x88, 0x61, 0x90, 0xbc, 0x70, 0x47, +0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69, 0x0b, 0x49, 0x49, 0x8b, +0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0, 0x01, 0x23, 0xdb, 0x02, +0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43, 0x05, 0xe0, 0x01, 0x23, +0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08, 0x52, 0x00, 0xca, 0x65, +0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0x68, 0x1b, 0x00, 0x80, +0x10, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xff, 0xf7, 0xde, 0xff, +0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20, 0x01, 0xab, 0x18, 0x80, +0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab, 0x5a, 0x80, 0xd9, 0x80, +0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91, 0x03, 0x90, 0x68, 0x46, +0x00, 0x21, 0xfc, 0xf7, 0x9d, 0xfd, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, +0x10, 0x2a, 0x00, 0x80, 0x0d, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, +0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, +0x09, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x08, 0x48, 0x80, 0x6c, +0x00, 0x04, 0x00, 0x0c, 0x07, 0x4b, 0x98, 0x42, 0x02, 0xd0, 0x02, 0x33, +0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, +0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, +0x04, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24, 0x21, 0x1c, 0x17, 0x48, +0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x02, 0xd1, +0x00, 0x68, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x21, 0x09, 0x06, 0x09, 0x0e, +0x11, 0x4f, 0x12, 0x4a, 0x02, 0xd0, 0x38, 0x68, 0x00, 0x0c, 0x00, 0xe0, +0x90, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x0f, 0x4b, +0x98, 0x42, 0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x0d, 0x4b, +0x98, 0x42, 0x0c, 0xd1, 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, +0x00, 0xe0, 0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, +0x00, 0x0e, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, +0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, +0x04, 0x99, 0x00, 0x00, 0x05, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, +0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, +0x80, 0x0a, 0x02, 0xd3, 0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, +0x40, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, +0x40, 0x08, 0x01, 0xd3, 0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, +0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, +0xf0, 0xb5, 0x01, 0x27, 0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x7a, 0xff, +0x03, 0x1c, 0x19, 0x4a, 0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, +0x1b, 0xd1, 0xcb, 0x04, 0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, +0x43, 0x60, 0x06, 0x68, 0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, +0x43, 0x60, 0x03, 0x68, 0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, +0x05, 0x23, 0x0f, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, +0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, +0x23, 0x60, 0x04, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, +0x06, 0x60, 0x27, 0x68, 0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, +0x00, 0x00, 0x22, 0x40, 0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, +0x00, 0x00, 0x28, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x38, 0xff, +0x01, 0x28, 0x05, 0xd1, 0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, +0x08, 0x40, 0x22, 0xe0, 0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, +0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, +0x14, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, +0x00, 0x04, 0x00, 0x0c, 0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, +0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, +0x07, 0x07, 0x05, 0x03, 0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, +0x00, 0x20, 0x01, 0x21, 0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, +0x08, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x98, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, +0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, +0xf0, 0xb5, 0x83, 0xb0, 0x07, 0x1c, 0x01, 0x20, 0x02, 0x90, 0x01, 0x25, +0x02, 0x24, 0x10, 0x26, 0x20, 0x21, 0x00, 0x91, 0xff, 0xf7, 0xea, 0xfe, +0x01, 0x28, 0x4d, 0xd1, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x3a, 0xd1, +0x2e, 0x4e, 0x3c, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x1c, 0xfb, +0x3e, 0x21, 0x05, 0x1c, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x16, 0xfb, +0x00, 0x04, 0x05, 0x43, 0x40, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, +0x0f, 0xfb, 0x01, 0x90, 0x42, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, +0x09, 0xfb, 0x00, 0x04, 0x01, 0x99, 0x08, 0x43, 0x06, 0x1c, 0xa8, 0x2f, +0x1b, 0xd1, 0x1f, 0x4a, 0x44, 0x21, 0x02, 0x20, +0xfc, 0xf7, 0xfe, 0xfa, 0x04, 0x1c, 0x1c, 0x4a, 0x46, 0x21, 0x02, 0x20, +0xfc, 0xf7, 0xf8, 0xfa, 0x00, 0x04, 0x04, 0x43, 0x18, 0x4a, 0x48, 0x21, +0x02, 0x20, 0xfc, 0xf7, 0xf1, 0xfa, 0x00, 0x90, 0x15, 0x4a, 0x4a, 0x21, +0x02, 0x20, 0xfc, 0xf7, 0xeb, 0xfa, 0x00, 0x04, 0x00, 0x99, 0x01, 0x43, +0x00, 0x91, 0x28, 0x1c, 0x30, 0x43, 0x20, 0x43, 0x00, 0x99, 0x08, 0x43, +0x00, 0xd1, 0x16, 0xe0, 0x11, 0x20, 0x00, 0x04, 0x05, 0x62, 0x46, 0x62, +0x84, 0x62, 0x00, 0x99, 0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x0a, 0x48, +0xc0, 0x46, 0x01, 0x60, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, +0x01, 0x21, 0x01, 0x60, 0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, +0x02, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x39, 0xb7, 0x21, 0x40, 0x98, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x07, 0x1c, +0xff, 0xf7, 0x7e, 0xfe, 0x01, 0x28, 0x19, 0xd1, 0x01, 0x05, 0x11, 0x48, +0x00, 0x2f, 0x18, 0xd0, 0x0b, 0x0a, 0x02, 0x68, 0x9a, 0x43, 0x0a, 0x60, +0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x0b, 0xd1, +0x00, 0x68, 0x80, 0x0a, 0x08, 0xd3, 0x0a, 0x48, 0x40, 0x6a, 0xff, 0x22, +0x01, 0x32, 0x02, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x4a, 0x62, 0x48, 0x62, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x68, 0x01, 0x23, 0x1b, 0x03, +0x18, 0x43, 0x08, 0x60, 0xf6, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, +0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x70, 0x47, 0x00, 0x00, +0x90, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x21, 0x68, 0x12, 0x48, 0x81, 0x42, +0x0b, 0xd0, 0x00, 0x23, 0x21, 0x1c, 0xe2, 0x1d, 0x6d, 0x32, 0x00, 0xe0, +0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0x74, 0x20, 0xa0, 0x80, +0x67, 0x72, 0x38, 0x01, 0x00, 0xf0, 0x18, 0xf8, 0x27, 0x72, 0x0a, 0x48, +0xc0, 0x46, 0xe0, 0x60, 0x08, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19, +0x01, 0x7d, 0x01, 0x31, 0x01, 0x75, 0xe0, 0x88, 0x01, 0x30, 0xe0, 0x80, +0x01, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x80, +0xfe, 0xca, 0x01, 0x20, 0x17, 0x40, 0x00, 0x02, 0x80, 0xb4, 0x08, 0x4a, +0xd1, 0x1d, 0x49, 0x31, 0x0b, 0x78, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23, +0x0b, 0x70, 0x07, 0x1c, 0x08, 0x78, 0x43, 0x1c, 0x0b, 0x70, 0x80, 0x18, +0x50, 0x30, 0x47, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80, +0x07, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x01, 0x20, +0x00, 0x2a, 0x06, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x09, 0x68, +0x89, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40, +0x90, 0xb5, 0x07, 0x1c, 0x09, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7, +0x4d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42, +0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfc, 0xf7, +0x81, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xbc, 0x67, 0x21, 0x40, +0xf8, 0xb5, 0x07, 0x1c, 0x79, 0x7a, 0x76, 0x48, 0x00, 0x23, 0x76, 0x4c, +0x01, 0x29, 0x5d, 0xd1, 0xa2, 0x88, 0xc0, 0x46, 0x00, 0x92, 0xa1, 0x89, +0x8a, 0x42, 0x74, 0xda, 0xfa, 0x7a, 0x00, 0x2a, 0x15, 0xd0, 0x7a, 0x6c, +0x00, 0x2a, 0x12, 0xd0, 0x8a, 0x42, 0x10, 0xd8, 0x00, 0x9a, 0x51, 0x1c, +0xa1, 0x80, 0xa1, 0x88, 0xc0, 0x46, 0x41, 0x81, 0x78, 0x6c, 0x6b, 0x4e, +0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, +0x79, 0x6c, 0x59, 0x43, 0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, +0x01, 0x32, 0x12, 0x04, 0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, +0x23, 0x80, 0x00, 0x22, 0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, +0x5e, 0x4b, 0x1d, 0x88, 0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, +0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, +0x15, 0xd1, 0x58, 0x49, 0x00, 0x9a, 0x01, 0x32, 0x8a, 0x80, 0x8a, 0x88, +0xc0, 0x46, 0x42, 0x81, 0x08, 0x88, 0x01, 0x30, 0x54, 0x4e, 0xc0, 0x46, +0xf0, 0x80, 0x58, 0x20, 0x68, 0x43, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, +0x65, 0xfa, 0xf0, 0x88, 0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, +0x01, 0x35, 0x2d, 0x04, 0x2d, 0x0c, 0x1d, 0x80, 0x8d, 0x42, 0x01, 0xdb, +0x00, 0x25, 0x1d, 0x80, 0x01, 0x32, 0x12, 0x04, 0x12, 0x14, 0x91, 0x42, +0xce, 0xdc, 0x81, 0xe0, 0xe1, 0x88, 0xe2, 0x89, 0x91, 0x42, 0x18, 0xda, +0xf9, 0x7a, 0x00, 0x29, 0x2f, 0xd0, 0x79, 0x6c, 0x49, 0x04, 0x49, 0x0c, +0x79, 0x64, 0x2a, 0xd0, 0xe2, 0x89, 0x91, 0x42, 0x27, 0xd8, 0xe1, 0x88, +0x01, 0x31, 0xe1, 0x80, 0xe1, 0x88, 0xc0, 0x46, 0x81, 0x81, 0x01, 0x23, +0xdb, 0x03, 0x78, 0x6c, 0x18, 0x43, 0x3a, 0x4e, 0xc0, 0x46, 0xf0, 0x80, +0x00, 0xe0, 0x63, 0xe0, 0xe0, 0x6a, 0x79, 0x6c, 0x4b, 0x00, 0x59, 0x18, +0x49, 0x01, 0x40, 0x18, 0xc1, 0x1f, 0x59, 0x39, 0x38, 0x1c, 0x00, 0xf0, +0x4b, 0xfa, 0xe0, 0x6a, 0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, +0x80, 0x18, 0x01, 0x39, 0x09, 0x04, 0x09, 0x0c, 0x60, 0x38, 0x00, 0xf0, +0xc5, 0xfa, 0xb6, 0xe7, 0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04, +0x09, 0x0c, 0x61, 0x80, 0xe2, 0x89, 0x91, 0x42, 0x00, 0xdb, 0x63, 0x80, +0x00, 0x21, 0x00, 0x2a, 0x3e, 0xdd, 0x24, 0x4c, 0xe4, 0x6a, 0x23, 0x4b, +0x5d, 0x88, 0x6b, 0x00, 0x5b, 0x19, 0x5b, 0x01, 0xe3, 0x18, 0xde, 0x1d, +0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, +0x20, 0xd1, 0x1c, 0x4e, 0xf1, 0x88, 0x01, 0x31, 0xf1, 0x80, 0xf1, 0x88, +0xc0, 0x46, 0x81, 0x81, 0x70, 0x88, 0x01, 0x23, 0xdb, 0x03, 0x01, 0x30, +0x18, 0x43, 0x17, 0x49, 0xc0, 0x46, 0xc8, 0x80, 0x68, 0x00, 0x40, 0x19, +0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xfa, 0x71, 0x88, +0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0xf0, 0x6a, 0x80, 0x18, 0x00, 0xf0, +0x89, 0xfa, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35, +0x2d, 0x04, 0x2d, 0x0c, 0x5d, 0x80, 0x95, 0x42, 0x01, 0xdb, 0x00, 0x25, +0x5d, 0x80, 0x01, 0x31, 0x09, 0x04, 0x09, 0x14, 0x8a, 0x42, 0xc2, 0xdc, +0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x00, 0x20, 0xc0, 0x43, 0xf8, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xb8, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, +0xbc, 0x67, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03, +0x33, 0x40, 0x01, 0x24, 0x30, 0x4f, 0x00, 0x20, 0x30, 0x4a, 0x31, 0x4d, +0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x2f, 0xd0, 0xe3, 0x03, 0xf3, 0x1a, +0x51, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x4e, 0xd3, 0xee, 0x88, 0x00, 0x2e, +0x4b, 0xd0, 0xee, 0x6a, 0x5d, 0x1e, 0x6b, 0x00, 0x5d, 0x19, 0x6d, 0x01, +0x73, 0x19, 0x9e, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, +0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x33, 0x9b, 0x8b, 0x9b, 0x00, +0x21, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0xf0, 0x50, +0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x1e, 0x4e, 0xf2, 0x6a, 0x52, 0x19, +0x90, 0x60, 0xf0, 0x88, 0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, +0x88, 0x81, 0x19, 0x49, 0x00, 0x28, 0x23, 0xd1, 0x4f, 0x80, 0x21, 0xe0, +0x00, 0x2e, 0x22, 0xd9, 0xab, 0x89, 0xb3, 0x42, 0x1f, 0xd3, 0xab, 0x88, +0x00, 0x2b, 0x1c, 0xd0, 0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x58, 0x23, +0x01, 0x3e, 0x73, 0x43, 0xaa, 0x6a, 0xd2, 0x18, 0x93, 0x68, 0x1b, 0x06, +0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0, 0xcb, 0x89, 0x01, 0x33, 0xcb, 0x81, +0x90, 0x60, 0xa8, 0x88, 0x01, 0x38, 0xa8, 0x80, 0xa8, 0x88, 0xc0, 0x46, +0x48, 0x81, 0x00, 0x28, 0x00, 0xd1, 0x2f, 0x80, 0x20, 0x1c, 0xf0, 0xbc, +0x70, 0x47, 0xca, 0x89, 0x01, 0x32, 0xca, 0x81, 0xf9, 0xe7, 0x00, 0x00, +0xff, 0xff, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, +0x00, 0xb5, 0x00, 0x21, 0x41, 0x60, 0x10, 0x49, 0x4a, 0x68, 0x00, 0x2a, +0x10, 0xd1, 0xca, 0x68, 0x00, 0x2a, 0x04, 0xd0, 0xca, 0x1d, 0x19, 0x32, +0x12, 0x79, 0x00, 0x2a, 0x08, 0xd0, 0x4a, 0x69, 0x00, 0x2a, 0x0b, 0xd1, +0x88, 0x61, 0x48, 0x61, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, +0x4a, 0x69, 0x00, 0x2a, 0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, +0x8a, 0x69, 0xc0, 0x46, 0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, +0xec, 0x05, 0x00, 0x80, 0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, +0x4c, 0xd0, 0x08, 0x22, 0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, +0xd9, 0x1d, 0xb9, 0x31, 0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, +0xc0, 0x46, 0x0c, 0x61, 0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, +0xc0, 0x46, 0x8c, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, +0xc0, 0x46, 0x0c, 0x63, 0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, +0xc0, 0x46, 0x0c, 0x61, 0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, +0xc0, 0x46, 0x8c, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, +0xc0, 0x46, 0x0c, 0x63, 0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, +0xcc, 0x82, 0x4f, 0x83, 0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, +0x8c, 0x00, 0x05, 0x19, 0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, +0x01, 0x34, 0x65, 0x62, 0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, +0x07, 0xd2, 0x8a, 0x00, 0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, +0x01, 0x31, 0x10, 0x29, 0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, +0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, +0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, +0x20, 0x01, 0x40, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, +0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, +0x36, 0x36, 0x36, 0x36, 0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, +0x15, 0x4d, 0xe9, 0x1d, 0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, +0x00, 0x20, 0xfc, 0xf7, 0x1a, 0xf8, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, +0x23, 0x1c, 0x0d, 0x1c, 0x11, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x11, 0xf8, +0x29, 0x1c, 0x23, 0x1c, 0x0e, 0x4a, 0x00, 0x20, 0xfc, 0xf7, 0x0b, 0xf8, +0x39, 0x1c, 0x23, 0x1c, 0x0c, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x05, 0xf8, +0x00, 0x21, 0x0b, 0x48, 0xc2, 0x1d, 0x19, 0x32, +0x51, 0x71, 0x01, 0x21, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x08, 0x1c, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0xad, 0x20, 0x40, +0x75, 0x08, 0xff, 0xff, 0x28, 0x00, 0x03, 0x00, 0x40, 0x00, 0x02, 0x00, +0x14, 0x00, 0x07, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x37, 0x4a, +0x50, 0x69, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, +0x01, 0x06, 0x09, 0x0e, 0x33, 0x4b, 0x01, 0x29, 0x49, 0xd1, 0x1f, 0x68, +0x19, 0x1c, 0x32, 0x4b, 0x9f, 0x42, 0x04, 0xd1, 0xff, 0xf7, 0x3e, 0xff, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0x9f, 0x00, 0xcc, 0x59, +0x55, 0x69, 0xef, 0x19, 0x3c, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, +0x00, 0x0a, 0x00, 0x02, 0x02, 0x23, 0x18, 0x43, 0x53, 0x69, 0xc0, 0x46, +0x98, 0x60, 0x50, 0x69, 0x08, 0x23, 0xc2, 0x68, 0x13, 0x40, 0x25, 0x4f, +0xfa, 0x1d, 0xb9, 0x32, 0x00, 0x2b, 0x02, 0xd0, 0x04, 0x23, 0x23, 0x4c, +0x01, 0xe0, 0x05, 0x23, 0x22, 0x4c, 0xc0, 0x46, 0x14, 0x61, 0x40, 0x24, +0xd4, 0x82, 0x00, 0x24, 0x54, 0x83, 0x20, 0x4c, 0x00, 0x22, 0x00, 0x2b, +0x0c, 0xd9, 0x95, 0x00, 0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, +0xff, 0x35, 0x01, 0x35, 0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, +0x10, 0x2a, 0x07, 0xd2, 0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, +0x5c, 0x62, 0x01, 0x32, 0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, +0xbc, 0xe7, 0x00, 0x21, 0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, +0x7c, 0x62, 0x01, 0x31, 0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, +0x03, 0x23, 0x18, 0x43, 0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, +0x40, 0x68, 0xc0, 0x46, 0x50, 0x61, 0x09, 0x48, 0xfb, 0xf7, 0x7a, 0xff, +0xa4, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, +0x67, 0x45, 0x23, 0x01, 0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, +0x20, 0x01, 0x40, 0x00, 0x5c, 0x5c, 0x5c, 0x5c, 0x85, 0x30, 0xff, 0xff, +0x80, 0xb5, 0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0xb9, 0x6b, +0x0b, 0x48, 0xc2, 0x68, 0x12, 0x04, 0x51, 0x40, 0x82, 0x69, 0x51, 0x40, +0x39, 0x65, 0xf9, 0x6b, 0x82, 0x69, 0x12, 0x04, 0xd2, 0x43, 0x51, 0x40, +0xc0, 0x68, 0xc0, 0x43, 0x48, 0x40, 0x78, 0x65, 0x04, 0x48, 0x01, 0x89, +0x01, 0x31, 0x01, 0x81, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x08, 0x83, 0x20, 0x40, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, +0x0f, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68, +0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, +0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, +0x08, 0x43, 0x38, 0x65, 0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69, +0xc0, 0x46, 0xb8, 0x65, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, +0x90, 0xb5, 0x00, 0x22, 0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18, +0x5f, 0x62, 0x01, 0x32, 0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08, +0x03, 0xd3, 0x00, 0x23, 0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b, +0xc0, 0x46, 0x8f, 0x63, 0xc7, 0x6a, 0xc0, 0x46, 0xcf, 0x63, 0x87, 0x6b, +0xc0, 0x46, 0x0f, 0x64, 0x47, 0x6b, 0xc0, 0x46, 0x4f, 0x64, 0x07, 0x6c, +0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, +0xca, 0x64, 0xc2, 0x88, 0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, +0x03, 0x7a, 0x1b, 0x04, 0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, +0x43, 0x7a, 0xdb, 0x07, 0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, +0x5a, 0x08, 0x05, 0xd3, 0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, +0x15, 0x22, 0x00, 0xe0, 0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, +0xc0, 0x08, 0x02, 0xd3, 0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, +0x10, 0x43, 0x3a, 0x0a, 0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, +0x8a, 0x60, 0x08, 0x1c, 0xff, 0xf7, 0x14, 0xfe, 0x05, 0xe0, 0x38, 0x0a, +0x00, 0x02, 0x03, 0x23, 0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, +0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x78, 0x2a, 0x00, 0x80, 0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, +0xe7, 0x69, 0xbd, 0x40, 0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, +0x2e, 0x1c, 0x45, 0x6d, 0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, +0xfd, 0x40, 0x2f, 0x1c, 0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, +0x08, 0xd0, 0x23, 0x69, 0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, +0xbe, 0x00, 0xae, 0x59, 0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, +0x11, 0x43, 0x05, 0x4b, 0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, +0x87, 0x83, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, +0x00, 0x00, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x00, 0xf0, +0xb1, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0x0e, 0xfa, 0x38, 0x0c, 0x00, 0xf0, +0x0b, 0xfa, 0x38, 0x0a, 0x00, 0xf0, 0x08, 0xfa, 0x38, 0x1c, 0x00, 0xf0, +0x05, 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, +0x00, 0xf0, 0x9e, 0xfa, 0x54, 0x20, 0x00, 0xf0, 0xfb, 0xf9, 0x38, 0x0c, +0x00, 0xf0, 0xf8, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xf5, 0xf9, 0x38, 0x1c, +0x00, 0xf0, 0xf2, 0xf9, 0x00, 0x20, 0x00, 0xf0, 0xef, 0xf9, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x89, 0xfa, 0x57, 0x20, +0x00, 0xf0, 0xe6, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, +0x41, 0x02, 0x53, 0x20, 0xff, 0xf7, 0xc8, 0xff, 0x00, 0xf0, 0x64, 0xfa, +0x00, 0xf0, 0xf5, 0xf8, 0x00, 0x24, 0x00, 0x26, 0x00, 0x25, 0x00, 0x27, +0x30, 0x1c, 0x01, 0x36, 0xff, 0xf7, 0xd0, 0xff, 0x00, 0xf0, 0x46, 0xf9, +0x00, 0x90, 0x00, 0xf0, 0x55, 0xfa, 0xf8, 0x00, 0x00, 0x99, 0x81, 0x40, +0x0d, 0x43, 0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xee, 0xd3, 0x02, 0x99, +0x20, 0xc1, 0x02, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42, 0xe5, 0xd3, +0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, +0x0f, 0x1c, 0x00, 0x26, 0x20, 0xcf, 0xb1, 0x00, 0x84, 0x20, 0xff, 0xf7, +0x9b, 0xff, 0x28, 0x1c, 0x00, 0xf0, 0xae, 0xf9, 0x28, 0x0a, 0x00, 0xf0, +0xab, 0xf9, 0x28, 0x0c, 0x00, 0xf0, 0xa8, 0xf9, 0x28, 0x0e, 0x00, 0xf0, +0xa5, 0xf9, 0x00, 0xf0, 0x2b, 0xfa, 0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, +0x61, 0x02, 0x83, 0x20, 0xff, 0xf7, 0x86, 0xff, 0x00, 0xf0, 0x22, 0xfa, +0x00, 0xf0, 0xb3, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, +0x41, 0x02, 0x60, 0x20, 0xff, 0xf7, 0x7a, 0xff, 0x00, 0xf0, 0x16, 0xfa, +0x00, 0xf0, 0xa7, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x90, 0xb5, 0x0f, 0x1c, 0x41, 0x02, 0x53, 0x20, +0xff, 0xf7, 0x6c, 0xff, 0x00, 0xf0, 0x08, 0xfa, 0x00, 0xf0, 0x99, 0xf8, +0xf8, 0x1d, 0x05, 0x30, 0x44, 0x1c, 0xff, 0xf7, 0x77, 0xff, 0x00, 0xf0, +0xed, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0xfc, 0xf9, 0x20, 0x1c, 0xff, 0xf7, +0x6f, 0xff, 0x00, 0xf0, 0xe5, 0xf8, 0x04, 0x1c, 0x00, 0xf0, 0xf4, 0xf9, +0x20, 0x02, 0x38, 0x43, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, +0xc2, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x17, 0x1c, 0x61, 0x02, 0x53, 0x20, +0xff, 0xf7, 0x48, 0xff, 0x00, 0xf0, 0xe4, 0xf9, 0x00, 0xf0, 0x75, 0xf8, +0x68, 0x46, 0x00, 0xf0, 0x5c, 0xf8, 0x6a, 0x46, 0xe8, 0x1d, 0x05, 0x30, +0x17, 0x54, 0x39, 0x0a, 0x68, 0x44, 0x41, 0x70, 0x68, 0x46, 0x00, 0x99, +0x0c, 0x30, 0x00, 0xf0, 0x73, 0xf8, 0x02, 0xab, 0x18, 0x70, 0x00, 0x20, +0x58, 0x70, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x6b, 0xf8, 0x02, 0xab, +0x58, 0x70, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x83, 0xff, 0x42, 0xb0, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc2, 0xb0, 0x04, 0x1c, +0x1f, 0x1c, 0x6b, 0x46, 0x00, 0x20, 0xc5, 0x43, 0x20, 0xc3, 0x01, 0x30, +0x42, 0x28, 0xfb, 0xd3, 0x68, 0x46, 0x0c, 0x30, 0x03, 0x1c, 0x00, 0x25, +0x00, 0x2a, 0x0a, 0xd9, 0x0e, 0x88, 0xc0, 0x46, 0x06, 0x70, 0x0e, 0x88, +0x36, 0x12, 0x46, 0x70, 0x02, 0x30, 0x02, 0x31, 0x02, 0x35, 0x95, 0x42, +0xf4, 0xd3, 0x00, 0x92, 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x40, 0xf8, +0x00, 0x26, 0x01, 0x96, 0x02, 0xab, 0x18, 0x70, 0x5e, 0x70, 0x9e, 0x70, +0xde, 0x70, 0x05, 0x1c, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x34, 0xf8, +0x02, 0xab, 0x58, 0x70, 0x38, 0x06, 0x00, 0x0e, 0x85, 0x42, 0x05, 0xd1, +0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x48, 0xff, 0x30, 0x1c, 0x00, 0xe0, +0x01, 0x20, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, +0x07, 0x1c, 0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0xff, 0xf7, +0xf1, 0xfe, 0x00, 0xf0, 0x67, 0xf8, 0x05, 0x1c, 0x00, 0xf0, 0x76, 0xf9, +0x3d, 0x70, 0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, 0xf7, 0xf6, 0xfe, +0x00, 0xf0, 0x56, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0x65, 0xf9, 0x38, 0x0a, +0xf6, 0xd3, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb4, 0x00, 0x22, +0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78, 0x7a, 0x40, 0x01, 0x30, +0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43, 0x00, 0x06, 0x00, 0x0e, +0x80, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02, +0x53, 0x20, 0xff, 0xf7, 0xab, 0xfe, 0x00, 0xf0, 0x47, 0xf9, 0xff, 0xf7, +0xd8, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xbf, 0xff, 0x02, 0xad, 0x6d, 0x78, +0x00, 0x24, 0x02, 0xab, 0x5c, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, +0xd9, 0xff, 0xa8, 0x42, 0x02, 0xd1, 0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, +0x20, 0x1c, 0x00, 0xe0, 0x01, 0x20, 0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x80, 0xb5, 0xc2, 0xb0, 0x69, 0x46, 0x02, 0x20, 0xff, 0xf7, +0xbb, 0xfe, 0x68, 0x46, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x07, 0x4a, +0x0f, 0x88, 0x43, 0x00, 0xd7, 0x52, 0x02, 0x31, 0x01, 0x30, 0x00, 0x04, +0x00, 0x0c, 0x25, 0x28, 0xf6, 0xdb, 0x42, 0xb0, 0x80, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, 0xfc, 0x46, 0x60, 0x47, +0x00, 0x00, 0xa0, 0xe3, 0xb4, 0x22, 0x9f, 0xe5, +0xb4, 0x32, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x03, 0x80, 0xe1, +0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x93, 0xe5, 0x01, 0x03, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, +0x81, 0x02, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x01, 0x02, 0x80, 0xe1, +0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x93, 0xe5, 0x81, 0x01, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, +0x01, 0x01, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x00, 0x80, 0xe1, +0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x93, 0xe5, 0x01, 0x00, 0x80, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, +0xfc, 0x46, 0x60, 0x47, 0xa4, 0x21, 0x9f, 0xe5, 0xa8, 0x31, 0x9f, 0xe5, +0xa0, 0x13, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x13, 0xa0, 0xe1, +0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0xa0, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, +0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x20, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0xa0, 0x11, 0xa0, 0xe1, +0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, +0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0xa0, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe1, +0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0xfc, 0x46, 0x60, 0x47, 0xa0, 0x30, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0xfc, 0x46, 0x60, 0x47, 0x70, 0x30, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0xfc, 0x46, 0x60, 0x47, 0x34, 0x20, 0x9f, 0xe5, 0x3c, 0x30, 0x9f, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, +0x1e, 0xff, 0x2f, 0xe1, 0xf8, 0x00, 0x18, 0x40, 0x04, 0x01, 0x18, 0x40, +0x00, 0x01, 0x18, 0x40, 0xfc, 0x00, 0x18, 0x40, 0x02, 0x1c, 0x00, 0x20, +0x00, 0x29, 0x07, 0xdd, 0x13, 0x78, 0xc0, 0x18, 0x00, 0x06, 0x00, 0x0e, +0x01, 0x32, 0x01, 0x39, 0x00, 0x29, 0xf7, 0xdc, 0x70, 0x47, 0x09, 0x4b, +0xc9, 0x18, 0x04, 0x29, 0x08, 0xd8, 0x8c, 0x22, 0x4a, 0x43, 0x07, 0x4b, +0xd2, 0x18, 0x13, 0x7a, 0x09, 0x06, 0x09, 0x0e, 0x8b, 0x42, 0x01, 0xd0, +0x14, 0x20, 0x70, 0x47, 0x02, 0x60, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, +0xf3, 0x0f, 0x01, 0x35, 0xb0, 0x6e, 0x21, 0x40, 0x01, 0x1c, 0x00, 0x22, +0x06, 0x48, 0x03, 0x7a, 0xff, 0x2b, 0x04, 0xd0, 0x8c, 0x30, 0x01, 0x32, +0x04, 0x2a, 0xf8, 0xd3, 0x01, 0xe0, 0x04, 0x2a, 0x00, 0xd3, 0x00, 0x20, +0x0a, 0x60, 0x70, 0x47, 0xb0, 0x6e, 0x21, 0x40, 0xf0, 0xb5, 0x07, 0x1c, +0x00, 0x24, 0x00, 0x2f, 0x21, 0xd0, 0x00, 0x26, 0xf8, 0x79, 0x00, 0x28, +0x1b, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, 0x05, 0x35, 0x00, 0x7b, +0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x92, 0xfb, 0x01, 0x1c, 0x8b, 0x68, +0x00, 0x2b, 0x08, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xca, 0x68, +0xa9, 0x68, 0xfb, 0xf7, 0x4a, 0xfb, 0x00, 0x20, 0x68, 0x60, 0x70, 0x1c, +0x06, 0x06, 0x36, 0x0e, 0xf8, 0x79, 0xb0, 0x42, 0xe3, 0xdc, 0xff, 0x20, +0x38, 0x72, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, +0x81, 0xb0, 0x0f, 0x1c, 0x68, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x00, 0x28, +0x01, 0xd1, 0x0d, 0x20, 0x37, 0xe0, 0xb9, 0x88, 0xc0, 0x46, 0x01, 0x80, +0xf9, 0x88, 0xc0, 0x46, 0x41, 0x80, 0xb9, 0x7a, 0xc0, 0x46, 0x41, 0x71, +0xf9, 0x7a, 0xc0, 0x46, 0x81, 0x71, 0x8c, 0x21, 0x01, 0x71, 0x3d, 0x7e, +0x00, 0x21, 0x00, 0x23, 0x00, 0x2d, 0x1f, 0xdd, 0x1a, 0x01, 0xd2, 0x19, +0x1c, 0x32, 0x16, 0x78, 0x05, 0x2e, 0x0d, 0xdc, 0x0c, 0x01, 0x24, 0x18, +0x26, 0x73, 0x96, 0x68, 0xc0, 0x46, 0x66, 0x61, 0xd6, 0x68, 0xc0, 0x46, +0x26, 0x61, 0x00, 0x24, 0x01, 0x31, 0x09, 0x06, 0x09, 0x0e, 0xd4, 0x60, +0x5a, 0x1c, 0x13, 0x06, 0x1b, 0x0e, 0xab, 0x42, 0xe6, 0xdb, 0x00, 0x29, +0x04, 0xd0, 0xc1, 0x71, 0x00, 0x99, 0xc0, 0x46, +0x01, 0x72, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x99, 0xc0, 0x46, 0x08, 0x60, +0x00, 0x20, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, +0x07, 0x1c, 0x38, 0x7e, 0x00, 0x28, 0x28, 0xd0, 0x01, 0x38, 0x05, 0x06, +0x2d, 0x0e, 0x00, 0x26, 0xff, 0x2d, 0x21, 0xd0, 0x28, 0x01, 0xc0, 0x19, +0xc4, 0x1d, 0x15, 0x34, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, +0x1f, 0xfb, 0x01, 0x1c, 0x11, 0xd0, 0x8a, 0x68, 0x00, 0x2a, 0x0c, 0xd0, +0xe0, 0x68, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x23, 0xcb, 0x56, 0x05, 0x2b, +0x05, 0xdc, 0x13, 0x1c, 0xca, 0x68, 0xa1, 0x68, 0xfb, 0xf7, 0xd1, 0xfa, +0xe6, 0x60, 0xff, 0x20, 0x20, 0x70, 0x68, 0x1e, 0x05, 0x06, 0x2d, 0x0e, +0xff, 0x2d, 0xdd, 0xd1, 0x3e, 0x76, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x13, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xf8, 0x1d, +0xd5, 0x30, 0x39, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x00, 0x90, 0x00, 0x98, +0x00, 0x28, 0x3b, 0xd1, 0x38, 0x7e, 0xc0, 0x46, 0x01, 0x90, 0x00, 0x26, +0x01, 0x98, 0x00, 0x28, 0x2d, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, +0x15, 0x35, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0xe4, 0xfa, +0x04, 0x1c, 0x20, 0x69, 0x00, 0x28, 0x17, 0xd0, 0x28, 0x78, 0x05, 0x28, +0x0d, 0xdd, 0xe9, 0x68, 0xaa, 0x68, 0x60, 0x68, 0x40, 0x08, 0x40, 0x00, +0x01, 0xf0, 0x0e, 0xf8, 0x09, 0x22, 0xe8, 0x68, 0xa9, 0x68, 0xfb, 0xf7, +0x87, 0xf9, 0x00, 0x20, 0xe8, 0x60, 0x21, 0x69, 0x28, 0x1c, 0xfb, 0xf7, +0x8c, 0xfa, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, +0x0c, 0xd1, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0x01, 0x98, 0x86, 0x42, +0xd1, 0xdb, 0x00, 0x20, 0x38, 0x76, 0x00, 0x98, 0x02, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x82, 0xff, 0xf6, 0xe7, +0xc1, 0x1d, 0x79, 0x31, 0x4a, 0x6b, 0xc0, 0x46, 0xca, 0x63, 0xc1, 0x1d, +0xb9, 0x31, 0x0a, 0x60, 0x00, 0x22, 0x8a, 0x60, 0x04, 0x4a, 0xc0, 0x46, +0x4a, 0x61, 0x8a, 0x61, 0x01, 0x21, 0xd0, 0x30, 0x41, 0x70, 0x08, 0x1c, +0x70, 0x47, 0x00, 0x00, 0xb9, 0xbd, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, +0x00, 0x20, 0x00, 0x90, 0xfe, 0x1d, 0xc9, 0x36, 0x30, 0x78, 0x00, 0x01, +0xc0, 0x19, 0xc4, 0x1d, 0x15, 0x34, 0x80, 0x6a, 0x45, 0x08, 0x6d, 0x00, +0x04, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xb2, 0xfe, 0x31, 0x78, 0x40, 0x18, +0x01, 0x06, 0x09, 0x0e, 0x00, 0x20, 0xa2, 0x68, 0x00, 0x2a, 0x0a, 0xd9, +0x2a, 0x78, 0x4a, 0x40, 0x2a, 0x70, 0x01, 0x30, 0x09, 0x18, 0x09, 0x06, +0x09, 0x0e, 0xa2, 0x68, 0x01, 0x35, 0x82, 0x42, 0xf4, 0xd8, 0xe0, 0x68, +0xa1, 0x68, 0x40, 0x08, 0x40, 0x00, 0xff, 0xf7, 0x99, 0xfe, 0x61, 0x78, +0x81, 0x42, 0x0a, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x0f, 0xf8, 0xf8, 0x1d, +0x79, 0x30, 0x80, 0x6b, 0xf9, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0c, 0x20, +0x00, 0x90, 0x30, 0x78, 0x01, 0x30, 0x30, 0x70, 0x00, 0x98, 0xf8, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 0xc9, 0x32, 0x11, 0x78, 0x09, 0x01, +0x09, 0x18, 0x09, 0x6a, 0xc3, 0x1d, 0x79, 0x33, 0xd9, 0x63, 0x13, 0x78, +0x1b, 0x01, 0x1b, 0x18, 0x5b, 0x6a, 0xcb, 0x18, 0xc1, 0x1d, 0xb9, 0x31, +0x0b, 0x60, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 0x9b, 0x6a, 0xc0, 0x46, +0x8b, 0x60, 0x07, 0x4b, 0xc0, 0x46, 0x4b, 0x61, 0x12, 0x78, 0x00, 0x7e, +0x01, 0x32, 0x82, 0x42, 0x01, 0xdb, 0x04, 0x48, +0x00, 0xe0, 0x04, 0x48, 0xc0, 0x46, 0x88, 0x61, 0x00, 0x20, 0x70, 0x47, +0x81, 0xbe, 0x21, 0x40, 0x55, 0xbe, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, +0xf8, 0xb5, 0x04, 0x1c, 0x00, 0x20, 0x00, 0x90, 0x25, 0x7e, 0x29, 0x01, +0xe0, 0x1d, 0x15, 0x30, 0xff, 0xf7, 0x4e, 0xfe, 0xa1, 0x7e, 0x81, 0x42, +0x0a, 0xd0, 0x20, 0x1c, 0x00, 0xf0, 0x61, 0xf8, 0xe0, 0x1d, 0x79, 0x30, +0x80, 0x6b, 0xe1, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0b, 0x20, 0x55, 0xe0, +0x00, 0x27, 0x00, 0x2d, 0x0f, 0xdd, 0x38, 0x01, 0x00, 0x19, 0x00, 0x7f, +0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x10, 0xfa, 0x00, 0x28, 0x01, 0xd1, +0x09, 0x20, 0x47, 0xe0, 0x78, 0x1c, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, +0xef, 0xdb, 0x00, 0x26, 0x00, 0x2d, 0x38, 0xdd, 0x30, 0x01, 0x00, 0x19, +0xc7, 0x1d, 0x15, 0x37, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, +0xfb, 0xf9, 0x00, 0x23, 0xc1, 0x56, 0x05, 0x29, 0x0c, 0xdc, 0x42, 0x68, +0x00, 0x2a, 0x04, 0xd0, 0xc1, 0x68, 0xb8, 0x68, 0xfb, 0xf7, 0xb2, 0xf9, +0xf8, 0x60, 0xf8, 0x68, 0x00, 0x28, 0x1b, 0xd1, 0x0e, 0x20, 0x17, 0xe0, +0xc0, 0x68, 0x00, 0x28, 0x07, 0xd0, 0xfb, 0xf7, 0xa5, 0xf9, 0x00, 0x28, +0x05, 0xda, 0x40, 0x42, 0xb9, 0x68, 0x81, 0x42, 0x04, 0xd0, 0x05, 0x20, +0x0a, 0xe0, 0xb9, 0x68, 0x81, 0x42, 0xfa, 0xd8, 0x09, 0x21, 0xb8, 0x68, +0xfb, 0xf7, 0x7a, 0xf8, 0xf8, 0x60, 0x00, 0x28, 0x02, 0xd1, 0x06, 0x20, +0x00, 0x90, 0x07, 0xe0, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0xae, 0x42, +0xc6, 0xdb, 0x00, 0x98, 0x00, 0x28, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, +0x92, 0xfe, 0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, +0x79, 0x32, 0x41, 0x69, 0xc0, 0x46, 0xd1, 0x63, 0x02, 0x7e, 0x12, 0x01, +0x8a, 0x18, 0xc1, 0x1d, 0xb9, 0x31, 0x0a, 0x60, 0xc2, 0x1d, 0x15, 0x32, +0x8a, 0x60, 0x05, 0x4a, 0xc0, 0x46, 0x4a, 0x61, 0x04, 0x4a, 0xc0, 0x46, +0x8a, 0x61, 0x00, 0x21, 0xd0, 0x30, 0x01, 0x70, 0x08, 0x1c, 0x70, 0x47, +0x59, 0xbf, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, +0x38, 0x68, 0x1d, 0x4b, 0x98, 0x42, 0x03, 0xd0, 0x03, 0x20, 0x90, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x1c, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xbc, 0xfd, +0xfc, 0x1d, 0x79, 0x34, 0x00, 0x28, 0x09, 0xd0, 0x38, 0x1c, 0x00, 0xf0, +0x2d, 0xf8, 0xf9, 0x1d, 0xb9, 0x31, 0xa0, 0x6b, 0xc0, 0x46, 0xc8, 0x60, +0x0a, 0x20, 0xea, 0xe7, 0x38, 0x7a, 0x1c, 0x28, 0x04, 0xd0, 0x78, 0x7a, +0x10, 0x28, 0x01, 0xd0, 0x04, 0x20, 0xe2, 0xe7, 0xb8, 0x7a, 0x01, 0x28, +0x01, 0xd0, 0x07, 0x20, 0xdd, 0xe7, 0x60, 0x6b, 0xf9, 0x68, 0x88, 0x42, +0x01, 0xd0, 0x05, 0x20, 0xd7, 0xe7, 0x38, 0x69, 0x00, 0x28, 0x04, 0xd0, +0x06, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x08, 0x20, 0xcf, 0xe7, 0x38, 0x7e, +0x08, 0x28, 0x01, 0xdd, 0x12, 0x20, 0xca, 0xe7, 0x00, 0x20, 0xc8, 0xe7, +0x73, 0x6e, 0x69, 0x70, 0x17, 0x40, 0x00, 0x02, 0xb8, 0xb5, 0x07, 0x1c, +0x38, 0x1c, 0xff, 0xf7, 0x2a, 0xfe, 0x00, 0x25, 0xf8, 0x1d, 0xc9, 0x30, +0x45, 0x70, 0xfc, 0x1d, 0xb9, 0x34, 0xe5, 0x61, 0x68, 0x46, 0xff, 0xf7, +0x9d, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 0x0d, 0xe0, 0xf8, 0x1d, +0x79, 0x30, 0x85, 0x63, 0xc5, 0x63, 0x1b, 0x20, 0x20, 0x60, 0xa7, 0x60, +0x04, 0x48, 0xc0, 0x46, 0x60, 0x61, 0x04, 0x48, 0xc0, 0x46, 0xa0, 0x61, +0x28, 0x1c, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x75, 0xc0, 0x21, 0x40, 0x3b, 0xc0, 0x21, 0x40, 0xf0, 0xb5, 0x82, 0xb0, +0x07, 0x1c, 0x00, 0x20, 0xfd, 0x1d, 0x79, 0x35, 0xfc, 0x1d, 0xb9, 0x34, +0xe9, 0x6a, 0xc0, 0x46, 0x61, 0x60, 0x62, 0x68, 0xe9, 0x6b, 0x8a, 0x42, +0x03, 0xd2, 0x61, 0x60, 0x2a, 0x6b, 0x91, 0x42, 0x34, 0xd2, 0x66, 0x68, +0xc0, 0x46, 0x01, 0x96, 0xe9, 0x6b, 0x73, 0x1a, 0xe9, 0x6a, 0x71, 0x1a, +0x26, 0x68, 0x2a, 0x6b, 0x96, 0x42, 0x00, 0xd2, 0x32, 0x1c, 0x01, 0x9e, +0x96, 0x1b, 0xa2, 0x68, 0xc0, 0x46, 0x00, 0x92, 0x00, 0x2a, 0x09, 0xd0, +0x28, 0x6a, 0x6a, 0x6a, 0x41, 0x18, 0x00, 0x98, 0xc0, 0x18, 0x33, 0x1c, +0xfc, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x61, 0x68, 0x89, 0x19, +0x61, 0x60, 0x22, 0x68, 0x91, 0x42, 0x0d, 0xd1, 0x61, 0x69, 0x38, 0x1c, +0xfb, 0xf7, 0xc1, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x0e, 0xd1, 0xa1, 0x69, +0x38, 0x1c, 0xfb, 0xf7, 0xba, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x07, 0xd1, +0x61, 0x68, 0x2a, 0x6b, 0x91, 0x42, 0xc2, 0xd3, 0xa9, 0x6b, 0xaa, 0x6a, +0x89, 0x18, 0xa9, 0x63, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xb0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfb, 0xf7, +0xbf, 0xfa, 0xfa, 0x1d, 0x09, 0x32, 0x32, 0x48, 0x00, 0x21, 0xc9, 0x43, +0xc4, 0x1d, 0xb9, 0x34, 0xe1, 0x60, 0xf9, 0x88, 0xc3, 0x1d, 0x89, 0x33, +0x19, 0x73, 0xc1, 0x1d, 0x79, 0x31, 0xbd, 0x68, 0xc0, 0x46, 0x0d, 0x62, +0xff, 0x68, 0xc0, 0x46, 0x4f, 0x62, 0x17, 0x68, 0xc0, 0x46, 0x8f, 0x62, +0x57, 0x68, 0xc0, 0x46, 0xcf, 0x62, 0x92, 0x68, 0xc0, 0x46, 0x4a, 0x63, +0xca, 0x6a, 0x8f, 0x6a, 0xd2, 0x19, 0x0a, 0x63, 0x1a, 0x7b, 0x01, 0x2a, +0x0d, 0xd0, 0x02, 0x2a, 0x1a, 0xd0, 0x03, 0x2a, 0x2e, 0xd1, 0xc2, 0x1d, +0xc9, 0x32, 0x52, 0x78, 0x00, 0x2a, 0x07, 0xd1, 0x10, 0x20, 0x89, 0x6b, +0xc0, 0x46, 0xe1, 0x60, 0x25, 0xe0, 0xff, 0xf7, 0x4d, 0xff, 0x22, 0xe0, +0xff, 0xf7, 0xac, 0xfd, 0x00, 0x28, 0x1e, 0xd1, 0xe1, 0x69, 0x00, 0x29, +0x1b, 0xd0, 0x09, 0x7a, 0x15, 0x4b, 0xc9, 0x18, 0x02, 0x91, 0x16, 0xe0, +0x8a, 0x6a, 0xcb, 0x6a, 0x9f, 0x18, 0x4d, 0x6b, 0xaf, 0x42, 0x05, 0xd8, +0x00, 0x2a, 0x03, 0xd0, 0x9f, 0x07, 0x01, 0xd1, 0x92, 0x07, 0x01, 0xd0, +0x0f, 0x20, 0x08, 0xe0, 0x89, 0x6b, 0x99, 0x42, 0x01, 0xd0, 0xe1, 0x60, +0xf8, 0xe7, 0xff, 0xf7, 0x53, 0xff, 0x00, 0xe0, 0x10, 0x20, 0x01, 0xab, +0x58, 0x80, 0xe0, 0x68, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, +0xfb, 0xf7, 0x9e, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x3c, 0xac, 0x20, 0x40, 0x0d, 0xf0, 0xfe, 0xca, +0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, +0x4d, 0xfa, 0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 0xa0, 0xfc, 0x00, 0x28, +0x02, 0xd1, 0x00, 0x98, 0xff, 0xf7, 0xc4, 0xfc, 0x02, 0xab, 0x58, 0x80, +0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x7e, 0xf9, 0x01, 0x20, 0x05, 0xb0, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, +0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x32, 0xfa, 0x68, 0x46, 0xb9, 0x68, +0xff, 0xf7, 0x85, 0xfc, 0x00, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x02, 0xab, +0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x65, 0xf9, 0x01, 0x20, +0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x85, 0xb0, +0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, +0x19, 0xfa, 0x3c, 0x69, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x14, 0xfa, +0x68, 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x67, 0xfc, 0x8c, 0x24, 0x00, 0x28, +0x0e, 0xd1, 0xb9, 0x68, 0x00, 0x29, 0x02, 0xd1, 0xfa, 0x68, 0x00, 0x2a, +0x08, 0xd0, 0xf8, 0x88, 0x23, 0x1c, 0x8c, 0x28, 0x00, 0xd8, 0x03, 0x1c, +0xf8, 0x68, 0x00, 0x9a, 0xfc, 0xf7, 0x38, 0xfe, 0x02, 0xab, 0x58, 0x80, +0x03, 0x94, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x37, 0xf9, 0x01, 0x20, +0x05, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0x04, 0x48, +0xff, 0x22, 0x02, 0x72, 0x8c, 0x30, 0x01, 0x31, 0x04, 0x29, 0xfa, 0xd3, +0x70, 0x47, 0x00, 0x00, 0xb0, 0x6e, 0x21, 0x40, 0x02, 0x48, 0x03, 0x49, +0x40, 0x1a, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0xb9, 0xce, 0x21, 0x40, +0xb5, 0xce, 0x21, 0x40, 0x00, 0x21, 0x08, 0x4a, 0x8b, 0x00, 0x5b, 0x18, +0x9b, 0x00, 0xd3, 0x56, 0x83, 0x42, 0x04, 0xd1, 0x88, 0x00, 0x40, 0x18, +0x80, 0x00, 0x80, 0x18, 0x70, 0x47, 0x01, 0x31, 0x01, 0x29, 0xf1, 0xd3, +0x00, 0x20, 0xf9, 0xe7, 0xe0, 0x70, 0x21, 0x40, 0x80, 0xb5, 0x00, 0xf0, +0x0c, 0xf8, 0x00, 0x27, 0x38, 0x1c, 0x00, 0xf0, 0x45, 0xf8, 0x78, 0x1c, +0x07, 0x04, 0x3f, 0x0c, 0x0c, 0x2f, 0xf7, 0xdd, 0x80, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x1c, 0x48, 0x02, 0x68, 0x1c, 0x49, 0x8b, 0x69, 0xd2, 0x18, +0x02, 0x60, 0x8a, 0x6a, 0x43, 0x68, 0x9b, 0x18, 0x43, 0x60, 0x93, 0x42, +0x02, 0xd2, 0x82, 0x68, 0x01, 0x32, 0x82, 0x60, 0xc2, 0x68, 0x0b, 0x6a, +0xd2, 0x18, 0xc2, 0x60, 0x42, 0x69, 0xcb, 0x68, 0xd2, 0x18, 0x42, 0x61, +0xc2, 0x69, 0x8b, 0x68, 0xd2, 0x18, 0xc2, 0x61, 0x02, 0x69, 0x0b, 0x69, +0xd2, 0x18, 0x02, 0x61, 0x82, 0x69, 0x0b, 0x68, 0xd2, 0x18, 0x82, 0x61, +0x02, 0x6b, 0xcb, 0x69, 0xd2, 0x18, 0x02, 0x63, 0x4a, 0x6a, 0x43, 0x6b, +0x9b, 0x18, 0x43, 0x63, 0x93, 0x42, 0x02, 0xd2, 0x82, 0x6b, 0x01, 0x32, +0x82, 0x63, 0xc2, 0x6b, 0x4b, 0x69, 0xd2, 0x18, 0xc2, 0x63, 0x02, 0x6c, +0xc9, 0x6a, 0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0x10, 0x2a, 0x00, 0x80, +0x00, 0x08, 0x14, 0x40, 0x88, 0xb5, 0x69, 0x46, 0x00, 0xf0, 0x17, 0xf8, +0x81, 0x08, 0x0a, 0xd0, 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22, +0x83, 0x00, 0x00, 0x9f, 0xc0, 0x46, 0xfa, 0x50, 0x01, 0x30, 0x88, 0x42, +0xf8, 0xd3, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, +0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, +0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 0x02, 0x28, 0x0c, 0xd0, +0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 0x08, 0x60, 0x10, 0x1c, +0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 0x50, 0x22, 0x08, 0x60, +0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 0xf3, 0xe7, 0x00, 0x00, +0x08, 0x83, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, +0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x00, 0x27, 0x68, 0x46, 0xfe, 0xf7, +0xa7, 0xfb, 0x10, 0x4c, 0x00, 0x28, 0x0b, 0xd0, 0x00, 0xf0, 0x3e, 0xf8, +0x00, 0x28, 0x07, 0xd0, 0x01, 0x27, 0x10, 0x23, 0x20, 0x68, 0x18, 0x43, +0x20, 0x60, 0x60, 0x68, 0x18, 0x43, 0x0b, 0xe0, 0x10, 0x23, 0xa0, 0x68, +0x98, 0x43, 0xa0, 0x60, 0x20, 0x69, 0x98, 0x43, 0x20, 0x61, 0x20, 0x68, +0x98, 0x43, 0x20, 0x60, 0x60, 0x68, 0x98, 0x43, 0x60, 0x60, 0x38, 0x1c, +0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0x00, 0xf0, 0xb5, 0xfc, 0xfe, 0xf7, +0xc5, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x14, 0x24, +0x00, 0x25, 0x00, 0x27, 0x08, 0x4e, 0x02, 0x20, 0x21, 0x1c, 0x32, 0x1c, +0xfa, 0xf7, 0xec, 0xfe, 0x78, 0x40, 0x07, 0x04, 0x3f, 0x0c, 0x02, 0x34, +0x01, 0x35, 0x03, 0x2d, 0xf3, 0xd3, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x39, 0xb7, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x24, +0x20, 0x1c, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 0x00, 0x20, +0x00, 0x06, 0x00, 0x0e, 0x16, 0xd0, 0x0d, 0x4a, 0x3a, 0x21, 0x02, 0x20, +0xfa, 0xf7, 0xce, 0xfe, 0x07, 0x04, 0x3f, 0x0c, 0x03, 0xd1, 0x00, 0x20, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xf7, 0xcf, 0xff, 0xc0, 0x43, +0x00, 0x04, 0x00, 0x0c, 0xb8, 0x42, 0x00, 0xd0, 0x00, 0x24, 0x20, 0x06, +0x00, 0x0e, 0xf1, 0xe7, 0x20, 0x1c, 0xef, 0xe7, 0xe8, 0x0d, 0x00, 0x80, +0x39, 0xb7, 0x21, 0x40, 0xb0, 0xb5, 0x01, 0x27, 0x3a, 0x1c, 0x18, 0x4b, +0xdb, 0x68, 0x01, 0x2b, 0x00, 0xd0, 0x00, 0x22, 0x12, 0x06, 0x12, 0x0e, +0x00, 0x24, 0x00, 0x2a, 0x23, 0xd0, 0x14, 0x4a, 0x53, 0x68, 0x1b, 0x04, +0x1b, 0x0c, 0x1d, 0x02, 0x1b, 0x12, 0x2b, 0x43, 0x92, 0x68, 0x12, 0x04, +0x12, 0x0c, 0x15, 0x02, 0x12, 0x12, 0x2a, 0x43, 0x12, 0x04, 0x12, 0x0c, +0x1b, 0x04, 0x1a, 0x43, 0x51, 0x40, 0x01, 0x31, 0x0f, 0xd1, 0x00, 0x28, +0x02, 0xd0, 0xff, 0xf7, 0x9b, 0xff, 0xc4, 0x43, 0x22, 0x04, 0x12, 0x0c, +0x07, 0x4b, 0x3a, 0x21, 0x02, 0x20, 0xfa, 0xf7, 0x8a, 0xfe, 0x38, 0x1c, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0x00, 0x00, +0xe8, 0x0d, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x7b, 0xb7, 0x21, 0x40, +0x80, 0xb4, 0x03, 0x22, 0xc2, 0x80, 0x15, 0x4a, 0xc0, 0x46, 0x82, 0x60, +0x14, 0x4a, 0x12, 0x88, 0x01, 0x32, 0xc2, 0x60, 0x00, 0x20, 0x13, 0x4a, +0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, +0xf8, 0xd3, 0x20, 0x22, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x0e, 0x4b, +0x1f, 0x5c, 0xc0, 0x46, 0x0f, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, +0xf8, 0xd3, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x09, 0x4a, 0x13, 0x5c, +0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, +0x00, 0x20, 0x08, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x17, 0x40, 0x00, 0x02, +0xe8, 0x0d, 0x00, 0x80, 0xfc, 0x03, 0x00, 0x80, 0x05, 0x04, 0x00, 0x80, +0x0e, 0x04, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x21, 0x45, 0x4d, 0xe8, 0x1d, +0x79, 0x30, 0x41, 0x73, 0x01, 0x73, 0x64, 0x22, 0x42, 0x82, 0x82, 0x82, +0xc1, 0x82, 0x7d, 0x21, 0xc9, 0x00, 0x01, 0x83, 0x00, 0x21, 0x41, 0x83, +0x3f, 0x48, 0x01, 0x22, 0x00, 0xf0, 0x08, 0xfb, 0x00, 0x26, 0xf6, 0x43, +0x3d, 0x4c, 0xe7, 0x1d, 0x39, 0x37, 0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, +0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, 0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, +0xb3, 0xfd, 0x38, 0x48, 0x02, 0x22, 0x00, 0x21, 0x00, 0xf0, 0xf4, 0xfa, +0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, 0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, +0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, 0xa4, 0xfd, 0xe8, 0x68, 0x2f, 0x1c, +0x01, 0x28, 0x05, 0xd1, 0x2f, 0x48, 0x7d, 0x22, 0xd2, 0x00, 0x00, 0x21, +0x00, 0xf0, 0xe0, 0xfa, 0x2d, 0x4d, 0x28, 0x1c, 0xfa, 0xf7, 0x02, 0xfe, +0x2c, 0x48, 0xfa, 0xf7, 0xff, 0xfd, 0x2c, 0x48, +0xfa, 0xf7, 0xfc, 0xfd, 0x2b, 0x4e, 0x71, 0x23, 0x5b, 0x01, 0xfc, 0x18, +0x2a, 0x4f, 0x20, 0x79, 0x00, 0x28, 0x0f, 0xd0, 0x28, 0x1c, 0xfa, 0xf7, +0xf1, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xee, 0xfd, 0x00, 0x28, 0x04, 0xd0, +0x38, 0x1c, 0xfa, 0xf7, 0xe9, 0xfd, 0x00, 0x28, 0xfa, 0xd1, 0x30, 0x1c, +0xfa, 0xf7, 0xe4, 0xfd, 0x60, 0x79, 0x00, 0x28, 0x23, 0xd0, 0x28, 0x1c, +0xfa, 0xf7, 0xde, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xdb, 0xfd, 0x00, 0x28, +0x04, 0xd0, 0x38, 0x1c, 0xfa, 0xf7, 0xd6, 0xfd, 0x00, 0x28, 0xfa, 0xd1, +0x19, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x14, 0x20, +0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, +0x89, 0x0a, 0x03, 0xd3, 0x13, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x03, 0xe0, +0x12, 0x49, 0xc0, 0x46, 0x08, 0x64, 0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, +0x1e, 0xfe, 0x10, 0x48, 0xfa, 0xf7, 0xb8, 0xfd, 0x0f, 0x48, 0xfa, 0xf7, +0xb5, 0xfd, 0xbc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x5d, 0x22, 0xff, 0xff, +0xa0, 0x82, 0x20, 0x40, 0x21, 0x21, 0xff, 0xff, 0x59, 0x7e, 0x21, 0x40, +0xf4, 0x01, 0xff, 0xff, 0x09, 0x2c, 0xff, 0xff, 0x04, 0x02, 0xff, 0xff, +0x00, 0x00, 0xff, 0xff, 0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, +0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x65, 0xa8, 0x21, 0x40, +0x48, 0x57, 0xff, 0xff, 0x00, 0xb5, 0x10, 0x20, 0x0f, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x0f, 0x4a, 0x0f, 0x48, 0x64, 0x21, 0xfa, 0xf7, 0x8e, 0xfd, +0x0e, 0x48, 0x01, 0x22, 0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x08, 0x21, +0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c, 0x07, 0xd1, 0x00, 0x68, +0x80, 0x0a, 0x04, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x08, 0xbc, +0x18, 0x47, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x64, 0xf9, 0xe7, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0x25, 0x55, 0xff, 0xff, 0xf8, 0x28, 0x00, 0x80, +0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, +0xb0, 0xb5, 0x24, 0x4f, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, +0x06, 0x20, 0x22, 0x4d, 0x22, 0x4c, 0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, +0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, +0x00, 0xe0, 0x20, 0x64, 0x03, 0x20, 0xfe, 0xf7, 0xc5, 0xfa, 0xfb, 0xf7, +0xa1, 0xf9, 0x01, 0x23, 0x18, 0x43, 0xfb, 0xf7, 0x6b, 0xfa, 0x00, 0xf0, +0x31, 0xf8, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x07, 0x20, +0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, +0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0x00, 0xf0, +0x89, 0xf8, 0x00, 0xf0, 0x69, 0xf8, 0x00, 0xf0, 0xd3, 0xf8, 0x01, 0x21, +0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x09, 0x20, 0x00, 0x29, 0x05, 0xd1, +0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, +0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, +0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x21, 0x48, 0xfa, 0xf7, 0x14, 0xfd, +0xfd, 0xf7, 0x4a, 0xf8, 0x00, 0xf0, 0xa6, 0xf8, 0xfd, 0xf7, 0x58, 0xf8, +0x00, 0xf0, 0xc0, 0xf8, 0xfc, 0xf7, 0x9f, 0xfc, 0xff, 0xf7, 0x5c, 0xfd, +0xfd, 0xf7, 0x3c, 0xfa, 0xfd, 0xf7, 0xc4, 0xf9, 0xfd, 0xf7, 0xdc, 0xfa, +0xfd, 0xf7, 0x60, 0xf9, 0xfd, 0xf7, 0x1a, 0xf9, +0xfd, 0xf7, 0xa2, 0xf9, 0x00, 0xf0, 0x8a, 0xf9, 0xfd, 0xf7, 0xb6, 0xfb, +0xfd, 0xf7, 0x24, 0xfb, 0xfd, 0xf7, 0xec, 0xfa, 0xfd, 0xf7, 0x46, 0xf8, +0xfa, 0xf7, 0xf2, 0xfb, 0xff, 0xf7, 0x18, 0xfd, 0x00, 0x20, 0xff, 0xf7, +0xef, 0xfd, 0x00, 0xf0, 0x29, 0xf8, 0x00, 0x20, 0x0a, 0x49, 0x71, 0x23, +0x5b, 0x01, 0xca, 0x18, 0x10, 0x71, 0x50, 0x71, 0x07, 0x23, 0x5b, 0x02, +0xc9, 0x18, 0xc8, 0x62, 0x06, 0x49, 0xc0, 0x46, 0x48, 0x62, 0x00, 0xf0, +0x87, 0xf9, 0x05, 0x48, 0xfa, 0xf7, 0xd6, 0xfc, 0x08, 0xbc, 0x18, 0x47, +0xff, 0xb8, 0x21, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x00, +0x31, 0x98, 0x21, 0x40, 0x00, 0xb5, 0x04, 0x48, 0xfa, 0xf7, 0xc8, 0xfc, +0xfd, 0xf7, 0x7c, 0xfb, 0xfd, 0xf7, 0x34, 0xf8, 0x08, 0xbc, 0x18, 0x47, +0x11, 0xa2, 0x21, 0x40, 0x00, 0xb5, 0xfd, 0xf7, 0x81, 0xfa, 0x06, 0x48, +0xfa, 0xf7, 0xba, 0xfc, 0xfd, 0xf7, 0x56, 0xfa, 0xfd, 0xf7, 0x8c, 0xfb, +0xfd, 0xf7, 0x9e, 0xfb, 0xfd, 0xf7, 0xac, 0xfb, 0x08, 0xbc, 0x18, 0x47, +0x91, 0x03, 0xff, 0xff, 0xf8, 0xb5, 0x1a, 0x48, 0xc1, 0x6b, 0xff, 0x29, +0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x0d, 0x1c, 0x16, 0x1c, 0x17, 0x4c, +0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 0xa1, 0x69, 0x99, 0x43, +0x1f, 0x04, 0xa1, 0x61, 0xf8, 0x60, 0xa0, 0x69, 0xc0, 0x46, 0x38, 0x61, +0x11, 0x4a, 0x12, 0x49, 0x64, 0x20, 0xfa, 0xf7, 0x95, 0xfc, 0x11, 0x4a, +0xc0, 0x46, 0x00, 0x92, 0x10, 0x4b, 0x00, 0x20, 0x29, 0x1c, 0x32, 0x1c, +0xfa, 0xf7, 0x94, 0xfc, 0x0e, 0x48, 0xc1, 0x68, 0x08, 0x29, 0xfc, 0xd1, +0x10, 0x23, 0x60, 0x69, 0x98, 0x43, 0x60, 0x61, 0xf8, 0x60, 0x01, 0x20, +0xe3, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x70, 0xf8, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x01, 0x18, 0x40, 0xe8, 0x0d, 0x00, 0x80, +0xa0, 0x54, 0xff, 0xff, 0x11, 0xc8, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, +0x44, 0x80, 0x20, 0x40, 0x40, 0x01, 0x18, 0x40, 0xfa, 0x21, 0x03, 0x48, +0xc0, 0x46, 0x41, 0x62, 0x40, 0x21, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, +0xc0, 0x00, 0x18, 0x00, 0x07, 0x48, 0x41, 0x69, 0x07, 0x4b, 0x19, 0x43, +0x41, 0x61, 0x82, 0x69, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, +0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x70, 0x47, 0x00, 0x00, +0xe8, 0x0d, 0x00, 0x80, 0xfe, 0xaf, 0x9a, 0x10, 0xf0, 0xb4, 0x4b, 0x4a, +0x4b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x4b, 0x4d, 0x4b, 0x4b, 0x98, 0x42, +0x02, 0xd0, 0x01, 0x33, 0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x28, 0x80, +0x01, 0x21, 0xc9, 0x03, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0x61, 0x61, +0x28, 0x88, 0x40, 0x04, 0x44, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x06, 0x20, +0xaf, 0x60, 0x43, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x20, 0x20, 0xc8, 0x23, +0x43, 0x43, 0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3e, 0x4e, 0xc0, 0x46, +0x31, 0x61, 0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3b, 0x4e, 0xc0, 0x46, +0xf3, 0x61, 0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, +0x81, 0x42, 0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, +0x41, 0x1e, 0x34, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, +0x02, 0x38, 0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, +0x06, 0xe0, 0x2e, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, +0x88, 0x42, 0xd2, 0xd9, 0x2b, 0x49, 0x00, 0x20, +0x63, 0x69, 0x9b, 0x08, 0x07, 0xd0, 0x2a, 0x4b, 0x87, 0x00, 0xcb, 0x51, +0x67, 0x69, 0xbf, 0x08, 0x01, 0x30, 0x87, 0x42, 0xf8, 0xd8, 0x24, 0x49, +0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89, 0x58, 0x20, 0x60, 0x43, 0x87, 0x18, +0x00, 0x20, 0x00, 0x22, 0x00, 0x2c, 0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, +0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, +0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc, 0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, +0x00, 0x19, 0x40, 0x01, 0xc7, 0x19, 0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, +0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01, 0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, +0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, +0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69, 0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, +0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51, 0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, +0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00, 0x08, 0x18, 0x04, 0x38, 0x28, 0x61, +0xf0, 0xbc, 0x70, 0x47, 0xb8, 0xce, 0x21, 0x40, 0x00, 0x00, 0x18, 0x40, +0xe8, 0x0d, 0x00, 0x80, 0x02, 0x99, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, +0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00, +0x0a, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, +0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, +0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x61, 0x01, 0x20, 0x00, 0x06, +0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x80, 0xb4, 0x02, 0x1c, 0x0b, 0x48, 0x1b, 0x23, 0xdb, 0x01, 0xc3, 0x18, +0x5a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61, +0x87, 0x69, 0x9f, 0x43, 0x01, 0x23, 0x1b, 0x05, 0x87, 0x61, 0xda, 0x60, +0x80, 0x69, 0xc0, 0x46, 0x18, 0x61, 0xa1, 0x20, 0x40, 0x03, 0x81, 0x61, +0x80, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0xff, 0xf7, +0xc9, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf8, 0x00, 0x20, 0x09, 0x49, +0x00, 0x22, 0x03, 0x01, 0x5f, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xfb, 0x18, +0x5a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3, 0x04, 0x48, 0x01, 0x22, +0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xe8, 0x0d, 0x00, 0x80, 0x91, 0x3d, 0xff, 0xff, 0x00, 0xb5, 0x02, 0x48, +0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xa8, 0x61, 0x00, 0x00, +0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b, 0xa1, 0x21, 0x49, 0x03, +0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c, 0x59, 0x69, 0x53, 0x01, +0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43, 0x87, 0x61, 0xd1, 0x60, +0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc, 0x70, 0x47, 0x18, 0x1c, +0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43, 0x47, 0x61, 0xd7, 0x60, +0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c, 0x03, 0x01, 0x1d, 0x19, +0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5d, 0x6a, 0xbd, 0x42, 0x05, 0xd1, +0xdd, 0x6a, 0x95, 0x42, 0x02, 0xd1, 0x9b, 0x6a, 0x8b, 0x42, 0x1c, 0xd0, +0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20, 0x03, 0x01, 0x1d, 0x19, +0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5b, 0x6a, 0x00, 0x2b, 0x09, 0xd1, +0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0xda, 0x62, +0x99, 0x62, 0x1a, 0x63, 0x5f, 0x62, 0x02, 0xe0, +0x01, 0x30, 0x0b, 0x28, 0xea, 0xd3, 0x0b, 0x28, 0x01, 0xd1, 0x00, 0x20, +0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x90, 0xb4, 0x01, 0x1c, 0x00, 0x22, 0x01, 0x20, 0x16, 0x4f, 0x01, 0xe0, +0x00, 0x2a, 0x07, 0xd1, 0x03, 0x01, 0xdc, 0x19, 0x33, 0x23, 0x9b, 0x01, +0xe3, 0x18, 0x5b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19, +0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x53, 0x6a, 0xc0, 0x46, 0x53, 0x61, +0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61, 0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, +0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28, +0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x5a, 0x68, 0x8a, 0x42, +0x03, 0xd1, 0x00, 0x21, 0x59, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, +0xc0, 0x43, 0xfa, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x68, 0x1b, 0x00, 0x80, +0x0b, 0x28, 0x17, 0xda, 0x0c, 0x49, 0x01, 0x23, 0x5b, 0x06, 0x8a, 0x69, +0x13, 0x43, 0x01, 0x22, 0x12, 0x05, 0x8b, 0x61, 0x13, 0x61, 0x00, 0x01, +0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc3, 0x6a, 0xc0, 0x46, +0x03, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61, +0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, +0x90, 0xb4, 0x08, 0x4a, 0xd0, 0x69, 0x00, 0x21, 0x07, 0x4f, 0xd3, 0x69, +0x83, 0x42, 0x02, 0xd9, 0xfc, 0x1a, 0x20, 0x18, 0x00, 0xe0, 0xc0, 0x1a, +0x09, 0x18, 0x18, 0x1c, 0xb9, 0x42, 0xf4, 0xd9, 0x90, 0xbc, 0x70, 0x47, +0x00, 0x20, 0x14, 0x40, 0xa8, 0x61, 0x00, 0x00, 0x43, 0x1a, 0x93, 0x42, +0x30, 0xd3, 0x84, 0x46, 0x8b, 0x07, 0x07, 0xd0, 0x52, 0x1e, 0x29, 0xd3, +0x0b, 0x78, 0x03, 0x70, 0x40, 0x1c, 0x49, 0x1c, 0x8b, 0x07, 0xf7, 0xd1, +0x83, 0x07, 0x17, 0xd1, 0x10, 0x3a, 0x05, 0xd3, 0xb0, 0xb4, 0xb8, 0xc9, +0xb8, 0xc0, 0x10, 0x3a, 0xfb, 0xd2, 0xb0, 0xbc, 0x0c, 0x32, 0x0f, 0xd3, +0x08, 0xc9, 0x08, 0xc0, 0x12, 0x1f, 0xfb, 0xd2, 0x0a, 0xe0, 0x08, 0xc9, +0x03, 0x70, 0x1b, 0x0a, 0x43, 0x70, 0x1b, 0x0a, 0x83, 0x70, 0x1b, 0x0a, +0xc3, 0x70, 0x00, 0x1d, 0x12, 0x1f, 0xf4, 0xd2, 0xd2, 0x1c, 0x05, 0xd3, +0x0b, 0x78, 0x03, 0x70, 0x49, 0x1c, 0x40, 0x1c, 0x52, 0x1e, 0xf9, 0xd2, +0x60, 0x46, 0x70, 0x47, 0x03, 0x1c, 0x0b, 0x43, 0x13, 0x43, 0x9b, 0x07, +0x04, 0xd1, 0x12, 0x1f, 0x8b, 0x58, 0x83, 0x50, 0xfb, 0xd1, 0x70, 0x47, +0x52, 0x1e, 0x8b, 0x5c, 0x83, 0x54, 0xfb, 0xd1, 0x70, 0x47, 0x00, 0x00, +0x00, 0x20, 0x70, 0x47, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/typhoon.h linux.21pre4-ac6/drivers/net/typhoon.h --- linux.21pre4/drivers/net/typhoon.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/net/typhoon.h 2003-02-19 16:01:19.000000000 +0000 @@ -0,0 +1,613 @@ +/* typhoon.h: chip info for the 3Com 3CR990 family of controllers */ +/* + Written 2002-2003 by David Dillow + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. + + This software is available on a public web site. It may enable + cryptographic capabilities of the 3Com hardware, and may be + exported from the United States under License Exception "TSU" + pursuant to 15 C.F.R. Section 740.13(e). + + This work was funded by the National Library of Medicine under + the Department of Energy project number 0274DD06D1 and NLM project + number Y1-LM-2015-01. +*/ + +/* All Typhoon ring positions are specificed in bytes, and point to the + * first "clean" entry in the ring -- ie the next entry we use for whatever + * purpose. + */ + +/* The Typhoon basic ring + * ringBase: where this ring lives (our virtual address) + * lastWrite: the next entry we'll use + */ +struct basic_ring { + u8 *ringBase; + u32 lastWrite; +}; + +/* The Typoon transmit ring -- same as a basic ring, plus: + * lastRead: where we're at in regard to cleaning up the ring + * writeRegister: register to use for writing (different for Hi & Lo rings) + */ +struct transmit_ring { + u8 *ringBase; + u32 lastWrite; + u32 lastRead; + int writeRegister; +}; + +/* The host<->Typhoon ring index structure + * This indicates the current positions in the rings + * + * All values must be in little endian format for the 3XP + * + * rxHiCleared: entry we've cleared to in the Hi receive ring + * rxLoCleared: entry we've cleared to in the Lo receive ring + * rxBuffReady: next entry we'll put a free buffer in + * respCleared: entry we've cleared to in the response ring + * + * txLoCleared: entry the NIC has cleared to in the Lo transmit ring + * txHiCleared: entry the NIC has cleared to in the Hi transmit ring + * rxLoReady: entry the NIC has filled to in the Lo receive ring + * rxBuffCleared: entry the NIC has cleared in the free buffer ring + * cmdCleared: entry the NIC has cleared in the command ring + * respReady: entry the NIC has filled to in the response ring + * rxHiReady: entry the NIC has filled to in the Hi receive ring + */ +struct typhoon_indexes { + /* The first four are written by the host, and read by the NIC */ + volatile u32 rxHiCleared; + volatile u32 rxLoCleared; + volatile u32 rxBuffReady; + volatile u32 respCleared; + + /* The remaining are written by the NIC, and read by the host */ + volatile u32 txLoCleared; + volatile u32 txHiCleared; + volatile u32 rxLoReady; + volatile u32 rxBuffCleared; + volatile u32 cmdCleared; + volatile u32 respReady; + volatile u32 rxHiReady; +} __attribute__ ((packed)); + +/* The host<->Typhoon interface + * Our means of communicating where things are + * + * All values must be in little endian format for the 3XP + * + * ringIndex: 64 bit bus address of the index structure + * txLoAddr: 64 bit bus address of the Lo transmit ring + * txLoSize: size (in bytes) of the Lo transmit ring + * txHi*: as above for the Hi priority transmit ring + * rxLo*: as above for the Lo priority receive ring + * rxBuff*: as above for the free buffer ring + * cmd*: as above for the command ring + * resp*: as above for the response ring + * zeroAddr: 64 bit bus address of a zero word (for DMA) + * rxHi*: as above for the Hi Priority receive ring + * + * While there is room for 64 bit addresses, current versions of the 3XP + * only do 32 bit addresses, so the *Hi for each of the above will always + * be zero. + */ +struct typhoon_interface { + u32 ringIndex; + u32 ringIndexHi; + u32 txLoAddr; + u32 txLoAddrHi; + u32 txLoSize; + u32 txHiAddr; + u32 txHiAddrHi; + u32 txHiSize; + u32 rxLoAddr; + u32 rxLoAddrHi; + u32 rxLoSize; + u32 rxBuffAddr; + u32 rxBuffAddrHi; + u32 rxBuffSize; + u32 cmdAddr; + u32 cmdAddrHi; + u32 cmdSize; + u32 respAddr; + u32 respAddrHi; + u32 respSize; + u32 zeroAddr; + u32 zeroAddrHi; + u32 rxHiAddr; + u32 rxHiAddrHi; + u32 rxHiSize; +} __attribute__ ((packed)); + +/* The Typhoon transmit/fragment descriptor + * + * A packet is described by a packet descriptor, followed by option descriptors, + * if any, then one or more fragment descriptors. + * + * Packet descriptor: + * flags: Descriptor type + * len:i zero, or length of this packet + * addr*: 8 bytes of opaque data to the firmware -- for skb pointer + * processFlags: Determine offload tasks to perform on this packet. + * + * Fragment descriptor: + * flags: Descriptor type + * len:i length of this fragment + * addr: low bytes of DMA address for this part of the packet + * addrHi: hi bytes of DMA address for this part of the packet + * processFlags: must be zero + * + * TYPHOON_DESC_VALID is not mentioned in their docs, but their Linux + * driver uses it. + */ +struct tx_desc { + u8 flags; +#define TYPHOON_TYPE_MASK 0x07 +#define TYPHOON_FRAG_DESC 0x00 +#define TYPHOON_TX_DESC 0x01 +#define TYPHOON_CMD_DESC 0x02 +#define TYPHOON_OPT_DESC 0x03 +#define TYPHOON_RX_DESC 0x04 +#define TYPHOON_RESP_DESC 0x05 +#define TYPHOON_OPT_TYPE_MASK 0xf0 +#define TYPHOON_OPT_IPSEC 0x00 +#define TYPHOON_OPT_TCP_SEG 0x10 +#define TYPHOON_CMD_RESPOND 0x40 +#define TYPHOON_RESP_ERROR 0x40 +#define TYPHOON_RX_ERROR 0x40 +#define TYPHOON_DESC_VALID 0x80 + u8 numDesc; + u16 len; + u32 addr; + u32 addrHi; + u32 processFlags; +#define TYPHOON_TX_PF_NO_CRC __constant_cpu_to_le32(0x00000001) +#define TYPHOON_TX_PF_IP_CHKSUM __constant_cpu_to_le32(0x00000002) +#define TYPHOON_TX_PF_TCP_CHKSUM __constant_cpu_to_le32(0x00000004) +#define TYPHOON_TX_PF_TCP_SEGMENT __constant_cpu_to_le32(0x00000008) +#define TYPHOON_TX_PF_INSERT_VLAN __constant_cpu_to_le32(0x00000010) +#define TYPHOON_TX_PF_IPSEC __constant_cpu_to_le32(0x00000020) +#define TYPHOON_TX_PF_VLAN_PRIORITY __constant_cpu_to_le32(0x00000040) +#define TYPHOON_TX_PF_UDP_CHKSUM __constant_cpu_to_le32(0x00000080) +#define TYPHOON_TX_PF_PAD_FRAME __constant_cpu_to_le32(0x00000100) +#define TYPHOON_TX_PF_RESERVED __constant_cpu_to_le32(0x00000e00) +#define TYPHOON_TX_PF_VLAN_MASK __constant_cpu_to_le32(0x0ffff000) +#define TYPHOON_TX_PF_INTERNAL __constant_cpu_to_le32(0xf0000000) +#define TYPHOON_TX_PF_VLAN_TAG_SHIFT 12 +} __attribute__ ((packed)); + +/* The TCP Segmentation offload option descriptor + * + * flags: descriptor type + * numDesc: must be 1 + * mss_flags: bits 0-11 (little endian) are MSS, 12 is first TSO descriptor + * 13 is list TSO descriptor, set both if only one TSO + * respAddrLo: low bytes of address of the bytesTx field of this descriptor + * bytesTx: total number of bytes in this TSO request + * status: 0 on completion + */ +struct tcpopt_desc { + u8 flags; + u8 numDesc; + u16 mss_flags; +#define TYPHOON_TSO_FIRST __constant_cpu_to_le16(0x1000) +#define TYPHOON_TSO_LAST __constant_cpu_to_le16(0x2000) + u32 respAddrLo; + u32 bytesTx; + u32 status; +} __attribute__ ((packed)); + +/* The IPSEC Offload descriptor + * + * flags: descriptor type + * numDesc: must be 1 + * ipsecFlags: bit 0: 0 -- generate IV, 1 -- use supplied IV + * sa1, sa2: Security Association IDs for this packet + * reserved: set to 0 + */ +struct ipsec_desc { + u8 flags; + u8 numDesc; + u16 ipsecFlags; +#define TYPHOON_IPSEC_GEN_IV __constant_cpu_to_le16(0x0000) +#define TYPHOON_IPSEC_USE_IV __constant_cpu_to_le16(0x0001) + u32 sa1; + u32 sa2; + u32 reserved; +} __attribute__ ((packed)); + +/* The Typhoon receive descriptor (Updated by NIC) + * + * flags: Descriptor type, error indication + * numDesc: Always zero + * frameLen: the size of the packet received + * addr: low 32 bytes of the virtual addr passed in for this buffer + * addrHi: high 32 bytes of the virtual addr passed in for this buffer + * rxStatus: Error if set in flags, otherwise result of offload processing + * filterResults: results of filtering on packet, not used + * ipsecResults: Results of IPSEC processing + * vlanTag: the 801.2q TCI from the packet + */ +struct rx_desc { + u8 flags; + u8 numDesc; + u16 frameLen; + u32 addr; + u32 addrHi; + u32 rxStatus; +#define TYPHOON_RX_ERR_INTERNAL __constant_cpu_to_le32(0x00000000) +#define TYPHOON_RX_ERR_FIFO_UNDERRUN __constant_cpu_to_le32(0x00000001) +#define TYPHOON_RX_ERR_BAD_SSD __constant_cpu_to_le32(0x00000002) +#define TYPHOON_RX_ERR_RUNT __constant_cpu_to_le32(0x00000003) +#define TYPHOON_RX_ERR_CRC __constant_cpu_to_le32(0x00000004) +#define TYPHOON_RX_ERR_OVERSIZE __constant_cpu_to_le32(0x00000005) +#define TYPHOON_RX_ERR_ALIGN __constant_cpu_to_le32(0x00000006) +#define TYPHOON_RX_ERR_DRIBBLE __constant_cpu_to_le32(0x00000007) +#define TYPHOON_RX_PROTO_MASK __constant_cpu_to_le32(0x00000003) +#define TYPHOON_RX_PROTO_UNKNOWN __constant_cpu_to_le32(0x00000000) +#define TYPHOON_RX_PROTO_IP __constant_cpu_to_le32(0x00000001) +#define TYPHOON_RX_PROTO_IPX __constant_cpu_to_le32(0x00000002) +#define TYPHOON_RX_VLAN __constant_cpu_to_le32(0x00000004) +#define TYPHOON_RX_IP_FRAG __constant_cpu_to_le32(0x00000008) +#define TYPHOON_RX_IPSEC __constant_cpu_to_le32(0x00000010) +#define TYPHOON_RX_IP_CHK_FAIL __constant_cpu_to_le32(0x00000020) +#define TYPHOON_RX_TCP_CHK_FAIL __constant_cpu_to_le32(0x00000040) +#define TYPHOON_RX_UDP_CHK_FAIL __constant_cpu_to_le32(0x00000080) +#define TYPHOON_RX_IP_CHK_GOOD __constant_cpu_to_le32(0x00000100) +#define TYPHOON_RX_TCP_CHK_GOOD __constant_cpu_to_le32(0x00000200) +#define TYPHOON_RX_UDP_CHK_GOOD __constant_cpu_to_le32(0x00000400) + u16 filterResults; +#define TYPHOON_RX_FILTER_MASK __constant_cpu_to_le16(0x7fff) +#define TYPHOON_RX_FILTERED __constant_cpu_to_le16(0x8000) + u16 ipsecResults; +#define TYPHOON_RX_OUTER_AH_GOOD __constant_cpu_to_le16(0x0001) +#define TYPHOON_RX_OUTER_ESP_GOOD __constant_cpu_to_le16(0x0002) +#define TYPHOON_RX_INNER_AH_GOOD __constant_cpu_to_le16(0x0004) +#define TYPHOON_RX_INNER_ESP_GOOD __constant_cpu_to_le16(0x0008) +#define TYPHOON_RX_OUTER_AH_FAIL __constant_cpu_to_le16(0x0010) +#define TYPHOON_RX_OUTER_ESP_FAIL __constant_cpu_to_le16(0x0020) +#define TYPHOON_RX_INNER_AH_FAIL __constant_cpu_to_le16(0x0040) +#define TYPHOON_RX_INNER_ESP_FAIL __constant_cpu_to_le16(0x0080) +#define TYPHOON_RX_UNKNOWN_SA __constant_cpu_to_le16(0x0100) +#define TYPHOON_RX_ESP_FORMAT_ERR __constant_cpu_to_le16(0x0200) + u32 vlanTag; +} __attribute__ ((packed)); + +/* The Typhoon free buffer descriptor, used to give a buffer to the NIC + * + * physAddr: low 32 bits of the bus address of the buffer + * physAddrHi: high 32 bits of the bus address of the buffer, always zero + * virtAddr: low 32 bits of the skb address + * virtAddrHi: high 32 bits of the skb address, always zero + * + * the virt* address is basically two 32 bit cookies, just passed back + * from the NIC + */ +struct rx_free { + u32 physAddr; + u32 physAddrHi; + u32 virtAddr; + u32 virtAddrHi; +} __attribute__ ((packed)); + +/* The Typhoon command descriptor, used for commands and responses + * + * flags: descriptor type + * numDesc: number of descriptors following in this command/response, + * ie, zero for a one descriptor command + * cmd: the command + * seqNo: sequence number (unused) + * parm1: use varies by command + * parm2: use varies by command + * parm3: use varies by command + */ +struct cmd_desc { + u8 flags; + u8 numDesc; + u16 cmd; +#define TYPHOON_CMD_TX_ENABLE __constant_cpu_to_le16(0x0001) +#define TYPHOON_CMD_TX_DISABLE __constant_cpu_to_le16(0x0002) +#define TYPHOON_CMD_RX_ENABLE __constant_cpu_to_le16(0x0003) +#define TYPHOON_CMD_RX_DISABLE __constant_cpu_to_le16(0x0004) +#define TYPHOON_CMD_SET_RX_FILTER __constant_cpu_to_le16(0x0005) +#define TYPHOON_CMD_READ_STATS __constant_cpu_to_le16(0x0007) +#define TYPHOON_CMD_XCVR_SELECT __constant_cpu_to_le16(0x0013) +#define TYPHOON_CMD_SET_MAX_PKT_SIZE __constant_cpu_to_le16(0x001a) +#define TYPHOON_CMD_READ_MEDIA_STATUS __constant_cpu_to_le16(0x001b) +#define TYPHOON_CMD_GOTO_SLEEP __constant_cpu_to_le16(0x0023) +#define TYPHOON_CMD_SET_MULTICAST_HASH __constant_cpu_to_le16(0x0025) +#define TYPHOON_CMD_SET_MAC_ADDRESS __constant_cpu_to_le16(0x0026) +#define TYPHOON_CMD_READ_MAC_ADDRESS __constant_cpu_to_le16(0x0027) +#define TYPHOON_CMD_VLAN_TYPE_WRITE __constant_cpu_to_le16(0x002b) +#define TYPHOON_CMD_CREATE_SA __constant_cpu_to_le16(0x0034) +#define TYPHOON_CMD_DELETE_SA __constant_cpu_to_le16(0x0035) +#define TYPHOON_CMD_READ_VERSIONS __constant_cpu_to_le16(0x0043) +#define TYPHOON_CMD_IRQ_COALESCE_CTRL __constant_cpu_to_le16(0x0045) +#define TYPHOON_CMD_ENABLE_WAKE_EVENTS __constant_cpu_to_le16(0x0049) +#define TYPHOON_CMD_SET_OFFLOAD_TASKS __constant_cpu_to_le16(0x004f) +#define TYPHOON_CMD_HELLO_RESP __constant_cpu_to_le16(0x0057) +#define TYPHOON_CMD_HALT __constant_cpu_to_le16(0x005d) +#define TYPHOON_CMD_READ_IPSEC_INFO __constant_cpu_to_le16(0x005e) +#define TYPHOON_CMD_GET_IPSEC_ENABLE __constant_cpu_to_le16(0x0067) +#define TYPHOON_CMD_GET_CMD_LVL __constant_cpu_to_le16(0x0069) + u16 seqNo; + u16 parm1; + u32 parm2; + u32 parm3; +} __attribute__ ((packed)); + +/* The Typhoon response descriptor, see command descriptor for details + */ +struct resp_desc { + u8 flags; + u8 numDesc; + u16 cmd; + u16 seqNo; + u16 parm1; + u32 parm2; + u32 parm3; +} __attribute__ ((packed)); + +#define INIT_COMMAND_NO_RESPONSE(x, command) \ + do { struct cmd_desc *_ptr = (x); \ + memset(_ptr, 0, sizeof(struct cmd_desc)); \ + _ptr->flags = TYPHOON_CMD_DESC | TYPHOON_DESC_VALID; \ + _ptr->cmd = command; \ + } while(0) + +/* We set seqNo to 1 if we're expecting a response from this command */ +#define INIT_COMMAND_WITH_RESPONSE(x, command) \ + do { struct cmd_desc *_ptr = (x); \ + memset(_ptr, 0, sizeof(struct cmd_desc)); \ + _ptr->flags = TYPHOON_CMD_RESPOND | TYPHOON_CMD_DESC; \ + _ptr->flags |= TYPHOON_DESC_VALID; \ + _ptr->cmd = command; \ + _ptr->seqNo = 1; \ + } while(0) + +/* TYPHOON_CMD_SET_RX_FILTER filter bits (cmd.parm1) + */ +#define TYPHOON_RX_FILTER_DIRECTED __constant_cpu_to_le16(0x0001) +#define TYPHOON_RX_FILTER_ALL_MCAST __constant_cpu_to_le16(0x0002) +#define TYPHOON_RX_FILTER_BROADCAST __constant_cpu_to_le16(0x0004) +#define TYPHOON_RX_FILTER_PROMISCOUS __constant_cpu_to_le16(0x0008) +#define TYPHOON_RX_FILTER_MCAST_HASH __constant_cpu_to_le16(0x0010) + +/* TYPHOON_CMD_READ_STATS response format + */ +struct stats_resp { + u8 flags; + u8 numDesc; + u16 cmd; + u16 seqNo; + u16 unused; + u32 txPackets; + u64 txBytes; + u32 txDeferred; + u32 txLateCollisions; + u32 txCollisions; + u32 txCarrierLost; + u32 txMultipleCollisions; + u32 txExcessiveCollisions; + u32 txFifoUnderruns; + u32 txMulticastTxOverflows; + u32 txFiltered; + u32 rxPacketsGood; + u64 rxBytesGood; + u32 rxFifoOverruns; + u32 BadSSD; + u32 rxCrcErrors; + u32 rxOversized; + u32 rxBroadcast; + u32 rxMulticast; + u32 rxOverflow; + u32 rxFiltered; + u32 linkStatus; +#define TYPHOON_LINK_STAT_MASK __constant_cpu_to_le32(0x00000001) +#define TYPHOON_LINK_GOOD __constant_cpu_to_le32(0x00000001) +#define TYPHOON_LINK_BAD __constant_cpu_to_le32(0x00000000) +#define TYPHOON_LINK_SPEED_MASK __constant_cpu_to_le32(0x00000002) +#define TYPHOON_LINK_100MBPS __constant_cpu_to_le32(0x00000002) +#define TYPHOON_LINK_10MBPS __constant_cpu_to_le32(0x00000000) +#define TYPHOON_LINK_DUPLEX_MASK __constant_cpu_to_le32(0x00000004) +#define TYPHOON_LINK_FULL_DUPLEX __constant_cpu_to_le32(0x00000004) +#define TYPHOON_LINK_HALF_DUPLEX __constant_cpu_to_le32(0x00000000) + u32 unused2; + u32 unused3; +} __attribute__ ((packed)); + +/* TYPHOON_CMD_XCVR_SELECT xcvr values (resp.parm1) + */ +#define TYPHOON_XCVR_10HALF __constant_cpu_to_le16(0x0000) +#define TYPHOON_XCVR_10FULL __constant_cpu_to_le16(0x0001) +#define TYPHOON_XCVR_100HALF __constant_cpu_to_le16(0x0002) +#define TYPHOON_XCVR_100FULL __constant_cpu_to_le16(0x0003) +#define TYPHOON_XCVR_AUTONEG __constant_cpu_to_le16(0x0004) + +/* TYPHOON_CMD_READ_MEDIA_STATUS (resp.parm1) + */ +#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE __constant_cpu_to_le16(0x0004) +#define TYPHOON_MEDIA_STAT_COLLISION_DETECT __constant_cpu_to_le16(0x0010) +#define TYPHOON_MEDIA_STAT_CARRIER_SENSE __constant_cpu_to_le16(0x0020) +#define TYPHOON_MEDIA_STAT_POLARITY_REV __constant_cpu_to_le16(0x0400) +#define TYPHOON_MEDIA_STAT_NO_LINK __constant_cpu_to_le16(0x0800) + +/* TYPHOON_CMD_SET_MULTICAST_HASH enable values (cmd.parm1) + */ +#define TYPHOON_MCAST_HASH_DISABLE __constant_cpu_to_le16(0x0000) +#define TYPHOON_MCAST_HASH_ENABLE __constant_cpu_to_le16(0x0001) +#define TYPHOON_MCAST_HASH_SET __constant_cpu_to_le16(0x0002) + +/* TYPHOON_CMD_CREATE_SA descriptor and settings + */ +struct sa_descriptor { + u8 flags; + u8 numDesc; + u16 cmd; + u16 seqNo; + u16 mode; +#define TYPHOON_SA_MODE_NULL __constant_cpu_to_le16(0x0000) +#define TYPHOON_SA_MODE_AH __constant_cpu_to_le16(0x0001) +#define TYPHOON_SA_MODE_ESP __constant_cpu_to_le16(0x0002) + u8 hashFlags; +#define TYPHOON_SA_HASH_ENABLE 0x01 +#define TYPHOON_SA_HASH_SHA1 0x02 +#define TYPHOON_SA_HASH_MD5 0x04 + u8 direction; +#define TYPHOON_SA_DIR_RX 0x00 +#define TYPHOON_SA_DIR_TX 0x01 + u8 encryptionFlags; +#define TYPHOON_SA_ENCRYPT_ENABLE 0x01 +#define TYPHOON_SA_ENCRYPT_DES 0x02 +#define TYPHOON_SA_ENCRYPT_3DES 0x00 +#define TYPHOON_SA_ENCRYPT_3DES_2KEY 0x00 +#define TYPHOON_SA_ENCRYPT_3DES_3KEY 0x04 +#define TYPHOON_SA_ENCRYPT_CBC 0x08 +#define TYPHOON_SA_ENCRYPT_ECB 0x00 + u8 specifyIndex; +#define TYPHOON_SA_SPECIFY_INDEX 0x01 +#define TYPHOON_SA_GENERATE_INDEX 0x00 + u32 SPI; + u32 destAddr; + u32 destMask; + u8 integKey[20]; + u8 confKey[24]; + u32 index; + u32 unused; + u32 unused2; +} __attribute__ ((packed)); + +/* TYPHOON_CMD_SET_OFFLOAD_TASKS bits (cmd.parm2 (Tx) & cmd.parm3 (Rx)) + * This is all for IPv4. + */ +#define TYPHOON_OFFLOAD_TCP_CHKSUM __constant_cpu_to_le32(0x00000002) +#define TYPHOON_OFFLOAD_UDP_CHKSUM __constant_cpu_to_le32(0x00000004) +#define TYPHOON_OFFLOAD_IP_CHKSUM __constant_cpu_to_le32(0x00000008) +#define TYPHOON_OFFLOAD_IPSEC __constant_cpu_to_le32(0x00000010) +#define TYPHOON_OFFLOAD_BCAST_THROTTLE __constant_cpu_to_le32(0x00000020) +#define TYPHOON_OFFLOAD_DHCP_PREVENT __constant_cpu_to_le32(0x00000040) +#define TYPHOON_OFFLOAD_VLAN __constant_cpu_to_le32(0x00000080) +#define TYPHOON_OFFLOAD_FILTERING __constant_cpu_to_le32(0x00000100) +#define TYPHOON_OFFLOAD_TCP_SEGMENT __constant_cpu_to_le32(0x00000200) + +/* TYPHOON_CMD_ENABLE_WAKE_EVENTS bits (cmd.parm1) + */ +#define TYPHOON_WAKE_MAGIC_PKT __constant_cpu_to_le16(0x01) +#define TYPHOON_WAKE_LINK_EVENT __constant_cpu_to_le16(0x02) +#define TYPHOON_WAKE_ICMP_ECHO __constant_cpu_to_le16(0x04) +#define TYPHOON_WAKE_ARP __constant_cpu_to_le16(0x08) + +/* These are used to load the firmware image on the NIC + */ +struct typhoon_file_header { + u8 tag[8]; + u32 version; + u32 numSections; + u32 startAddr; +} __attribute__ ((packed)); + +struct typhoon_section_header { + u32 len; + u16 checksum; + u16 reserved; + u32 startAddr; +} __attribute__ ((packed)); + +/* The Typhoon Register offsets + */ +#define TYPHOON_REG_SOFT_RESET 0x00 +#define TYPHOON_REG_INTR_STATUS 0x04 +#define TYPHOON_REG_INTR_ENABLE 0x08 +#define TYPHOON_REG_INTR_MASK 0x0c +#define TYPHOON_REG_SELF_INTERRUPT 0x10 +#define TYPHOON_REG_HOST2ARM7 0x14 +#define TYPHOON_REG_HOST2ARM6 0x18 +#define TYPHOON_REG_HOST2ARM5 0x1c +#define TYPHOON_REG_HOST2ARM4 0x20 +#define TYPHOON_REG_HOST2ARM3 0x24 +#define TYPHOON_REG_HOST2ARM2 0x28 +#define TYPHOON_REG_HOST2ARM1 0x2c +#define TYPHOON_REG_HOST2ARM0 0x30 +#define TYPHOON_REG_ARM2HOST3 0x34 +#define TYPHOON_REG_ARM2HOST2 0x38 +#define TYPHOON_REG_ARM2HOST1 0x3c +#define TYPHOON_REG_ARM2HOST0 0x40 + +#define TYPHOON_REG_BOOT_DATA_LO TYPHOON_REG_HOST2ARM5 +#define TYPHOON_REG_BOOT_DATA_HI TYPHOON_REG_HOST2ARM4 +#define TYPHOON_REG_BOOT_DEST_ADDR TYPHOON_REG_HOST2ARM3 +#define TYPHOON_REG_BOOT_CHECKSUM TYPHOON_REG_HOST2ARM2 +#define TYPHOON_REG_BOOT_LENGTH TYPHOON_REG_HOST2ARM1 + +#define TYPHOON_REG_DOWNLOAD_BOOT_ADDR TYPHOON_REG_HOST2ARM1 + +#define TYPHOON_REG_BOOT_RECORD_ADDR_HI TYPHOON_REG_HOST2ARM2 +#define TYPHOON_REG_BOOT_RECORD_ADDR_LO TYPHOON_REG_HOST2ARM1 + +#define TYPHOON_REG_TX_LO_READY TYPHOON_REG_HOST2ARM3 +#define TYPHOON_REG_CMD_READY TYPHOON_REG_HOST2ARM2 +#define TYPHOON_REG_TX_HI_READY TYPHOON_REG_HOST2ARM1 + +#define TYPHOON_REG_COMMAND TYPHOON_REG_HOST2ARM0 +#define TYPHOON_REG_HEARTBEAT TYPHOON_REG_ARM2HOST3 +#define TYPHOON_REG_STATUS TYPHOON_REG_ARM2HOST0 + +/* 3XP Reset values (TYPHOON_REG_SOFT_RESET) + */ +#define TYPHOON_RESET_ALL 0x7f +#define TYPHOON_RESET_NONE 0x00 + +/* 3XP irq bits (TYPHOON_REG_INTR{STATUS,ENABLE,MASK}) + * + * Some of these came from OpenBSD, as the 3Com docs have it wrong + * (INTR_SELF) or don't list it at all (INTR_*_ABORT) + * + * Enabling irqs on the Heartbeat reg (ArmToHost3) gets you an irq + * about every 8ms, so don't do it. + */ +#define TYPHOON_INTR_HOST_INT 0x00000001 +#define TYPHOON_INTR_ARM2HOST0 0x00000002 +#define TYPHOON_INTR_ARM2HOST1 0x00000004 +#define TYPHOON_INTR_ARM2HOST2 0x00000008 +#define TYPHOON_INTR_ARM2HOST3 0x00000010 +#define TYPHOON_INTR_DMA0 0x00000020 +#define TYPHOON_INTR_DMA1 0x00000040 +#define TYPHOON_INTR_DMA2 0x00000080 +#define TYPHOON_INTR_DMA3 0x00000100 +#define TYPHOON_INTR_MASTER_ABORT 0x00000200 +#define TYPHOON_INTR_TARGET_ABORT 0x00000400 +#define TYPHOON_INTR_SELF 0x00000800 +#define TYPHOON_INTR_RESERVED 0xfffff000 + +#define TYPHOON_INTR_BOOTCMD TYPHOON_INTR_ARM2HOST0 + +#define TYPHOON_INTR_ENABLE_ALL 0xffffffef +#define TYPHOON_INTR_ALL 0xffffffff +#define TYPHOON_INTR_NONE 0x00000000 + +/* The commands for the 3XP chip (TYPHOON_REG_COMMAND) + */ +#define TYPHOON_BOOTCMD_BOOT 0x00 +#define TYPHOON_BOOTCMD_WAKEUP 0xfa +#define TYPHOON_BOOTCMD_DNLD_COMPLETE 0xfb +#define TYPHOON_BOOTCMD_SEG_AVAILABLE 0xfc +#define TYPHOON_BOOTCMD_RUNTIME_IMAGE 0xfd +#define TYPHOON_BOOTCMD_REG_BOOT_RECORD 0xff + +/* 3XP Status values (TYPHOON_REG_STATUS) + */ +#define TYPHOON_STATUS_WAITING_FOR_BOOT 0x07 +#define TYPHOON_STATUS_SECOND_INIT 0x08 +#define TYPHOON_STATUS_RUNNING 0x09 +#define TYPHOON_STATUS_WAITING_FOR_HOST 0x0d +#define TYPHOON_STATUS_WAITING_FOR_SEGMENT 0x10 +#define TYPHOON_STATUS_SLEEPING 0x11 +#define TYPHOON_STATUS_HALTED 0x14 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/via-rhine.c linux.21pre4-ac6/drivers/net/via-rhine.c --- linux.21pre4/drivers/net/via-rhine.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/via-rhine.c 2003-01-12 00:33:19.000000000 +0000 @@ -1239,6 +1239,12 @@ /* Calculate the next Tx descriptor entry. */ entry = np->cur_tx % TX_RING_SIZE; + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + np->tx_skbuff[entry] = skb; if ((np->drv_flags & ReqTxAlign) && diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/8253x/8253xtty.c linux.21pre4-ac6/drivers/net/wan/8253x/8253xtty.c --- linux.21pre4/drivers/net/wan/8253x/8253xtty.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/8253x/8253xtty.c 2003-02-11 18:04:34.000000000 +0000 @@ -2131,7 +2131,7 @@ /* Check whether or not the port is open in SYNC mode */ if(port->open_type == OPEN_SYNC_NET) { - if(port->dev && netif_carrier_ok(port->dev)); + if(port->dev && netif_carrier_ok(port->dev)) { port->tty= NULL; /* Don't bother with open counting here but make sure the tty field is NULL*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/c101.c linux.21pre4-ac6/drivers/net/wan/c101.c --- linux.21pre4/drivers/net/wan/c101.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/c101.c 2003-01-28 16:39:15.000000000 +0000 @@ -1,12 +1,11 @@ /* * Moxa C101 synchronous serial card driver for Linux * - * Copyright (C) 2000-2002 Krzysztof Halasa + * Copyright (C) 2000-2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * * For information see http://hq.pm.waw.pl/hdlc/ * @@ -31,7 +30,7 @@ #include "hd64570.h" -static const char* version = "Moxa C101 driver version: 1.10"; +static const char* version = "Moxa C101 driver version: 1.12"; static const char* devname = "C101"; #define C101_PAGE 0x1D00 @@ -78,7 +77,12 @@ #define sca_in(reg, card) readb((card)->win0base + C101_SCA + (reg)) #define sca_out(value, reg, card) writeb(value, (card)->win0base + C101_SCA + (reg)) #define sca_inw(reg, card) readw((card)->win0base + C101_SCA + (reg)) -#define sca_outw(value, reg, card) writew(value, (card)->win0base + C101_SCA + (reg)) + +/* EDA address register must be set in EDAL, EDAH order - 8 bit ISA bus */ +#define sca_outw(value, reg, card) do { \ + writeb(value & 0xFF, (card)->win0base + C101_SCA + (reg)); \ + writeb((value >> 8 ) & 0xFF, (card)->win0base + C101_SCA + (reg+1));\ +} while(0) #define port_to_card(port) (port) #define log_node(port) (0) @@ -352,7 +356,7 @@ c101_run(irq, ram); if (*hw == '\x0') - return 0; + return first_card ? 0 : -ENOSYS; }while(*hw++ == ':'); printk(KERN_ERR "c101: invalid hardware parameters\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/comx-hw-mixcom.c linux.21pre4-ac6/drivers/net/wan/comx-hw-mixcom.c --- linux.21pre4/drivers/net/wan/comx-hw-mixcom.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/comx-hw-mixcom.c 2003-02-06 22:45:26.000000000 +0000 @@ -102,7 +102,7 @@ unsigned char cec; unsigned delay = 0; - while ((cec = (rd_hscx(dev, HSCX_STAR) & HSCX_CEC) != 0) && + while ((cec = (rd_hscx(dev, HSCX_STAR) & HSCX_CEC)) != 0 && (jiffs + HZ > jiffies)) { udelay(1); if (++delay > (100000 / HZ)) break; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/comx-hw-munich.c linux.21pre4-ac6/drivers/net/wan/comx-hw-munich.c --- linux.21pre4/drivers/net/wan/comx-hw-munich.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/comx-hw-munich.c 2003-02-06 16:04:53.000000000 +0000 @@ -269,7 +269,7 @@ - Path Code Violations >1, but <320 - not a Severely Errored Second - no AIS - - not incremented during an Unavailabla Second */ + - not incremented during an Unavailable Second */ severely_err_secs, /* Severely Errored Second: - CRC4: >=832 Path COde Violations || >0 Out Of Frame defects - noCRC4: >=2048 Line Code Violations diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/Config.in linux.21pre4-ac6/drivers/net/wan/Config.in --- linux.21pre4/drivers/net/wan/Config.in 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/Config.in 2003-01-28 16:39:15.000000000 +0000 @@ -68,6 +68,7 @@ tristate ' Generic HDLC layer' CONFIG_HDLC if [ "$CONFIG_HDLC" != "n" ]; then bool ' Raw HDLC support' CONFIG_HDLC_RAW + bool ' Raw HDLC Ethernet device support' CONFIG_HDLC_RAW_ETH bool ' Cisco HDLC support' CONFIG_HDLC_CISCO bool ' Frame Relay support' CONFIG_HDLC_FR bool ' Synchronous Point-to-Point Protocol (PPP) support' CONFIG_HDLC_PPP diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/dscc4.c linux.21pre4-ac6/drivers/net/wan/dscc4.c --- linux.21pre4/drivers/net/wan/dscc4.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/dscc4.c 2003-02-19 16:16:43.000000000 +0000 @@ -487,9 +487,9 @@ skb = dev_alloc_skb(len); dpriv->rx_skbuff[dirty] = skb; if (skb) { - skb->dev = dev; - skb->protocol = htons(ETH_P_HDLC); - skb->mac.raw = skb->data; + skb->dev = dev; + skb->protocol = hdlc_type_trans(skb, dev); + skb->mac.raw = skb->data; rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, len, PCI_DMA_FROMDEVICE); } else { @@ -1757,7 +1757,7 @@ (++i%TX_RING_SIZE)*sizeof(*tx_fd)); } while (i < TX_RING_SIZE); - if (dscc4_init_dummy_skb(dpriv) < 0) + if (dscc4_init_dummy_skb(dpriv) == NULL) goto err_free_dma_tx; memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/farsync.c linux.21pre4-ac6/drivers/net/wan/farsync.c --- linux.21pre4/drivers/net/wan/farsync.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/farsync.c 2003-01-28 16:39:15.000000000 +0000 @@ -764,7 +764,7 @@ /* Push upstream */ skb->mac.raw = skb->data; skb->dev = hdlc_to_dev ( &port->hdlc ); - skb->protocol = htons ( ETH_P_HDLC ); + skb->protocol = hdlc_type_trans(skb, skb->dev); netif_rx ( skb ); port_to_dev ( port )->last_rx = jiffies; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hd6457x.c linux.21pre4-ac6/drivers/net/wan/hd6457x.c --- linux.21pre4/drivers/net/wan/hd6457x.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hd6457x.c 2003-01-28 16:39:15.000000000 +0000 @@ -1,12 +1,11 @@ /* * Hitachi SCA HD64570 and HD64572 common driver for Linux * - * Copyright (C) 1998-2000 Krzysztof Halasa + * Copyright (C) 1998-2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * * Sources of information: * Hitachi HD64570 SCA User's Manual @@ -42,7 +41,7 @@ #error Either hd64570.h or hd64572.h must be included #endif -static char sca_version[]="1.09"; +static char sca_version[]="1.12"; #define get_msci(port) (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET) @@ -294,7 +293,7 @@ skb->mac.raw = skb->data; skb->dev = hdlc_to_dev(&port->hdlc); skb->dev->last_rx = jiffies; - skb->protocol = htons(ETH_P_HDLC); + skb->protocol = hdlc_type_trans(skb, hdlc_to_dev(&port->hdlc)); netif_rx(skb); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_cisco.c linux.21pre4-ac6/drivers/net/wan/hdlc_cisco.c --- linux.21pre4/drivers/net/wan/hdlc_cisco.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_cisco.c 2003-01-28 16:39:15.000000000 +0000 @@ -2,12 +2,11 @@ * Generic HDLC support routines for Linux * Cisco HDLC support * - * Copyright (C) 2000 - 2001 Krzysztof Halasa + * Copyright (C) 2000 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ #include @@ -85,12 +84,37 @@ skb_put(skb, sizeof(cisco_packet)); skb->priority = TC_PRIO_CONTROL; skb->dev = hdlc_to_dev(hdlc); + skb->nh.raw = skb->data; dev_queue_xmit(skb); } +static unsigned short cisco_type_trans(struct sk_buff *skb, + struct net_device *dev) +{ + hdlc_header *data = (hdlc_header*)skb->data; + + if (skb->len < sizeof(hdlc_header)) + return __constant_htons(ETH_P_HDLC); + + if (data->address != CISCO_MULTICAST && + data->address != CISCO_UNICAST) + return __constant_htons(ETH_P_HDLC); + + switch(data->protocol) { + case __constant_htons(ETH_P_IP): + case __constant_htons(ETH_P_IPX): + case __constant_htons(ETH_P_IPV6): + skb_pull(skb, sizeof(hdlc_header)); + return data->protocol; + default: + return __constant_htons(ETH_P_HDLC); + } +} + + static void cisco_rx(struct sk_buff *skb) { hdlc_device *hdlc = dev_to_hdlc(skb->dev); @@ -109,14 +133,6 @@ skb_pull(skb, sizeof(hdlc_header)); switch(ntohs(data->protocol)) { - case ETH_P_IP: - case ETH_P_IPX: - case ETH_P_IPV6: - skb->protocol = data->protocol; - skb->dev = hdlc_to_dev(hdlc); - netif_rx(skb); - return; - case CISCO_SYS_INFO: /* Packet is not needed, drop it. */ dev_kfree_skb_any(skb); @@ -288,6 +304,7 @@ hdlc->open = cisco_open; hdlc->stop = cisco_close; hdlc->netif_rx = cisco_rx; + hdlc->type_trans = cisco_type_trans; hdlc->proto = IF_PROTO_CISCO; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = cisco_hard_header; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_fr.c linux.21pre4-ac6/drivers/net/wan/hdlc_fr.c --- linux.21pre4/drivers/net/wan/hdlc_fr.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_fr.c 2003-01-28 16:39:15.000000000 +0000 @@ -2,13 +2,22 @@ * Generic HDLC support routines for Linux * Frame Relay support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + + Theory of PVC state in DCE mode: + + (exist,new) -> 0,0 when "PVC create" or if "link unreliable" + 0,x -> 1,1 if "link reliable" when sending FULL STATUS + 1,1 -> 1,0 if received FULL STATUS ACK + + (active) -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create" + -> 1 when "PVC up" and (exist,new) = 1,0 +*/ #include #include @@ -20,19 +29,23 @@ #include #include #include +#include #include #include #include +#include #include __inline__ pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) { - pvc_device *pvc=hdlc->state.fr.first_pvc; + pvc_device *pvc = hdlc->state.fr.first_pvc; - while (pvc) { - if (netdev_dlci(&pvc->netdev) == dlci) + while(pvc) { + if (pvc->dlci == dlci) return pvc; + if (pvc->dlci > dlci) + return NULL; /* the listed is sorted */ pvc = pvc->next; } @@ -40,18 +53,72 @@ } +__inline__ pvc_device* add_pvc(hdlc_device *hdlc, u16 dlci) +{ + pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; + + while(*pvc_p) { + if ((*pvc_p)->dlci == dlci) + return *pvc_p; + if ((*pvc_p)->dlci > dlci) + break; /* the listed is sorted */ + pvc_p = &(*pvc_p)->next; + } + + pvc = kmalloc(sizeof(pvc_device), GFP_KERNEL); + if (!pvc) + return NULL; + + memset(pvc, 0, sizeof(pvc_device)); + pvc->dlci = dlci; + pvc->master = hdlc; + pvc->next = *pvc_p; /* Put it in the chain */ + *pvc_p = pvc; + return pvc; +} + + +__inline__ int pvc_is_used(pvc_device *pvc) +{ + return pvc->main != NULL || pvc->ether != NULL; +} + + +__inline__ void delete_unused_pvcs(hdlc_device *hdlc) +{ + pvc_device **pvc_p = &hdlc->state.fr.first_pvc; + + while(*pvc_p) { + if (!pvc_is_used(*pvc_p)) { + pvc_device *pvc = *pvc_p; + *pvc_p = pvc->next; + kfree(pvc); + continue; + } + pvc_p = &(*pvc_p)->next; + } +} + -__inline__ u16 status_to_dlci(hdlc_device *hdlc, u8 *status, - int *active, int *new) +__inline__ struct net_device** get_dev_p(pvc_device *pvc, int type) { - *new = (status[2] & 0x08); - *active = (!*new && (status[2] & 0x02)); + if (type == ARPHRD_ETHER) + return &pvc->ether; + else + return &pvc->main; +} + + +__inline__ u16 status_to_dlci(u8 *status, int *active, int *new) +{ + *new = (status[2] & 0x08) ? 1 : 0; + *active = (status[2] & 0x02) ? 1 : 0; return ((status[0] & 0x3F)<<4) | ((status[1] & 0x78)>>3); } -__inline__ void dlci_to_status(hdlc_device *hdlc, u16 dlci, u8 *status, +__inline__ void dlci_to_status(u16 dlci, u8 *status, int active, int new) { status[0] = (dlci>>4) & 0x3F; @@ -66,37 +133,50 @@ -static int fr_hard_header(struct sk_buff *skb, struct net_device *dev, - u16 type, void *daddr, void *saddr, unsigned int len) +static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) { u16 head_len; + struct sk_buff *skb = *skb_p; - if (!daddr) - daddr = dev->broadcast; - -#ifdef CONFIG_HDLC_DEBUG_HARD_HEADER - printk(KERN_DEBUG "%s: fr_hard_header called\n", dev->name); -#endif - - switch(type) { - case ETH_P_IP: + switch(skb->protocol) { + case __constant_ntohs(ETH_P_IP): head_len = 4; skb_push(skb, head_len); skb->data[3] = NLPID_IP; break; - case ETH_P_IPV6: + case __constant_ntohs(ETH_P_IPV6): head_len = 4; skb_push(skb, head_len); skb->data[3] = NLPID_IPV6; break; - case LMI_PROTO: + case __constant_ntohs(LMI_PROTO): head_len = 4; skb_push(skb, head_len); skb->data[3] = LMI_PROTO; break; + case __constant_ntohs(ETH_P_802_3): + head_len = 10; + if (skb_headroom(skb) < head_len) { + struct sk_buff *skb2 = skb_realloc_headroom(skb, + head_len); + if (!skb2) + return -ENOBUFS; + dev_kfree_skb(skb); + skb = *skb_p = skb2; + } + skb_push(skb, head_len); + skb->data[3] = FR_PAD; + skb->data[4] = NLPID_SNAP; + skb->data[5] = FR_PAD; + skb->data[6] = 0x80; + skb->data[7] = 0xC2; + skb->data[8] = 0x00; + skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */ + break; + default: head_len = 10; skb_push(skb, head_len); @@ -105,14 +185,12 @@ skb->data[5] = FR_PAD; skb->data[6] = FR_PAD; skb->data[7] = FR_PAD; - skb->data[8] = type>>8; - skb->data[9] = (u8)type; + *(u16*)(skb->data + 8) = skb->protocol; } - memcpy(skb->data, daddr, 2); + dlci_to_q922(skb->data, dlci); skb->data[2] = FR_UI; - - return head_len; + return 0; } @@ -124,13 +202,12 @@ if ((hdlc_to_dev(pvc->master)->flags & IFF_UP) == 0) return -EIO; /* Master must be UP in order to activate PVC */ - if (pvc->master->state.fr.settings.lmi != LMI_NONE) - pvc->state.active = 0; - else - pvc->state.active = 1; + if (pvc->open_count++ == 0) { + if (pvc->master->state.fr.settings.lmi == LMI_NONE) + pvc->state.active = 1; - pvc->state.new = 0; - pvc->master->state.fr.changed = 1; + pvc->master->state.fr.dce_changed = 1; + } return 0; } @@ -139,38 +216,94 @@ static int pvc_close(struct net_device *dev) { pvc_device *pvc = dev_to_pvc(dev); - pvc->state.active = pvc->state.new = 0; - pvc->master->state.fr.changed = 1; + + if (--pvc->open_count == 0) { + if (pvc->master->state.fr.settings.lmi == LMI_NONE) + pvc->state.active = 0; + + if (pvc->master->state.fr.settings.dce) { + pvc->master->state.fr.dce_changed = 1; + pvc->state.active = 0; + } + } return 0; } -static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) +int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { pvc_device *pvc = dev_to_pvc(dev); + fr_proto_pvc_info info; - if (pvc->state.active) { - skb->dev = hdlc_to_dev(pvc->master); - pvc->stats.tx_bytes += skb->len; - pvc->stats.tx_packets++; - if (pvc->state.fecn) - pvc->stats.tx_compressed++; /* TX Congestion counter */ - dev_queue_xmit(skb); - } else { - pvc->stats.tx_dropped++; - dev_kfree_skb(skb); + if (ifr->ifr_settings.type == IF_GET_PROTO) { + if (dev->type == ARPHRD_ETHER) + ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC; + else + ifr->ifr_settings.type = IF_PROTO_FR_PVC; + + if (ifr->ifr_settings.size < sizeof(info)) { + /* data size wanted */ + ifr->ifr_settings.size = sizeof(info); + return -ENOBUFS; + } + + info.dlci = pvc->dlci; + memcpy(info.master, hdlc_to_name(pvc->master), IFNAMSIZ); + if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, + &info, sizeof(info))) + return -EFAULT; + return 0; } - return 0; + return -EINVAL; +} + + +__inline__ struct net_device_stats *pvc_get_stats(struct net_device *dev) +{ + return (struct net_device_stats *) + ((char *)dev + sizeof(struct net_device)); } -static struct net_device_stats *pvc_get_stats(struct net_device *dev) +static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) { pvc_device *pvc = dev_to_pvc(dev); - return &pvc->stats; + struct net_device_stats *stats = pvc_get_stats(dev); + + if (pvc->state.active) { + if (dev->type == ARPHRD_ETHER) { + int pad = ETH_ZLEN - skb->len; + if (pad > 0) { /* Pad the frame with zeros */ + int len = skb->len; + if (skb_tailroom(skb) < pad) + if (pskb_expand_head(skb, 0, pad, + GFP_ATOMIC)) { + stats->tx_dropped++; + dev_kfree_skb(skb); + return 0; + } + skb_put(skb, pad); + memset(skb->data + len, 0, pad); + } + skb->protocol = __constant_htons(ETH_P_802_3); + } + if (!fr_hard_header(&skb, pvc->dlci)) { + stats->tx_bytes += skb->len; + stats->tx_packets++; + if (pvc->state.fecn) /* TX Congestion counter */ + stats->tx_compressed++; + skb->dev = hdlc_to_dev(pvc->master); + dev_queue_xmit(skb); + return 0; + } + } + + stats->tx_dropped++; + dev_kfree_skb(skb); + return 0; } @@ -187,9 +320,15 @@ static inline void fr_log_dlci_active(pvc_device *pvc) { - printk(KERN_INFO "%s: %sactive%s\n", pvc_to_name(pvc), - pvc->state.active ? "" : "in", - pvc->state.new ? " new" : ""); + printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", + hdlc_to_name(pvc->master), + pvc->dlci, + pvc->main ? pvc->main->name : "", + pvc->main && pvc->ether ? " " : "", + pvc->ether ? pvc->ether->name : "", + pvc->state.new ? " new" : "", + !pvc->state.exist ? "deleted" : + pvc->state.active ? "active" : "inactive"); } @@ -213,8 +352,8 @@ int i = 0; if (hdlc->state.fr.settings.dce && fullrep) { - len += hdlc->state.fr.pvc_count * (2 + stat_len); - if (len > HDLC_MAX_MTU) { + len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); + if (len > HDLC_MAX_MRU) { printk(KERN_WARNING "%s: Too many PVCs while sending " "LMI full report\n", hdlc_to_name(hdlc)); return; @@ -224,12 +363,13 @@ skb = dev_alloc_skb(len); if (!skb) { printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n", - hdlc_to_name(hdlc)); + hdlc_to_name(hdlc)); return; } memset(skb->data, 0, len); skb_reserve(skb, 4); - fr_hard_header(skb, hdlc_to_dev(hdlc), LMI_PROTO, NULL, NULL, 0); + skb->protocol = __constant_htons(LMI_PROTO); + fr_hard_header(&skb, LMI_DLCI); data = skb->tail; data[i++] = LMI_CALLREF; data[i++] = hdlc->state.fr.settings.dce @@ -253,16 +393,20 @@ ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT; data[i++] = stat_len; - if (hdlc->state.fr.reliable && - (pvc->netdev.flags & IFF_UP) && - !pvc->state.active && - !pvc->state.new) { - pvc->state.new = 1; + /* LMI start/restart */ + if (hdlc->state.fr.reliable && !pvc->state.exist) { + pvc->state.exist = pvc->state.new = 1; + fr_log_dlci_active(pvc); + } + + /* ifconfig PVC up */ + if (pvc->open_count && !pvc->state.active && + pvc->state.exist && !pvc->state.new) { + pvc->state.active = 1; fr_log_dlci_active(pvc); } - dlci_to_status(hdlc, netdev_dlci(&pvc->netdev), - data + i, + dlci_to_status(pvc->dlci, data + i, pvc->state.active, pvc->state.new); i += stat_len; pvc = pvc->next; @@ -272,6 +416,7 @@ skb_put(skb, i); skb->priority = TC_PRIO_CONTROL; skb->dev = hdlc_to_dev(hdlc); + skb->nh.raw = skb->data; dev_queue_xmit(skb); } @@ -312,10 +457,11 @@ if (reliable) { hdlc->state.fr.n391cnt = 0; /* Request full status */ - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_changed = 1; } else { while (pvc) { /* Deactivate all PVCs */ - pvc->state.new = pvc->state.active = 0; + pvc->state.exist = 0; + pvc->state.active = pvc->state.new = 0; pvc = pvc->next; } } @@ -346,7 +492,7 @@ { int stat_len; pvc_device *pvc; - int reptype = -1, error; + int reptype = -1, error, no_ram; u8 rxseq, txseq; int i; @@ -420,20 +566,18 @@ while (pvc) { if (pvc->state.new) { pvc->state.new = 0; - pvc->state.active = 1; - fr_log_dlci_active(pvc); /* Tell DTE that new PVC is now active */ - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_changed = 1; } pvc = pvc->next; } } - if (hdlc->state.fr.changed) { + if (hdlc->state.fr.dce_changed) { reptype = LMI_FULLREP; hdlc->state.fr.fullrep_sent = 1; - hdlc->state.fr.changed = 0; + hdlc->state.fr.dce_changed = 0; } fr_lmi_send(hdlc, reptype == LMI_FULLREP ? 1 : 0); @@ -449,13 +593,14 @@ pvc = hdlc->state.fr.first_pvc; while (pvc) { - pvc->state.deleted = pvc->state.active; /* mark active PVCs */ + pvc->state.deleted = 1; pvc = pvc->next; } + no_ram = 0; while (skb->len >= i + 2 + stat_len) { u16 dlci; - int active, new; + unsigned int active, new; if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT) ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) { @@ -472,21 +617,28 @@ } i++; - dlci = status_to_dlci(hdlc, skb->data + i, &active, &new); - pvc = find_pvc(hdlc, dlci); + dlci = status_to_dlci(skb->data + i, &active, &new); + + pvc = add_pvc(hdlc, dlci); + + if (!pvc && !no_ram) { + printk(KERN_WARNING + "%s: Memory squeeze on fr_lmi_recv()\n", + hdlc_to_name(hdlc)); + no_ram = 1; + } - active |= new; if (pvc) { - if (active && !pvc->state.active && - (pvc->netdev.flags & IFF_UP)) { + pvc->state.exist = 1; + pvc->state.deleted = 0; + if (active != pvc->state.active || + new != pvc->state.new || + !pvc->state.exist) { + pvc->state.new = new; pvc->state.active = active; fr_log_dlci_active(pvc); } - pvc->state.deleted = 0; } - else if (new) - printk(KERN_INFO "%s: new PVC available, DLCI=%u\n", - hdlc_to_name(hdlc), dlci); i += stat_len; } @@ -494,10 +646,10 @@ pvc = hdlc->state.fr.first_pvc; while (pvc) { - if (pvc->state.deleted) { + if (pvc->state.deleted && pvc->state.exist) { pvc->state.active = pvc->state.new = 0; + pvc->state.exist = 0; fr_log_dlci_active(pvc); - pvc->state.deleted = 0; } pvc = pvc->next; } @@ -517,8 +669,9 @@ u8 *data = skb->data; u16 dlci; pvc_device *pvc; + struct net_device *dev = NULL; - if (skb->len<4 || fh->ea1 || data[2] != FR_UI) + if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI) goto rx_error; dlci = q922_to_dlci(skb->data); @@ -550,57 +703,39 @@ printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", hdlc_to_name(hdlc), dlci); #endif - goto rx_error; - } - - if ((pvc->netdev.flags & IFF_UP) == 0) { -#ifdef CONFIG_HDLC_DEBUG_PKT - printk(KERN_INFO "%s: PVC for received frame's DLCI %d is down\n", - hdlc_to_name(hdlc), dlci); -#endif - goto rx_error; + dev_kfree_skb_any(skb); + return; } - pvc->stats.rx_packets++; /* PVC traffic */ - pvc->stats.rx_bytes += skb->len; - - if (pvc->state.fecn != (fh->fecn ? PVC_STATE_FECN : 0)) { + if (pvc->state.fecn != fh->fecn) { #ifdef CONFIG_HDLC_DEBUG_ECN - printk(KERN_DEBUG "%s: FECN O%s\n", pvc_to_name(pvc), - fh->fecn ? "N" : "FF"); + printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", hdlc_to_name(pvc), + dlci, fh->fecn ? "N" : "FF"); #endif pvc->state.fecn ^= 1; } - if (pvc->state.becn != (fh->becn ? PVC_STATE_BECN : 0)) { + if (pvc->state.becn != fh->becn) { #ifdef CONFIG_HDLC_DEBUG_ECN - printk(KERN_DEBUG "%s: BECN O%s\n", pvc_to_name(pvc), - fh->becn ? "N" : "FF"); + printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", hdlc_to_name(pvc), + dlci, fh->becn ? "N" : "FF"); #endif pvc->state.becn ^= 1; } - if (pvc->state.becn) - pvc->stats.rx_compressed++; - - skb->dev = &pvc->netdev; if (data[3] == NLPID_IP) { skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */ + dev = pvc->main; skb->protocol = htons(ETH_P_IP); - netif_rx(skb); - return; - } - - if (data[3] == NLPID_IPV6) { + } else if (data[3] == NLPID_IPV6) { skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */ + dev = pvc->main; skb->protocol = htons(ETH_P_IPV6); - netif_rx(skb); - return; - } - if (data[3] == FR_PAD && data[4] == NLPID_SNAP && data[5] == FR_PAD) { + } else if (skb->len > 10 && data[3] == FR_PAD && + data[4] == NLPID_SNAP && data[5] == FR_PAD) { u16 oui = ntohs(*(u16*)(data + 6)); u16 pid = ntohs(*(u16*)(data + 8)); skb_pull(skb, 10); @@ -610,23 +745,39 @@ case ETH_P_IPX: case ETH_P_IP: /* a long variant */ case ETH_P_IPV6: + dev = pvc->main; skb->protocol = htons(pid); break; + case 0x80C20007: /* bridged Ethernet frame */ + if ((dev = pvc->ether) != NULL) + skb->protocol = eth_type_trans(skb, dev); + break; + default: printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " "PID=%x\n", hdlc_to_name(hdlc), oui, pid); dev_kfree_skb_any(skb); return; } - - netif_rx(skb); + } else { + printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " + "length = %i\n", hdlc_to_name(hdlc), data[3], skb->len); + dev_kfree_skb_any(skb); return; } - printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x\n", - hdlc_to_name(hdlc), data[3]); - dev_kfree_skb_any(skb); + if (dev) { + struct net_device_stats *stats = pvc_get_stats(dev); + stats->rx_packets++; /* PVC traffic */ + stats->rx_bytes += skb->len; + if (pvc->state.becn) + stats->rx_compressed++; + skb->dev = dev; + netif_rx(skb); + } else + dev_kfree_skb_any(skb); + return; rx_error: @@ -641,7 +792,7 @@ if (hdlc->state.fr.settings.lmi != LMI_NONE) { hdlc->state.fr.last_poll = 0; hdlc->state.fr.reliable = 0; - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_changed = 1; hdlc->state.fr.request = 0; hdlc->state.fr.fullrep_sent = 0; hdlc->state.fr.last_errors = 0xFFFFFFFF; @@ -669,90 +820,119 @@ if (hdlc->state.fr.settings.lmi != LMI_NONE) del_timer_sync(&hdlc->state.fr.timer); - while(pvc) { - dev_close(&pvc->netdev); /* Shutdown all PVCs for this FRAD */ + while(pvc) { /* Shutdown all PVCs for this FRAD */ + if (pvc->main) + dev_close(pvc->main); + if (pvc->ether) + dev_close(pvc->ether); + pvc->state.active = pvc->state.new = pvc->state.fecn = + pvc->state.becn = 0; + pvc->state.exist = 0; pvc = pvc->next; } } - -static int fr_pvc(hdlc_device *hdlc, unsigned int dlci, int create) +static int fr_add_pvc(hdlc_device *hdlc, unsigned int dlci, int type) { - pvc_device **pvc_p = &hdlc->state.fr.first_pvc; - pvc_device *pvc; - int result; + pvc_device *pvc = NULL; + struct net_device *dev; + int result, used; + char * prefix = "pvc%d"; - if(dlci <= 0 || dlci >= 1024) - return -EINVAL; /* Only 10 bits for DLCI, DLCI 0 reserved */ + if (type == ARPHRD_ETHER) + prefix = "pvceth%d"; - while(*pvc_p) { - if (netdev_dlci(&(*pvc_p)->netdev) == dlci) - break; - pvc_p = &(*pvc_p)->next; + if ((pvc = add_pvc(hdlc, dlci)) == NULL) { + printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", + hdlc_to_name(hdlc)); + return -ENOBUFS; } - if (create) { /* Create PVC */ - if (*pvc_p != NULL) - return -EEXIST; - - pvc = *pvc_p = kmalloc(sizeof(pvc_device), GFP_KERNEL); - if (!pvc) { - printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", - hdlc_to_name(hdlc)); - return -ENOBUFS; - } - memset(pvc, 0, sizeof(pvc_device)); + if (*get_dev_p(pvc, type)) + return -EEXIST; - pvc->netdev.hard_start_xmit = pvc_xmit; - pvc->netdev.get_stats = pvc_get_stats; - pvc->netdev.open = pvc_open; - pvc->netdev.stop = pvc_close; - pvc->netdev.change_mtu = pvc_change_mtu; - pvc->netdev.mtu = HDLC_MAX_MTU; - - pvc->netdev.type = ARPHRD_DLCI; - pvc->netdev.hard_header_len = 16; - pvc->netdev.hard_header = fr_hard_header; - pvc->netdev.tx_queue_len = 0; - pvc->netdev.flags = IFF_POINTOPOINT; - - pvc->master = hdlc; - *(u16*)pvc->netdev.dev_addr = htons(dlci); - dlci_to_q922(pvc->netdev.broadcast, dlci); - pvc->netdev.addr_len = 2; + used = pvc_is_used(pvc); - result = dev_alloc_name(&pvc->netdev, "pvc%d"); - if (result < 0) { - kfree(pvc); - *pvc_p = NULL; - return result; - } - - if (register_netdevice(&pvc->netdev) != 0) { - kfree(pvc); - *pvc_p = NULL; - return -EIO; - } + dev = kmalloc(sizeof(struct net_device) + + sizeof(struct net_device_stats), GFP_KERNEL); + if (!dev) { + printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", + hdlc_to_name(hdlc)); + delete_unused_pvcs(hdlc); + return -ENOBUFS; + } + memset(dev, 0, sizeof(struct net_device) + + sizeof(struct net_device_stats)); - hdlc->state.fr.changed = 1; - hdlc->state.fr.pvc_count++; - return 0; + if (type == ARPHRD_ETHER) { + ether_setup(dev); + memcpy(dev->dev_addr, "\x00\x01", 2); + get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); + } else { + dev->type = ARPHRD_DLCI; + dev->flags = IFF_POINTOPOINT; + dev->hard_header_len = 10; + dev->addr_len = 2; + *(u16*)dev->dev_addr = htons(dlci); + dlci_to_q922(dev->broadcast, dlci); + } + dev->hard_start_xmit = pvc_xmit; + dev->get_stats = pvc_get_stats; + dev->open = pvc_open; + dev->stop = pvc_close; + dev->do_ioctl = pvc_ioctl; + dev->change_mtu = pvc_change_mtu; + dev->mtu = HDLC_MAX_MTU; + dev->tx_queue_len = 0; + dev->priv = pvc; + + result = dev_alloc_name(dev, prefix); + if (result < 0) { + kfree(dev); + delete_unused_pvcs(hdlc); + return result; + } + + if (register_netdevice(dev) != 0) { + kfree(dev); + delete_unused_pvcs(hdlc); + return -EIO; + } + + *get_dev_p(pvc, type) = dev; + if (!used) { + hdlc->state.fr.dce_changed = 1; + hdlc->state.fr.dce_pvc_count++; } + return 0; +} + + - if (*pvc_p == NULL) /* Delete PVC */ +static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type) +{ + pvc_device *pvc; + struct net_device *dev; + + if ((pvc = find_pvc(hdlc, dlci)) == NULL) return -ENOENT; - pvc = *pvc_p; + if ((dev = *get_dev_p(pvc, type)) == NULL) + return -ENOENT; - if (pvc->netdev.flags & IFF_UP) + if (dev->flags & IFF_UP) return -EBUSY; /* PVC in use */ - hdlc->state.fr.changed = 1; - hdlc->state.fr.pvc_count--; - *pvc_p = pvc->next; - unregister_netdevice(&pvc->netdev); - kfree(pvc); + unregister_netdevice(dev); + kfree(dev); + *get_dev_p(pvc, type) = NULL; + + if (!pvc_is_used(pvc)) { + hdlc->state.fr.dce_pvc_count--; + hdlc->state.fr.dce_changed = 1; + } + delete_unused_pvcs(hdlc); return 0; } @@ -763,14 +943,21 @@ pvc_device *pvc = hdlc->state.fr.first_pvc; while(pvc) { pvc_device *next = pvc->next; - unregister_netdev(&pvc->netdev); + if (pvc->main) { + unregister_netdevice(pvc->main); + kfree(pvc->main); + } + if (pvc->ether) { + unregister_netdevice(pvc->ether); + kfree(pvc->ether); + } kfree(pvc); pvc = next; } hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ - hdlc->state.fr.pvc_count = 0; - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_pvc_count = 0; + hdlc->state.fr.dce_changed = 1; } @@ -828,25 +1015,27 @@ if (hdlc->proto != IF_PROTO_FR) { hdlc_proto_detach(hdlc); hdlc->state.fr.first_pvc = NULL; - hdlc->state.fr.pvc_count = 0; + hdlc->state.fr.dce_pvc_count = 0; } memcpy(&hdlc->state.fr.settings, &new_settings, size); hdlc->open = fr_open; hdlc->stop = fr_close; hdlc->netif_rx = fr_rx; + hdlc->type_trans = NULL; hdlc->proto_detach = fr_destroy; hdlc->proto = IF_PROTO_FR; dev->hard_start_xmit = hdlc->xmit; - dev->hard_header = fr_hard_header; + dev->hard_header = NULL; dev->type = ARPHRD_FRAD; - dev->addr_len = 2; - *(u16*)dev->dev_addr = htons(LMI_DLCI); - dlci_to_q922(dev->broadcast, LMI_DLCI); + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->addr_len = 0; return 0; case IF_PROTO_FR_ADD_PVC: case IF_PROTO_FR_DEL_PVC: + case IF_PROTO_FR_ADD_ETH_PVC: + case IF_PROTO_FR_DEL_ETH_PVC: if(!capable(CAP_NET_ADMIN)) return -EPERM; @@ -854,8 +1043,20 @@ sizeof(fr_proto_pvc))) return -EFAULT; - return fr_pvc(hdlc, pvc.dlci, - ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC); + if (pvc.dlci <= 0 || pvc.dlci >= 1024) + return -EINVAL; /* Only 10 bits, DLCI 0 reserved */ + + if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC || + ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC) + result = ARPHRD_ETHER; /* bridged Ethernet device */ + else + result = ARPHRD_DLCI; + + if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC || + ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC) + return fr_add_pvc(hdlc, pvc.dlci, result); + else + return fr_del_pvc(hdlc, pvc.dlci, result); } return -EINVAL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_generic.c linux.21pre4-ac6/drivers/net/wan/hdlc_generic.c --- linux.21pre4/drivers/net/wan/hdlc_generic.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_generic.c 2003-01-28 16:39:15.000000000 +0000 @@ -1,17 +1,13 @@ /* * Generic HDLC support routines for Linux * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * - * Current status: - * - this is work in progress - * - not heavily tested on SMP - * - currently supported: + * Currently supported: * * raw IP-in-HDLC * * Cisco HDLC * * Frame Relay with ANSI or CCITT LMI (both user and network side) @@ -37,7 +33,7 @@ #include -static const char* version = "HDLC support module revision 1.11"; +static const char* version = "HDLC support module revision 1.12"; static int hdlc_change_mtu(struct net_device *dev, int new_mtu) @@ -60,7 +56,13 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p) { - dev_to_hdlc(dev)->netif_rx(skb); + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->netif_rx) + hdlc->netif_rx(skb); + else { + hdlc->stats.rx_dropped++; /* Shouldn't happen */ + dev_kfree_skb(skb); + } return 0; } @@ -69,6 +71,10 @@ #define hdlc_raw_ioctl(hdlc, ifr) -ENOSYS #endif +#ifndef CONFIG_HDLC_RAW_ETH +#define hdlc_raw_eth_ioctl(hdlc, ifr) -ENOSYS +#endif + #ifndef CONFIG_HDLC_PPP #define hdlc_ppp_ioctl(hdlc, ifr) -ENOSYS #endif @@ -96,6 +102,7 @@ switch(ifr->ifr_settings.type) { case IF_PROTO_HDLC: + case IF_PROTO_HDLC_ETH: case IF_PROTO_PPP: case IF_PROTO_CISCO: case IF_PROTO_FR: @@ -109,6 +116,7 @@ switch(proto) { case IF_PROTO_HDLC: return hdlc_raw_ioctl(hdlc, ifr); + case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(hdlc, ifr); case IF_PROTO_PPP: return hdlc_ppp_ioctl(hdlc, ifr); case IF_PROTO_CISCO: return hdlc_cisco_ioctl(hdlc, ifr); case IF_PROTO_FR: return hdlc_fr_ioctl(hdlc, ifr); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_ppp.c linux.21pre4-ac6/drivers/net/wan/hdlc_ppp.c --- linux.21pre4/drivers/net/wan/hdlc_ppp.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_ppp.c 2003-01-28 16:39:15.000000000 +0000 @@ -2,12 +2,11 @@ * Generic HDLC support routines for Linux * Point-to-point protocol support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ #include @@ -68,10 +67,10 @@ -static void ppp_rx(struct sk_buff *skb) +static unsigned short ppp_type_trans(struct sk_buff *skb, + struct net_device *dev) { - skb->protocol = htons(ETH_P_WAN_PPP); - netif_rx(skb); + return __constant_htons(ETH_P_WAN_PPP); } @@ -103,7 +102,8 @@ hdlc->open = ppp_open; hdlc->stop = ppp_close; - hdlc->netif_rx = ppp_rx; + hdlc->netif_rx = NULL; + hdlc->type_trans = ppp_type_trans; hdlc->proto = IF_PROTO_PPP; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = NULL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_raw.c linux.21pre4-ac6/drivers/net/wan/hdlc_raw.c --- linux.21pre4/drivers/net/wan/hdlc_raw.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_raw.c 2003-01-28 16:39:15.000000000 +0000 @@ -2,12 +2,11 @@ * Generic HDLC support routines for Linux * HDLC support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ #include @@ -26,10 +25,10 @@ #include -static void raw_rx(struct sk_buff *skb) +static unsigned short raw_type_trans(struct sk_buff *skb, + struct net_device *dev) { - skb->protocol = htons(ETH_P_IP); - netif_rx(skb); + return __constant_htons(ETH_P_IP); } @@ -67,7 +66,7 @@ new_settings.encoding = ENCODING_NRZ; if (new_settings.parity == PARITY_DEFAULT) - new_settings.parity = PARITY_NONE; + new_settings.parity = PARITY_CRC16_PR1_CCITT; result = hdlc->attach(hdlc, new_settings.encoding, new_settings.parity); @@ -79,11 +78,13 @@ hdlc->open = NULL; hdlc->stop = NULL; - hdlc->netif_rx = raw_rx; + hdlc->netif_rx = NULL; + hdlc->type_trans = raw_type_trans; hdlc->proto = IF_PROTO_HDLC; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = NULL; dev->type = ARPHRD_RAWHDLC; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; dev->addr_len = 0; return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_raw_eth.c linux.21pre4-ac6/drivers/net/wan/hdlc_raw_eth.c --- linux.21pre4/drivers/net/wan/hdlc_raw_eth.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_raw_eth.c 2003-01-28 16:39:15.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * Generic HDLC support routines for Linux + * HDLC Ethernet emulation support + * + * Copyright (C) 2002-2003 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int eth_tx(struct sk_buff *skb, struct net_device *dev) +{ + int pad = ETH_ZLEN - skb->len; + if (pad > 0) { /* Pad the frame with zeros */ + int len = skb->len; + if (skb_tailroom(skb) < pad) + if (pskb_expand_head(skb, 0, pad, GFP_ATOMIC)) { + dev_to_hdlc(dev)->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; + } + skb_put(skb, pad); + memset(skb->data + len, 0, pad); + } + return dev_to_hdlc(dev)->xmit(skb, dev); +} + + +int hdlc_raw_eth_ioctl(hdlc_device *hdlc, struct ifreq *ifr) +{ + raw_hdlc_proto *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; + const size_t size = sizeof(raw_hdlc_proto); + raw_hdlc_proto new_settings; + struct net_device *dev = hdlc_to_dev(hdlc); + int result; + void *old_ch_mtu; + int old_qlen; + + switch (ifr->ifr_settings.type) { + case IF_GET_PROTO: + ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) + return -EFAULT; + return 0; + + case IF_PROTO_HDLC_ETH: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (dev->flags & IFF_UP) + return -EBUSY; + + if (copy_from_user(&new_settings, raw_s, size)) + return -EFAULT; + + if (new_settings.encoding == ENCODING_DEFAULT) + new_settings.encoding = ENCODING_NRZ; + + if (new_settings.parity == PARITY_DEFAULT) + new_settings.parity = PARITY_CRC16_PR1_CCITT; + + result = hdlc->attach(hdlc, new_settings.encoding, + new_settings.parity); + if (result) + return result; + + hdlc_proto_detach(hdlc); + memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); + + hdlc->open = NULL; + hdlc->stop = NULL; + hdlc->netif_rx = NULL; + hdlc->type_trans = eth_type_trans; + hdlc->proto = IF_PROTO_HDLC_ETH; + dev->hard_start_xmit = eth_tx; + old_ch_mtu = dev->change_mtu; + old_qlen = dev->tx_queue_len; + ether_setup(dev); + dev->change_mtu = old_ch_mtu; + dev->tx_queue_len = old_qlen; + memcpy(dev->dev_addr, "\x00\x01", 2); + get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); + return 0; + } + + return -EINVAL; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/hdlc_x25.c linux.21pre4-ac6/drivers/net/wan/hdlc_x25.c --- linux.21pre4/drivers/net/wan/hdlc_x25.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/hdlc_x25.c 2003-01-28 16:39:15.000000000 +0000 @@ -2,12 +2,11 @@ * Generic HDLC support routines for Linux * X.25 support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ #include @@ -204,6 +203,7 @@ hdlc->open = x25_open; hdlc->stop = x25_close; hdlc->netif_rx = x25_rx; + hdlc->type_trans = NULL; hdlc->proto = IF_PROTO_X25; dev->hard_start_xmit = x25_xmit; dev->hard_header = NULL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wan/Makefile linux.21pre4-ac6/drivers/net/wan/Makefile --- linux.21pre4/drivers/net/wan/Makefile 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wan/Makefile 2003-01-28 16:39:15.000000000 +0000 @@ -24,6 +24,7 @@ hdlc-y := hdlc_generic.o hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o +hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/wavelan.c linux.21pre4-ac6/drivers/net/wavelan.c --- linux.21pre4/drivers/net/wavelan.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/wavelan.c 2003-01-06 23:13:06.000000000 +0000 @@ -2825,6 +2825,13 @@ (unsigned) skb); #endif + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + /* * Block a timer-based transmit from overlapping. * In other words, prevent reentering this routine. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/yellowfin.c linux.21pre4-ac6/drivers/net/yellowfin.c --- linux.21pre4/drivers/net/yellowfin.c 2003-01-29 16:26:41.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/yellowfin.c 2003-01-06 15:38:15.000000000 +0000 @@ -857,6 +857,7 @@ { struct yellowfin_private *yp = dev->priv; unsigned entry; + int len = skb->len; netif_stop_queue (dev); @@ -872,27 +873,37 @@ int cacheline_end = ((unsigned long)skb->data + skb->len) % 32; /* Fix GX chipset errata. */ if (cacheline_end > 24 || cacheline_end == 0) - skb->len += 32 - cacheline_end + 1; + { + len = skb->len + 32 - cacheline_end + 1; + if(len != skb->len) + skb = skb_padto(skb, len); + } + if(skb == NULL) + { + yp->tx_skbuff[entry] = NULL; + netif_wake_queue(dev); + return 0; + } } #ifdef NO_TXSTATS yp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, - skb->data, skb->len, PCI_DMA_TODEVICE)); + skb->data, len, PCI_DMA_TODEVICE)); yp->tx_ring[entry].result_status = 0; if (entry >= TX_RING_SIZE-1) { /* New stop command. */ yp->tx_ring[0].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->tx_ring[TX_RING_SIZE-1].dbdma_cmd = - cpu_to_le32(CMD_TX_PKT|BRANCH_ALWAYS | skb->len); + cpu_to_le32(CMD_TX_PKT|BRANCH_ALWAYS | len); } else { yp->tx_ring[entry+1].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->tx_ring[entry].dbdma_cmd = - cpu_to_le32(CMD_TX_PKT | BRANCH_IFTRUE | skb->len); + cpu_to_le32(CMD_TX_PKT | BRANCH_IFTRUE | len); } yp->cur_tx++; #else - yp->tx_ring[entry<<1].request_cnt = skb->len; + yp->tx_ring[entry<<1].request_cnt = len; yp->tx_ring[entry<<1].addr = cpu_to_le32(pci_map_single(yp->pci_dev, - skb->data, skb->len, PCI_DMA_TODEVICE)); + skb->data, len, PCI_DMA_TODEVICE)); /* The input_last (status-write) command is constant, but we must rewrite the subsequent 'stop' command. */ @@ -905,7 +916,7 @@ yp->tx_ring[entry<<1].dbdma_cmd = cpu_to_le32( ((entry % 6) == 0 ? CMD_TX_PKT|INTR_ALWAYS|BRANCH_IFTRUE : - CMD_TX_PKT | BRANCH_IFTRUE) | skb->len); + CMD_TX_PKT | BRANCH_IFTRUE) | len); #endif /* Non-x86 Todo: explicitly flush cache lines here. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/net/znet.c linux.21pre4-ac6/drivers/net/znet.c --- linux.21pre4/drivers/net/znet.c 2003-01-29 16:26:40.000000000 +0000 +++ linux.21pre4-ac6/drivers/net/znet.c 2003-01-06 15:38:15.000000000 +0000 @@ -348,10 +348,19 @@ int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; + short length = skb->len; if (znet_debug > 4) printk(KERN_DEBUG "%s: ZNet_send_packet.\n", dev->name); + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + netif_stop_queue (dev); /* Check that the part hasn't reset itself, probably from suspend. */ @@ -362,7 +371,6 @@ hardware_init(dev); if (1) { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = (void *)skb->data; ushort *tx_link = zn.tx_cur - 1; ushort rnd_len = (length + 1)>>1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/pci/pci.ids linux.21pre4-ac6/drivers/pci/pci.ids --- linux.21pre4/drivers/pci/pci.ids 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/pci/pci.ids 2003-01-06 15:38:23.000000000 +0000 @@ -3044,7 +3044,7 @@ f015 NinjaSCSI-32 Melco 1146 Force Computers 1147 Interface Corp -1148 Syskonnect (Schneider & Koch) +1148 SysKonnect 4000 FDDI Adapter 0e11 b03b Netelligent 100 FDDI DAS Fibre SC 0e11 b03c Netelligent 100 FDDI SAS Fibre SC @@ -3062,15 +3062,25 @@ 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64) 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS) 4200 Token Ring adapter - 4300 Gigabit Ethernet - 1148 9821 SK-9821 (1000Base-T single link) - 1148 9822 SK-9822 (1000Base-T dual link) - 1148 9841 SK-9841 (1000Base-LX single link) - 1148 9842 SK-9842 (1000Base-LX dual link) - 1148 9843 SK-9843 (1000Base-SX single link) - 1148 9844 SK-9844 (1000Base-SX dual link) - 1148 9861 SK-9861 (1000Base-SX VF45 single link) - 1148 9862 SK-9862 (1000Base-SX VF45 dual link) + 4300 SK-98xx Gigabit Ethernet Server Adapter + 1148 9821 SK-9821 Gigabit Ethernet 1000Base-T Server Adapter + 1148 9822 SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter + 1148 9841 SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter + 1148 9842 SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter + 1148 9843 SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter + 1148 9844 SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter + 1148 9861 SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter + 1148 9862 SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter + 1148 9871 SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter + 1148 9872 SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter + 4320 SK-98xx Gigabit Ethernet Server Adapter + 1148 9521 SK-9521 10/100/1000Base-T Adapter + 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter + 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter + 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter + 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter + 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter + 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter 4400 Gigabit Ethernet 1149 Win System Corporation 114a VMIC diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/pci/quirks.c linux.21pre4-ac6/drivers/pci/quirks.c --- linux.21pre4/drivers/pci/quirks.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/pci/quirks.c 2003-01-31 12:33:14.000000000 +0000 @@ -234,7 +234,6 @@ static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev) { printk(KERN_INFO "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb.\n"); - /* Mae rhaid in i beidio a edrych ar y lleoliad I/O hyn */ request_region(0x3b0, 0x0C, "RadeonIGP"); request_region(0x3d3, 0x01, "RadeonIGP"); } @@ -573,6 +572,41 @@ } /* + * Ensure C0 rev restreaming is off. This is normally done by + * the BIOS but in the odd case it is not the results are corruption + * hence the presence of a Linux check + */ + +static void __init quirk_disable_pxb(struct pci_dev *pdev) +{ + u16 config; + u8 rev; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); + if(rev != 0x04) /* Only C0 requires this */ + return; + pci_read_config_word(pdev, 0x40, &config); + if(config & (1<<6)) + { + config &= ~(1<<6); + pci_write_config_word(pdev, 0x40, config); + printk(KERN_INFO "PCI: C0 revision 450NX. Disabling PCI restreaming.\n"); + } +} + +/* + * VIA northbridges care about PCI_INTERRUPT_LINE + */ + +int interrupt_line_quirk; + +static void __init quirk_via_bridge(struct pci_dev *pdev) +{ + if(pdev->devfn == 0) + interrupt_line_quirk = 1; +} + +/* * The main table of quirks. */ @@ -587,6 +621,7 @@ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_isa_dma_hangs }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, quirk_isa_dma_hangs }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, quirk_isa_dma_hangs }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, quirk_triton }, @@ -616,6 +651,7 @@ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb }, { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_ide_bases }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_bridge }, { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy }, #ifdef CONFIG_X86_IO_APIC diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/pnp/Config.in linux.21pre4-ac6/drivers/pnp/Config.in --- linux.21pre4/drivers/pnp/Config.in 2003-01-29 16:26:56.000000000 +0000 +++ linux.21pre4-ac6/drivers/pnp/Config.in 2003-01-06 15:42:40.000000000 +0000 @@ -8,4 +8,8 @@ dep_tristate ' ISA Plug and Play support' CONFIG_ISAPNP $CONFIG_PNP +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_bool ' PNPBIOS support (EXPERIMENTAL)' CONFIG_PNPBIOS $CONFIG_PNP +fi + endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/pnp/Makefile linux.21pre4-ac6/drivers/pnp/Makefile --- linux.21pre4/drivers/pnp/Makefile 2003-01-29 16:26:56.000000000 +0000 +++ linux.21pre4-ac6/drivers/pnp/Makefile 2003-01-06 15:42:50.000000000 +0000 @@ -10,15 +10,22 @@ O_TARGET := pnp.o -export-objs := isapnp.o -list-multi := isa-pnp.o +export-objs := isapnp.o pnpbios_core.o +multi-objs := isa-pnp.o pnpbios.o -proc-$(CONFIG_PROC_FS) = isapnp_proc.o -isa-pnp-objs := isapnp.o quirks.o $(proc-y) +isa-pnp-proc-$(CONFIG_PROC_FS) = isapnp_proc.o +pnpbios-proc-$(CONFIG_PROC_FS) = pnpbios_proc.o + +isa-pnp-objs := isapnp.o quirks.o $(isa-pnp-proc-y) +pnpbios-objs := pnpbios_core.o $(pnpbios-proc-y) obj-$(CONFIG_ISAPNP) += isa-pnp.o +obj-$(CONFIG_PNPBIOS) += pnpbios.o include $(TOPDIR)/Rules.make isa-pnp.o: $(isa-pnp-objs) $(LD) $(LD_RFLAG) -r -o $@ $(isa-pnp-objs) + +pnpbios.o: $(pnpbios-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(pnpbios-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/pnp/pnpbios_core.c linux.21pre4-ac6/drivers/pnp/pnpbios_core.c --- linux.21pre4/drivers/pnp/pnpbios_core.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/pnp/pnpbios_core.c 2003-01-06 15:42:50.000000000 +0000 @@ -0,0 +1,1352 @@ +/* + * PnP BIOS services + * + * Originally (C) 1998 Christian Schmidt + * Modifications (c) 1998 Tom Lees + * Minor reorganizations by David Hinds + * Modifications (c) 2001,2002 by Thomas Hood + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * References: + * Compaq Computer Corporation, Phoenix Technologies Ltd., Intel Corporation + * Plug and Play BIOS Specification, Version 1.0A, May 5, 1994 + * Plug and Play BIOS Clarification Paper, October 6, 1994 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * + * PnP BIOS INTERFACE + * + */ + +/* PnP BIOS signature: "$PnP" */ +#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24)) + +#pragma pack(1) +union pnp_bios_expansion_header { + struct { + u32 signature; /* "$PnP" */ + u8 version; /* in BCD */ + u8 length; /* length in bytes, currently 21h */ + u16 control; /* system capabilities */ + u8 checksum; /* all bytes must add up to 0 */ + + u32 eventflag; /* phys. address of the event flag */ + u16 rmoffset; /* real mode entry point */ + u16 rmcseg; + u16 pm16offset; /* 16 bit protected mode entry */ + u32 pm16cseg; + u32 deviceID; /* EISA encoded system ID or 0 */ + u16 rmdseg; /* real mode data segment */ + u32 pm16dseg; /* 16 bit pm data segment base */ + } fields; + char chars[0x21]; /* To calculate the checksum */ +}; +#pragma pack() + +static struct { + u16 offset; + u16 segment; +} pnp_bios_callpoint; + +static union pnp_bios_expansion_header * pnp_bios_hdr = NULL; + +/* The PnP BIOS entries in the GDT */ +#define PNP_GDT (0x0060) +#define PNP_CS32 (PNP_GDT+0x00) /* segment for calling fn */ +#define PNP_CS16 (PNP_GDT+0x08) /* code segment for BIOS */ +#define PNP_DS (PNP_GDT+0x10) /* data segment for BIOS */ +#define PNP_TS1 (PNP_GDT+0x18) /* transfer data segment */ +#define PNP_TS2 (PNP_GDT+0x20) /* another data segment */ + +/* + * These are some opcodes for a "static asmlinkage" + * As this code is *not* executed inside the linux kernel segment, but in a + * alias at offset 0, we need a far return that can not be compiled by + * default (please, prove me wrong! this is *really* ugly!) + * This is the only way to get the bios to return into the kernel code, + * because the bios code runs in 16 bit protected mode and therefore can only + * return to the caller if the call is within the first 64kB, and the linux + * kernel begins at offset 3GB... + */ + +asmlinkage void pnp_bios_callfunc(void); + +__asm__( + ".text \n" + __ALIGN_STR "\n" + SYMBOL_NAME_STR(pnp_bios_callfunc) ":\n" + " pushl %edx \n" + " pushl %ecx \n" + " pushl %ebx \n" + " pushl %eax \n" + " lcallw " SYMBOL_NAME_STR(pnp_bios_callpoint) "\n" + " addl $16, %esp \n" + " lret \n" + ".previous \n" +); + +#define Q_SET_SEL(selname, address, size) \ +set_base (gdt [(selname) >> 3], __va((u32)(address))); \ +set_limit (gdt [(selname) >> 3], size) + +#define Q2_SET_SEL(selname, address, size) \ +set_base (gdt [(selname) >> 3], (u32)(address)); \ +set_limit (gdt [(selname) >> 3], size) + +/* + * At some point we want to use this stack frame pointer to unwind + * after PnP BIOS oopses. + */ + +u32 pnp_bios_fault_esp; +u32 pnp_bios_fault_eip; +u32 pnp_bios_is_utter_crap = 0; + +static spinlock_t pnp_bios_lock; + +static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, + u16 arg4, u16 arg5, u16 arg6, u16 arg7, + void *ts1_base, u32 ts1_size, + void *ts2_base, u32 ts2_size) +{ + unsigned long flags; + u16 status; + + /* + * PnP BIOSes are generally not terribly re-entrant. + * Also, don't rely on them to save everything correctly. + */ + if(pnp_bios_is_utter_crap) + return PNP_FUNCTION_NOT_SUPPORTED; + + /* On some boxes IRQ's during PnP BIOS calls are deadly. */ + spin_lock_irqsave(&pnp_bios_lock, flags); + + if (ts1_size) + Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size); + if (ts2_size) + Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size); + + __asm__ __volatile__( + "pushl %%ebp\n\t" + "pushl %%edi\n\t" + "pushl %%esi\n\t" + "pushl %%ds\n\t" + "pushl %%es\n\t" + "pushl %%fs\n\t" + "pushl %%gs\n\t" + "pushfl\n\t" + "movl %%esp, pnp_bios_fault_esp\n\t" + "movl $1f, pnp_bios_fault_eip\n\t" + "lcall %5,%6\n\t" + "1:popfl\n\t" + "popl %%gs\n\t" + "popl %%fs\n\t" + "popl %%es\n\t" + "popl %%ds\n\t" + "popl %%esi\n\t" + "popl %%edi\n\t" + "popl %%ebp\n\t" + : "=a" (status) + : "0" ((func) | (((u32)arg1) << 16)), + "b" ((arg2) | (((u32)arg3) << 16)), + "c" ((arg4) | (((u32)arg5) << 16)), + "d" ((arg6) | (((u32)arg7) << 16)), + "i" (PNP_CS32), + "i" (0) + : "memory" + ); + spin_unlock_irqrestore(&pnp_bios_lock, flags); + + /* If we get here and this is set then the PnP BIOS faulted on us. */ + if(pnp_bios_is_utter_crap) + { + printk(KERN_ERR "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue.\n"); + printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably.\n"); + printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS.\n"); + } + + return status; +} + + +/* + * + * UTILITY FUNCTIONS + * + */ + +static void pnpbios_warn_unexpected_status(const char * module, u16 status) +{ + printk(KERN_ERR "PnPBIOS: %s: Unexpected status 0x%x\n", module, status); +} + +void *pnpbios_kmalloc(size_t size, int f) +{ + void *p = kmalloc( size, f ); + if ( p == NULL ) + printk(KERN_ERR "PnPBIOS: kmalloc() failed\n"); + return p; +} + +/* + * Call this only after init time + */ +static inline int pnp_bios_present(void) +{ + return (pnp_bios_hdr != NULL); +} + +/* Forward declaration */ +static void update_devlist( u8 nodenum, struct pnp_bios_node *data ); + + +/* + * + * PnP BIOS ACCESS FUNCTIONS + * + */ + +#define PNP_GET_NUM_SYS_DEV_NODES 0x00 +#define PNP_GET_SYS_DEV_NODE 0x01 +#define PNP_SET_SYS_DEV_NODE 0x02 +#define PNP_GET_EVENT 0x03 +#define PNP_SEND_MESSAGE 0x04 +#define PNP_GET_DOCKING_STATION_INFORMATION 0x05 +#define PNP_SET_STATIC_ALLOCED_RES_INFO 0x09 +#define PNP_GET_STATIC_ALLOCED_RES_INFO 0x0a +#define PNP_GET_APM_ID_TABLE 0x0b +#define PNP_GET_PNP_ISA_CONFIG_STRUC 0x40 +#define PNP_GET_ESCD_INFO 0x41 +#define PNP_READ_ESCD 0x42 +#define PNP_WRITE_ESCD 0x43 + +/* + * Call PnP BIOS with function 0x00, "get number of system device nodes" + */ +static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0, + data, sizeof(struct pnp_dev_node_info), 0, 0); + data->no_nodes &= 0xff; + return status; +} + +int pnp_bios_dev_node_info(struct pnp_dev_node_info *data) +{ + int status = __pnp_bios_dev_node_info( data ); + if ( status ) + pnpbios_warn_unexpected_status( "dev_node_info", status ); + return status; +} + +/* + * Note that some PnP BIOSes (e.g., on Sony Vaio laptops) die a horrible + * death if they are asked to access the "current" configuration. + * Therefore, if it's a matter of indifference, it's better to call + * get_dev_node() and set_dev_node() with boot=1 rather than with boot=0. + */ + +/* + * Call PnP BIOS with function 0x01, "get system device node" + * Input: *nodenum = desired node, + * boot = whether to get nonvolatile boot (!=0) + * or volatile current (0) config + * Output: *nodenum=next node or 0xff if no more nodes + */ +static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + if ( !boot & pnpbios_dont_use_current_config ) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0, + nodenum, sizeof(char), data, 65536); + return status; +} + +int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) +{ + int status; + status = __pnp_bios_get_dev_node( nodenum, boot, data ); + if ( status ) + pnpbios_warn_unexpected_status( "get_dev_node", status ); + return status; +} + + +/* + * Call PnP BIOS with function 0x02, "set system device node" + * Input: *nodenum = desired node, + * boot = whether to set nonvolatile boot (!=0) + * or volatile current (0) config + */ +static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + if ( !boot & pnpbios_dont_use_current_config ) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0, + data, 65536, 0, 0); + return status; +} + +int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data) +{ + int status; + status = __pnp_bios_set_dev_node( nodenum, boot, data ); + if ( status ) { + pnpbios_warn_unexpected_status( "set_dev_node", status ); + return status; + } + if ( !boot ) { /* Update devlist */ + u8 thisnodenum = nodenum; + status = pnp_bios_get_dev_node( &nodenum, boot, data ); + if ( status ) + return status; + update_devlist( thisnodenum, data ); + } + return status; +} + +#if needed +/* + * Call PnP BIOS with function 0x03, "get event" + */ +static int pnp_bios_get_event(u16 *event) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0, + event, sizeof(u16), 0, 0); + return status; +} +#endif + +#if needed +/* + * Call PnP BIOS with function 0x04, "send message" + */ +static int pnp_bios_send_message(u16 message) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return status; +} +#endif + +#ifdef CONFIG_HOTPLUG +/* + * Call PnP BIOS with function 0x05, "get docking station information" + */ +static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + data, sizeof(struct pnp_docking_station_info), 0, 0); + return status; +} +#endif + +#if needed +/* + * Call PnP BIOS with function 0x09, "set statically allocated resource + * information" + */ +static int pnp_bios_set_stat_res(char *info) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + info, *((u16 *) info), 0, 0); + return status; +} +#endif + +/* + * Call PnP BIOS with function 0x0a, "get statically allocated resource + * information" + */ +static int __pnp_bios_get_stat_res(char *info) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + info, 65536, 0, 0); + return status; +} + +int pnp_bios_get_stat_res(char *info) +{ + int status; + status = __pnp_bios_get_stat_res( info ); + if ( status ) + pnpbios_warn_unexpected_status( "get_stat_res", status ); + return status; +} + +#if needed +/* + * Call PnP BIOS with function 0x0b, "get APM id table" + */ +static int pnp_bios_apm_id_table(char *table, u16 *size) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0, + table, *size, size, sizeof(u16)); + return status; +} +#endif + +/* + * Call PnP BIOS with function 0x40, "get isa pnp configuration structure" + */ +static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + data, sizeof(struct pnp_isa_config_struc), 0, 0); + return status; +} + +int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data) +{ + int status; + status = __pnp_bios_isapnp_config( data ); + if ( status ) + pnpbios_warn_unexpected_status( "isapnp_config", status ); + return status; +} + +/* + * Call PnP BIOS with function 0x41, "get ESCD info" + */ +static int __pnp_bios_escd_info(struct escd_info_struc *data) +{ + u16 status; + if (!pnp_bios_present()) + return ESCD_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS, + data, sizeof(struct escd_info_struc), 0, 0); + return status; +} + +int pnp_bios_escd_info(struct escd_info_struc *data) +{ + int status; + status = __pnp_bios_escd_info( data ); + if ( status ) + pnpbios_warn_unexpected_status( "escd_info", status ); + return status; +} + +/* + * Call PnP BIOS function 0x42, "read ESCD" + * nvram_base is determined by calling escd_info + */ +static int __pnp_bios_read_escd(char *data, u32 nvram_base) +{ + u16 status; + if (!pnp_bios_present()) + return ESCD_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0, + data, 65536, (void *)nvram_base, 65536); + return status; +} + +int pnp_bios_read_escd(char *data, u32 nvram_base) +{ + int status; + status = __pnp_bios_read_escd( data, nvram_base ); + if ( status ) + pnpbios_warn_unexpected_status( "read_escd", status ); + return status; +} + +#if needed +/* + * Call PnP BIOS function 0x43, "write ESCD" + */ +static int pnp_bios_write_escd(char *data, u32 nvram_base) +{ + u16 status; + if (!pnp_bios_present()) + return ESCD_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0, + data, 65536, nvram_base, 65536); + return status; +} +#endif + + +/* + * + * DOCKING FUNCTIONS + * + */ + +#ifdef CONFIG_HOTPLUG + +static int unloading = 0; +static struct completion unload_sem; + +/* + * (Much of this belongs in a shared routine somewhere) + */ + +static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) +{ + char *argv [3], **envp, *buf, *scratch; + int i = 0, value; + + if (!hotplug_path [0]) + return -ENOENT; + if (!current->fs->root) { + return -EAGAIN; + } + if (!(envp = (char **) pnpbios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) { + return -ENOMEM; + } + if (!(buf = pnpbios_kmalloc (256, GFP_KERNEL))) { + kfree (envp); + return -ENOMEM; + } + + /* only one standardized param to hotplug command: type */ + argv [0] = hotplug_path; + argv [1] = "dock"; + argv [2] = 0; + + /* minimal command environment */ + envp [i++] = "HOME=/"; + envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + +#ifdef DEBUG + /* hint that policy agent should enter no-stdout debug mode */ + envp [i++] = "DEBUG=kernel"; +#endif + /* extensible set of named bus-specific parameters, + * supporting multiple driver selection algorithms. + */ + scratch = buf; + + /* action: add, remove */ + envp [i++] = scratch; + scratch += sprintf (scratch, "ACTION=%s", dock?"add":"remove") + 1; + + /* Report the ident for the dock */ + envp [i++] = scratch; + scratch += sprintf (scratch, "DOCK=%x/%x/%x", + info->location_id, info->serial, info->capabilities); + envp[i] = 0; + + value = call_usermodehelper (argv [0], argv, envp); + kfree (buf); + kfree (envp); + return 0; +} + +/* + * Poll the PnP docking at regular intervals + */ +static int pnp_dock_thread(void * unused) +{ + static struct pnp_docking_station_info now; + int docked = -1, d = 0; + daemonize(); + reparent_to_init(); + strcpy(current->comm, "kpnpbiosd"); + while(!unloading && !signal_pending(current)) + { + int status; + + /* + * Poll every 2 seconds + */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ*2); + if(signal_pending(current)) + break; + + status = pnp_bios_dock_station_info(&now); + + switch(status) + { + /* + * No dock to manage + */ + case PNP_FUNCTION_NOT_SUPPORTED: + complete_and_exit(&unload_sem, 0); + case PNP_SYSTEM_NOT_DOCKED: + d = 0; + break; + case PNP_SUCCESS: + d = 1; + break; + default: + pnpbios_warn_unexpected_status( "pnp_dock_thread", status ); + continue; + } + if(d != docked) + { + if(pnp_dock_event(d, &now)==0) + { + docked = d; +#if 0 + printk(KERN_INFO "PnPBIOS: Docking station %stached\n", docked?"at":"de"); +#endif + } + } + } + complete_and_exit(&unload_sem, 0); +} + +#endif /* CONFIG_HOTPLUG */ + + +/* + * + * NODE DATA PARSING FUNCTIONS + * + */ + +static void add_irqresource(struct pci_dev *dev, int irq) +{ + int i = 0; + while (!(dev->irq_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_IRQ) i++; + if (i < DEVICE_COUNT_IRQ) { + dev->irq_resource[i].start = (unsigned long) irq; + dev->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag + } +} + +static void add_dmaresource(struct pci_dev *dev, int dma) +{ + int i = 0; + while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++; + if (i < DEVICE_COUNT_DMA) { + dev->dma_resource[i].start = (unsigned long) dma; + dev->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag + } +} + +static void add_ioresource(struct pci_dev *dev, int io, int len) +{ + int i = 0; + while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++; + if (i < DEVICE_COUNT_RESOURCE) { + dev->resource[i].start = (unsigned long) io; + dev->resource[i].end = (unsigned long)(io + len - 1); + dev->resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag + } +} + +static void add_memresource(struct pci_dev *dev, int mem, int len) +{ + int i = 0; + while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++; + if (i < DEVICE_COUNT_RESOURCE) { + dev->resource[i].start = (unsigned long) mem; + dev->resource[i].end = (unsigned long)(mem + len - 1); + dev->resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag + } +} + +static void node_resource_data_to_dev(struct pnp_bios_node *node, struct pci_dev *dev) +{ + unsigned char *p = node->data, *lastp=NULL; + int i; + + /* + * First, set resource info to default values + */ + for (i=0;iresource[i].start = 0; // "disabled" + dev->resource[i].flags = IORESOURCE_UNSET; + } + for (i=0;iirq_resource[i].start = (unsigned long)-1; // "disabled" + dev->irq_resource[i].flags = IORESOURCE_UNSET; + } + for (i=0;idma_resource[i].start = (unsigned long)-1; // "disabled" + dev->dma_resource[i].flags = IORESOURCE_UNSET; + } + + /* + * Fill in dev resource info + */ + while ( (char *)p < ((char *)node->data + node->size )) { + if(p==lastp) break; + + if( p[0] & 0x80 ) {// large item + switch (p[0] & 0x7f) { + case 0x01: // memory + { + int io = *(short *) &p[4]; + int len = *(short *) &p[10]; + add_memresource(dev, io, len); + break; + } + case 0x02: // device name + { + int len = *(short *) &p[1]; + memcpy(dev->name, p + 3, len >= 80 ? 79 : len); + break; + } + case 0x05: // 32-bit memory + { + int io = *(int *) &p[4]; + int len = *(int *) &p[16]; + add_memresource(dev, io, len); + break; + } + case 0x06: // fixed location 32-bit memory + { + int io = *(int *) &p[4]; + int len = *(int *) &p[8]; + add_memresource(dev, io, len); + break; + } + } /* switch */ + lastp = p+3; + p = p + p[1] + p[2]*256 + 3; + continue; + } + if ((p[0]>>3) == 0x0f) // end tag + break; + switch (p[0]>>3) { + case 0x04: // irq + { + int i, mask, irq = -1; + mask= p[1] + p[2]*256; + for (i=0;i<16;i++, mask=mask>>1) + if(mask & 0x01) irq=i; + add_irqresource(dev, irq); + break; + } + case 0x05: // dma + { + int i, mask, dma = -1; + mask = p[1]; + for (i=0;i<8;i++, mask = mask>>1) + if(mask & 0x01) dma=i; + add_dmaresource(dev, dma); + break; + } + case 0x08: // io + { + int io= p[2] + p[3] *256; + int len = p[7]; + add_ioresource(dev, io, len); + break; + } + case 0x09: // fixed location io + { + int io = p[1] + p[2] * 256; + int len = p[3]; + add_ioresource(dev, io, len); + break; + } + } /* switch */ + lastp=p+1; + p = p + (p[0] & 0x07) + 1; + + } /* while */ + + return; +} + + +/* + * + * DEVICE LIST MANAGEMENT FUNCTIONS + * + * + * Some of these are exported to give public access + * + * Question: Why maintain a device list when the PnP BIOS can + * list devices for us? Answer: Some PnP BIOSes can't report + * the current configuration, only the boot configuration. + * The boot configuration can be changed, so we need to keep + * a record of what the configuration was when we booted; + * presumably it continues to describe the current config. + * For those BIOSes that can change the current config, we + * keep the information in the devlist up to date. + * + * Note that it is currently assumed that the list does not + * grow or shrink in size after init time, and slot_name + * never changes. The list is protected by a spinlock. + */ + +static LIST_HEAD(pnpbios_devices); + +static spinlock_t pnpbios_devices_lock; + +static int inline insert_device(struct pci_dev *dev) +{ + + /* + * FIXME: Check for re-add of existing node; + * return -1 if node already present + */ + + /* We don't lock because we only do this at init time */ + list_add_tail(&dev->global_list, &pnpbios_devices); + + return 0; +} + +#define HEX(id,a) hex[((id)>>a) & 15] +#define CHAR(id,a) (0x40 + (((id)>>a) & 31)) +// +static void inline pnpid32_to_pnpid(u32 id, char *str) +{ + const char *hex = "0123456789abcdef"; + + id = be32_to_cpu(id); + str[0] = CHAR(id, 26); + str[1] = CHAR(id, 21); + str[2] = CHAR(id,16); + str[3] = HEX(id, 12); + str[4] = HEX(id, 8); + str[5] = HEX(id, 4); + str[6] = HEX(id, 0); + str[7] = '\0'; + + return; +} +// +#undef CHAR +#undef HEX + +/* + * Build a linked list of pci_devs in order of ascending node number + * Called only at init time. + */ +static void __init build_devlist(void) +{ + u8 nodenum; + unsigned int nodes_got = 0; + unsigned int devs = 0; + struct pnp_bios_node *node; + struct pnp_dev_node_info node_info; + struct pci_dev *dev; + + if (!pnp_bios_present()) + return; + + if (pnp_bios_dev_node_info(&node_info) != 0) + return; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) + return; + + for(nodenum=0; nodenum<0xff; ) { + u8 thisnodenum = nodenum; + /* We build the list from the "boot" config because + * asking for the "current" config causes some + * BIOSes to crash. + */ + if (pnp_bios_get_dev_node(&nodenum, (char )1 , node)) + break; + nodes_got++; + dev = pnpbios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL); + if (!dev) + break; + memset(dev,0,sizeof(struct pci_dev)); + dev->devfn = thisnodenum; + memcpy(dev->name,"PNPBIOS",8); + pnpid32_to_pnpid(node->eisa_id,dev->slot_name); + node_resource_data_to_dev(node,dev); + if(insert_device(dev)<0) + kfree(dev); + else + devs++; + if (nodenum <= thisnodenum) { + printk(KERN_ERR "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (unsigned int)nodenum, (unsigned int)thisnodenum); + break; + } + } + kfree(node); + + printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS; %i recorded by driver\n", + nodes_got, nodes_got != 1 ? "s" : "", devs); +} + +static struct pci_dev *find_device_by_nodenum( u8 nodenum ) +{ + struct pci_dev *dev; + + pnpbios_for_each_dev(dev) { + if(dev->devfn == nodenum) + return dev; + } + + return NULL; +} + +static void update_devlist( u8 nodenum, struct pnp_bios_node *data ) +{ + unsigned long flags; + struct pci_dev *dev; + + spin_lock_irqsave(&pnpbios_devices_lock, flags); + dev = find_device_by_nodenum( nodenum ); + if ( dev ) { + node_resource_data_to_dev(data,dev); + } + spin_unlock_irqrestore(&pnpbios_devices_lock, flags); + + return; +} + + +/* + * + * DRIVER REGISTRATION FUNCTIONS + * + * + * Exported to give public access + * + */ + +static LIST_HEAD(pnpbios_drivers); + +static const struct pnpbios_device_id * +match_device(const struct pnpbios_device_id *ids, const struct pci_dev *dev) +{ + while (*ids->id) + { + if(memcmp(ids->id, dev->slot_name, 7)==0) + return ids; + ids++; + } + return NULL; +} + +static int announce_device(struct pnpbios_driver *drv, struct pci_dev *dev) +{ + const struct pnpbios_device_id *id; + struct pci_dev tmpdev; + int ret; + + if (drv->id_table) { + id = match_device(drv->id_table, dev); + if (!id) + return 0; + } else + id = NULL; + + memcpy( &tmpdev, dev, sizeof(struct pci_dev)); + tmpdev.global_list.prev = NULL; + tmpdev.global_list.next = NULL; + + dev_probe_lock(); + /* Obviously, probe() should not call any pnpbios functions */ + ret = drv->probe(&tmpdev, id); + dev_probe_unlock(); + if (ret < 1) + return 0; + + dev->driver = (void *)drv; + + return 1; +} + +/** + * pnpbios_register_driver - register a new pci driver + * @drv: the driver structure to register + * + * Adds the driver structure to the list of registered drivers + * + * For each device in the pnpbios device list that matches one of + * the ids in drv->id_table, calls the driver's "probe" function with + * arguments (1) a pointer to a *temporary* struct pci_dev containing + * resource info for the device, and (2) a pointer to the id string + * of the device. Expects the probe function to return 1 if the + * driver claims the device (otherwise 0) in which case, marks the + * device as having this driver. + * + * Returns the number of pci devices which were claimed by the driver + * during registration. The driver remains registered even if the + * return value is zero. + */ +int pnpbios_register_driver(struct pnpbios_driver *drv) +{ + struct pci_dev *dev; + unsigned long flags; + int count = 0; + + list_add_tail(&drv->node, &pnpbios_drivers); + spin_lock_irqsave(&pnpbios_devices_lock, flags); + pnpbios_for_each_dev(dev) { + if (!pnpbios_dev_driver(dev)) + count += announce_device(drv, dev); + } + spin_unlock_irqrestore(&pnpbios_devices_lock, flags); + return count; +} + +EXPORT_SYMBOL(pnpbios_register_driver); + +/** + * pnpbios_unregister_driver - unregister a pci driver + * @drv: the driver structure to unregister + * + * Deletes the driver structure from the list of registered PnPBIOS + * drivers, gives it a chance to clean up by calling its "remove" + * function for each device it was responsible for, and marks those + * devices as driverless. + */ +void pnpbios_unregister_driver(struct pnpbios_driver *drv) +{ + unsigned long flags; + struct pci_dev *dev; + + list_del(&drv->node); + spin_lock_irqsave(&pnpbios_devices_lock, flags); + pnpbios_for_each_dev(dev) { + if (dev->driver == (void *)drv) { + if (drv->remove) + drv->remove(dev); + dev->driver = NULL; + } + } + spin_unlock_irqrestore(&pnpbios_devices_lock, flags); +} + +EXPORT_SYMBOL(pnpbios_unregister_driver); + + +/* + * + * RESOURCE RESERVATION FUNCTIONS + * + * + * Used only at init time + * + */ + +static void __init reserve_ioport_range(char *pnpid, int start, int end) +{ + struct resource *res; + char *regionid; + +#if 0 + /* + * TEMPORARY hack to work around the fact that the + * floppy driver inappropriately reserves ioports 0x3f0 and 0x3f1 + * Remove this once the floppy driver is fixed. + */ + if ( + (0x3f0 >= start && 0x3f0 <= end) + || (0x3f1 >= start && 0x3f1 <= end) + ) { + printk(KERN_INFO + "PnPBIOS: %s: ioport range 0x%x-0x%x NOT reserved\n", + pnpid, start, end + ); + return; + } +#endif + + regionid = pnpbios_kmalloc(16, GFP_KERNEL); + if ( regionid == NULL ) + return; + snprintf(regionid, 16, "PnPBIOS %s", pnpid); + res = request_region(start,end-start+1,regionid); + if ( res == NULL ) + kfree( regionid ); + else + res->flags &= ~IORESOURCE_BUSY; + /* + * Failures at this point are usually harmless. pci quirks for + * example do reserve stuff they know about too, so we may well + * have double reservations. + */ + printk(KERN_INFO + "PnPBIOS: %s: ioport range 0x%x-0x%x %s reserved\n", + pnpid, start, end, + NULL != res ? "has been" : "could not be" + ); + + return; +} + +static void __init reserve_resources_of_dev( struct pci_dev *dev ) +{ + int i; + + for (i=0;iresource[i].flags & IORESOURCE_UNSET ) + /* end of resources */ + break; + if (dev->resource[i].flags & IORESOURCE_IO) { + /* ioport */ + if ( dev->resource[i].start == 0 ) + /* disabled */ + /* Do nothing */ + continue; + if ( dev->resource[i].start < 0x100 ) + /* + * Below 0x100 is only standard PC hardware + * (pics, kbd, timer, dma, ...) + * We should not get resource conflicts there, + * and the kernel reserves these anyway + * (see arch/i386/kernel/setup.c). + * So, do nothing + */ + continue; + if ( dev->resource[i].end < dev->resource[i].start ) + /* invalid endpoint */ + /* Do nothing */ + continue; + reserve_ioport_range( + dev->slot_name, + dev->resource[i].start, + dev->resource[i].end + ); + } else if (dev->resource[i].flags & IORESOURCE_MEM) { + /* iomem */ + /* For now do nothing */ + continue; + } else { + /* Neither ioport nor iomem */ + /* Do nothing */ + continue; + } + } + + return; +} + +static void __init reserve_resources( void ) +{ + struct pci_dev *dev; + + pnpbios_for_each_dev(dev) { + if ( + 0 != strcmp(dev->slot_name,"PNP0c01") && /* memory controller */ + 0 != strcmp(dev->slot_name,"PNP0c02") /* system peripheral: other */ + ) { + continue; + } + reserve_resources_of_dev(dev); + } + + return; +} + + +/* + * + * INIT AND EXIT + * + */ + +extern int is_sony_vaio_laptop; + +static int pnpbios_disabled; /* = 0 */ +static int dont_reserve_resources; /* = 0 */ +int pnpbios_dont_use_current_config; /* = 0 */ + +#ifndef MODULE +static int __init pnpbios_setup(char *str) +{ + int invert; + + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "off", 3) == 0) + pnpbios_disabled=1; + if (strncmp(str, "on", 2) == 0) + pnpbios_disabled=0; + invert = (strncmp(str, "no-", 3) == 0); + if (invert) + str += 3; + if (strncmp(str, "curr", 4) == 0) + pnpbios_dont_use_current_config = invert; + if (strncmp(str, "res", 3) == 0) + dont_reserve_resources = invert; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + + return 1; +} + +__setup("pnpbios=", pnpbios_setup); +#endif + +int __init pnpbios_init(void) +{ + union pnp_bios_expansion_header *check; + u8 sum; + int i, length, r; + + spin_lock_init(&pnp_bios_lock); + spin_lock_init(&pnpbios_devices_lock); + + if(pnpbios_disabled) { + printk(KERN_INFO "PnPBIOS: Disabled\n"); + return -ENODEV; + } + + if ( is_sony_vaio_laptop ) + pnpbios_dont_use_current_config = 1; + + /* + * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS + * structure and, if one is found, sets up the selectors and + * entry points + */ + for (check = (union pnp_bios_expansion_header *) __va(0xf0000); + check < (union pnp_bios_expansion_header *) __va(0xffff0); + ((void *) (check)) += 16) { + if (check->fields.signature != PNP_SIGNATURE) + continue; + length = check->fields.length; + if (!length) + continue; + for (sum = 0, i = 0; i < length; i++) + sum += check->chars[i]; + if (sum) + continue; + if (check->fields.version < 0x10) { + printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n", + check->fields.version >> 4, + check->fields.version & 15); + continue; + } + printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check); + printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n", + check->fields.version >> 4, check->fields.version & 15, + check->fields.pm16cseg, check->fields.pm16offset, + check->fields.pm16dseg); + Q2_SET_SEL(PNP_CS32, &pnp_bios_callfunc, 64 * 1024); + Q_SET_SEL(PNP_CS16, check->fields.pm16cseg, 64 * 1024); + Q_SET_SEL(PNP_DS, check->fields.pm16dseg, 64 * 1024); + pnp_bios_callpoint.offset = check->fields.pm16offset; + pnp_bios_callpoint.segment = PNP_CS16; + pnp_bios_hdr = check; + break; + } + if (!pnp_bios_present()) + return -ENODEV; + build_devlist(); + if ( ! dont_reserve_resources ) + reserve_resources(); +#ifdef CONFIG_PROC_FS + r = pnpbios_proc_init(); + if (r) + return r; +#endif + return 0; +} + +static int pnpbios_thread_init(void) +{ +#ifdef CONFIG_HOTPLUG + init_completion(&unload_sem); + if(kernel_thread(pnp_dock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)>0) + unloading = 0; +#endif + return 0; +} + +#ifndef MODULE + +/* init/main.c calls pnpbios_init early */ + +/* Start the kernel thread later: */ +module_init(pnpbios_thread_init); + +#else + +/* + * N.B.: Building pnpbios as a module hasn't been fully implemented + */ + +MODULE_LICENSE("GPL"); + +static int pnpbios_init_all(void) +{ + int r; + r = pnpbios_init(); + if (r) + return r; + r = pnpbios_thread_init(); + if (r) + return r; + return 0; +} + +static void __exit pnpbios_exit(void) +{ +#ifdef CONFIG_HOTPLUG + unloading = 1; + wait_for_completion(&unload_sem); +#endif + pnpbios_proc_exit(); + /* We ought to free resources here */ + return; +} + +module_init(pnpbios_init_all); +module_exit(pnpbios_exit); + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/pnp/pnpbios_proc.c linux.21pre4-ac6/drivers/pnp/pnpbios_proc.c --- linux.21pre4/drivers/pnp/pnpbios_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/pnp/pnpbios_proc.c 2003-01-06 15:42:50.000000000 +0000 @@ -0,0 +1,278 @@ +/* + * /proc/bus/pnp interface for Plug and Play devices + * + * Written by David Hinds, dahinds@users.sourceforge.net + * Modified by Thomas Hood, jdthood@mail.com + * + * The .../devices and .../ and .../boot/ files are + * utilized by the lspnp and setpnp utilities, supplied with the + * pcmcia-cs package. + * http://pcmcia-cs.sourceforge.net + * + * The .../escd file is utilized by the lsescd utility written by + * Gunther Mayer. + * http://home.t-online.de/home/gunther.mayer/lsescd + * + * The .../legacy_device_resources file is not used yet. + * + * The other files are human-readable. + */ + +//#include +#define __NO_VERSION__ +//#include + +#include +#include +#include +#include +#include +#include + +static struct proc_dir_entry *proc_pnp = NULL; +static struct proc_dir_entry *proc_pnp_boot = NULL; +static struct pnp_dev_node_info node_info; + +static int proc_read_pnpconfig(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct pnp_isa_config_struc pnps; + + if (pnp_bios_isapnp_config(&pnps)) + return -EIO; + return snprintf(buf, count, + "structure_revision %d\n" + "number_of_CSNs %d\n" + "ISA_read_data_port 0x%x\n", + pnps.revision, + pnps.no_csns, + pnps.isa_rd_data_port + ); +} + +static int proc_read_escdinfo(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct escd_info_struc escd; + + if (pnp_bios_escd_info(&escd)) + return -EIO; + return snprintf(buf, count, + "min_ESCD_write_size %d\n" + "ESCD_size %d\n" + "NVRAM_base 0x%x\n", + escd.min_escd_write_size, + escd.escd_size, + escd.nv_storage_base + ); +} + +#define MAX_SANE_ESCD_SIZE (32*1024) +static int proc_read_escd(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct escd_info_struc escd; + char *tmpbuf; + int escd_size, escd_left_to_read, n; + + if (pnp_bios_escd_info(&escd)) + return -EIO; + + /* sanity check */ + if (escd.escd_size > MAX_SANE_ESCD_SIZE) { + printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by BIOS escd_info call is too great\n"); + return -EFBIG; + } + + tmpbuf = pnpbios_kmalloc(escd.escd_size, GFP_KERNEL); + if (!tmpbuf) return -ENOMEM; + + if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base)) + return -EIO; + + escd_size = (unsigned char)(tmpbuf[0]) + (unsigned char)(tmpbuf[1])*256; + + /* sanity check */ + if (escd_size > MAX_SANE_ESCD_SIZE) { + printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by BIOS read_escd call is too great\n"); + return -EFBIG; + } + + escd_left_to_read = escd_size - pos; + if (escd_left_to_read < 0) escd_left_to_read = 0; + if (escd_left_to_read == 0) *eof = 1; + n = min(count,escd_left_to_read); + memcpy(buf, tmpbuf + pos, n); + kfree(tmpbuf); + *start = buf; + return n; +} + +static int proc_read_legacyres(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + /* Assume that the following won't overflow the buffer */ + if (pnp_bios_get_stat_res(buf)) + return -EIO; + + return count; // FIXME: Return actual length +} + +static int proc_read_devices(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct pnp_bios_node *node; + u8 nodenum; + char *p = buf; + + if (pos >= 0xff) + return 0; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) return -ENOMEM; + + for (nodenum=pos; nodenum<0xff; ) { + u8 thisnodenum = nodenum; + /* 26 = the number of characters per line sprintf'ed */ + if ((p - buf + 26) > count) + break; + if (pnp_bios_get_dev_node(&nodenum, 1, node)) + break; + p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n", + node->handle, node->eisa_id, + node->type_code[0], node->type_code[1], + node->type_code[2], node->flags); + if (nodenum <= thisnodenum) { + printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum); + *eof = 1; + break; + } + } + kfree(node); + if (nodenum == 0xff) + *eof = 1; + *start = (char *)((off_t)nodenum - pos); + return p - buf; +} + +static int proc_read_node(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct pnp_bios_node *node; + int boot = (long)data >> 8; + u8 nodenum = (long)data; + int len; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) return -ENOMEM; + if (pnp_bios_get_dev_node(&nodenum, boot, node)) + return -EIO; + len = node->size - sizeof(struct pnp_bios_node); + memcpy(buf, node->data, len); + kfree(node); + return len; +} + +static int proc_write_node(struct file *file, const char *buf, + unsigned long count, void *data) +{ + struct pnp_bios_node *node; + int boot = (long)data >> 8; + u8 nodenum = (long)data; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) return -ENOMEM; + if ( pnp_bios_get_dev_node(&nodenum, boot, node) ) + return -EIO; + if (count != node->size - sizeof(struct pnp_bios_node)) + return -EINVAL; + memcpy(node->data, buf, count); + if (pnp_bios_set_dev_node(node->handle, boot, node) != 0) + return -EINVAL; + kfree(node); + return count; +} + +/* + * When this is called, pnpbios functions are assumed to + * work and the pnpbios_dont_use_current_config flag + * should already have been set to the appropriate value + */ +int __init pnpbios_proc_init( void ) +{ + struct pnp_bios_node *node; + struct proc_dir_entry *ent; + char name[3]; + u8 nodenum; + + if (pnp_bios_dev_node_info(&node_info)) + return -EIO; + + proc_pnp = proc_mkdir("pnp", proc_bus); + if (!proc_pnp) + return -EIO; + proc_pnp_boot = proc_mkdir("boot", proc_pnp); + if (!proc_pnp_boot) + return -EIO; + create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL); + create_proc_read_entry("configuration_info", 0, proc_pnp, proc_read_pnpconfig, NULL); + create_proc_read_entry("escd_info", S_IRUSR, proc_pnp, proc_read_escdinfo, NULL); + create_proc_read_entry("escd", S_IRUSR, proc_pnp, proc_read_escd, NULL); + create_proc_read_entry("legacy_device_resources", 0, proc_pnp, proc_read_legacyres, NULL); + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) + return -ENOMEM; + + for (nodenum=0; nodenum<0xff; ) { + u8 thisnodenum = nodenum; + if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0) + break; + sprintf(name, "%02x", node->handle); + if ( !pnpbios_dont_use_current_config ) { + ent = create_proc_entry(name, 0, proc_pnp); + if (ent) { + ent->read_proc = proc_read_node; + ent->write_proc = proc_write_node; + ent->data = (void *)(long)(node->handle); + } + } + ent = create_proc_entry(name, 0, proc_pnp_boot); + if (ent) { + ent->read_proc = proc_read_node; + ent->write_proc = proc_write_node; + ent->data = (void *)(long)(node->handle+0x100); + } + if (nodenum <= thisnodenum) { + printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_init:", (unsigned int)nodenum, (unsigned int)thisnodenum); + break; + } + } + kfree(node); + + return 0; +} + +void __exit pnpbios_proc_exit(void) +{ + int i; + char name[3]; + + if (!proc_pnp) return; + + for (i=0; i<0xff; i++) { + sprintf(name, "%02x", i); + if ( !pnpbios_dont_use_current_config ) + remove_proc_entry(name, proc_pnp); + remove_proc_entry(name, proc_pnp_boot); + } + remove_proc_entry("legacy_device_resources", proc_pnp); + remove_proc_entry("escd", proc_pnp); + remove_proc_entry("escd_info", proc_pnp); + remove_proc_entry("configuration_info", proc_pnp); + remove_proc_entry("devices", proc_pnp); + remove_proc_entry("boot", proc_pnp); + remove_proc_entry("pnp", proc_bus); + + return; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aacraid/aachba.c linux.21pre4-ac6/drivers/scsi/aacraid/aachba.c --- linux.21pre4/drivers/scsi/aacraid/aachba.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aacraid/aachba.c 2003-02-19 16:21:10.000000000 +0000 @@ -233,7 +233,8 @@ int aac_get_containers(struct aac_dev *dev) { struct fsa_scsi_hba *fsa_dev_ptr; - u32 index, status = 0; + u32 index; + int status = 0; struct aac_query_mount *dinfo; struct aac_mount *dresp; struct fib * fibptr; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7770.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7770.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7770.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7770.c 2003-01-22 22:10:29.000000000 +0000 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#21 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#27 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -56,6 +56,8 @@ #define ID_AHA_274x 0x04907771 #define ID_AHA_284xB 0x04907756 /* BIOS enabled */ #define ID_AHA_284x 0x04907757 /* BIOS disabled*/ +#define ID_OLV_274x 0x04907782 /* Olivetti OEM */ +#define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ static int aha2840_load_seeprom(struct ahc_softc *ahc); static ahc_device_setup_t ahc_aic7770_VL_setup; @@ -77,6 +79,18 @@ "Adaptec 284X SCSI adapter", ahc_aic7770_VL_setup }, + { + ID_OLV_274x, + 0xFFFFFFFF, + "Adaptec (Olivetti OEM) 274X SCSI adapter", + ahc_aic7770_EISA_setup + }, + { + ID_OLV_274xD, + 0xFFFFFFFF, + "Adaptec (Olivetti OEM) 274X Differential SCSI adapter", + ahc_aic7770_EISA_setup + }, /* Generic chip probes for devices we don't know 'exactly' */ { ID_AIC7770, @@ -105,7 +119,6 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) { u_long l; - u_long s; int error; int have_seeprom; u_int hostconf; @@ -235,13 +248,6 @@ */ ahc_outb(ahc, BCTL, ENABLE); - /* - * Allow interrupts. - */ - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, TRUE); - ahc_unlock(ahc, &s); - ahc_list_unlock(&l); return (0); @@ -274,7 +280,7 @@ if (bootverbose) printf("%s: Reading SEEPROM...", ahc_name(ahc)); have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, - /*start_addr*/0, sizeof(*sc)/2); + /*start_addr*/0, sizeof(sc)/2); if (have_seeprom) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7770_osm.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7770_osm.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7770_osm.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7770_osm.c 2003-01-22 22:10:29.000000000 +0000 @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#12 $ */ #include "aic7xxx_osm.h" @@ -61,8 +61,14 @@ uint32_t eisa_id; size_t id_size; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0) continue; + request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx"); +#else + if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") != 0) + continue; +#endif eisa_id = 0; id_size = sizeof(eisa_id); @@ -72,6 +78,7 @@ eisa_id |= inb(eisaBase + IDOFFSET + i) << ((id_size-i-1) * 8); } + release_region(eisaBase, AHC_EISA_IOSIZE); if (eisa_id & 0x80000000) continue; /* no EISA card in slot */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_core.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_core.c --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_core.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_core.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,9505 @@ +/* + * Core routines and tables shareable across OS platforms. + * + * Copyright (c) 1994-2002 Justin T. Gibbs. + * Copyright (c) 2000-2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#156 $ + * + * $FreeBSD$ + */ + +#ifdef __linux__ +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" +#include "aicasm/aicasm_insformat.h" +#else +#include +#include +#include +#endif + +/******************************** Globals *************************************/ +struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq); + +/***************************** Lookup Tables **********************************/ +char *ahd_chip_names[] = +{ + "NONE", + "aic7901", + "aic7902", + "aic7901A" +}; +static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names); + +/* + * Hardware error codes. + */ +struct ahd_hard_error_entry { + uint8_t errno; + char *errmesg; +}; + +static struct ahd_hard_error_entry ahd_hard_errors[] = { + { DSCTMOUT, "Discard Timer has timed out" }, + { ILLOPCODE, "Illegal Opcode in sequencer program" }, + { SQPARERR, "Sequencer Parity Error" }, + { DPARERR, "Data-path Parity Error" }, + { MPARERR, "Scratch or SCB Memory Parity Error" }, + { CIOPARERR, "CIOBUS Parity Error" }, +}; +static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors); + +static struct ahd_phase_table_entry ahd_phase_table[] = +{ + { P_DATAOUT, MSG_NOOP, "in Data-out phase" }, + { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" }, + { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" }, + { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" }, + { P_COMMAND, MSG_NOOP, "in Command phase" }, + { P_MESGOUT, MSG_NOOP, "in Message-out phase" }, + { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" }, + { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" }, + { P_BUSFREE, MSG_NOOP, "while idle" }, + { 0, MSG_NOOP, "in unknown phase" } +}; + +/* + * In most cases we only wish to itterate over real phases, so + * exclude the last element from the count. + */ +static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1; + +/* Our Sequencer Program */ +#include "aic79xx_seq.h" + +/**************************** Function Declarations ***************************/ +static void ahd_handle_transmission_error(struct ahd_softc *ahd); +static void ahd_handle_lqiphase_error(struct ahd_softc *ahd, + u_int lqistat1); +static int ahd_handle_pkt_busfree(struct ahd_softc *ahd, + u_int busfreetime); +static int ahd_handle_nonpkt_busfree(struct ahd_softc *ahd); +static void ahd_handle_proto_violation(struct ahd_softc *ahd); +static void ahd_force_renegotiation(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); + +static struct ahd_tmode_tstate* + ahd_alloc_tstate(struct ahd_softc *ahd, + u_int scsi_id, char channel); +#ifdef AHD_TARGET_MODE +static void ahd_free_tstate(struct ahd_softc *ahd, + u_int scsi_id, char channel, int force); +#endif +static void ahd_devlimited_syncrate(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *, + u_int *period, + u_int *ppr_options, + role_t role); +static void ahd_update_neg_table(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct ahd_transinfo *tinfo); +static void ahd_update_pending_scbs(struct ahd_softc *ahd); +static void ahd_fetch_devinfo(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_scb_devinfo(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct scb *scb); +static void ahd_setup_initiator_msgout(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct scb *scb); +static void ahd_build_transfer_msg(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_construct_sdtr(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int period, u_int offset); +static void ahd_construct_wdtr(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int bus_width); +static void ahd_construct_ppr(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int period, u_int offset, + u_int bus_width, u_int ppr_options); +static void ahd_clear_msg_state(struct ahd_softc *ahd); +static void ahd_handle_message_phase(struct ahd_softc *ahd); +typedef enum { + AHDMSG_1B, + AHDMSG_2B, + AHDMSG_EXT +} ahd_msgtype; +static int ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, + u_int msgval, int full); +static int ahd_parse_msg(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static int ahd_handle_msg_reject(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_handle_ign_wide_residue(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd); +static void ahd_handle_devreset(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int lun, cam_status status, + char *message, int verbose_level); +#if AHD_TARGET_MODE +static void ahd_setup_target_msgin(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct scb *scb); +#endif + +static u_int ahd_sglist_size(struct ahd_softc *ahd); +static u_int ahd_sglist_allocsize(struct ahd_softc *ahd); +static bus_dmamap_callback_t + ahd_dmamap_cb; +static void ahd_initialize_hscbs(struct ahd_softc *ahd); +static int ahd_init_scbdata(struct ahd_softc *ahd); +static void ahd_fini_scbdata(struct ahd_softc *ahd); +static void ahd_setup_iocell_workaround(struct ahd_softc *ahd); +static void ahd_iocell_first_selection(struct ahd_softc *ahd); +static void ahd_add_col_list(struct ahd_softc *ahd, + struct scb *scb, u_int col_idx); +static void ahd_rem_col_list(struct ahd_softc *ahd, + struct scb *scb); +static void ahd_chip_init(struct ahd_softc *ahd); +static void ahd_qinfifo_requeue(struct ahd_softc *ahd, + struct scb *prev_scb, + struct scb *scb); +static int ahd_qinfifo_count(struct ahd_softc *ahd); +static int ahd_search_scb_list(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status, + ahd_search_action action, + u_int *list_head, u_int tid); +static void ahd_stitch_tid_list(struct ahd_softc *ahd, + u_int tid_prev, u_int tid_cur, + u_int tid_next); +static void ahd_add_scb_to_free_list(struct ahd_softc *ahd, + u_int scbid); +static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, + u_int prev, u_int next, u_int tid); +static void ahd_reset_current_bus(struct ahd_softc *ahd); +static ahd_callback_t ahd_reset_poll; +static ahd_callback_t ahd_stat_timer; +#ifdef AHD_DUMP_SEQ +static void ahd_dumpseq(struct ahd_softc *ahd); +#endif +static void ahd_loadseq(struct ahd_softc *ahd); +static int ahd_check_patch(struct ahd_softc *ahd, + struct patch **start_patch, + u_int start_instr, u_int *skip_addr); +static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd, + u_int address); +static void ahd_download_instr(struct ahd_softc *ahd, + u_int instrptr, uint8_t *dconsts); +static int ahd_probe_stack_size(struct ahd_softc *ahd); +#ifdef AHD_TARGET_MODE +static void ahd_queue_lstate_event(struct ahd_softc *ahd, + struct ahd_tmode_lstate *lstate, + u_int initiator_id, + u_int event_type, + u_int event_arg); +static void ahd_update_scsiid(struct ahd_softc *ahd, + u_int targid_mask); +static int ahd_handle_target_cmd(struct ahd_softc *ahd, + struct target_cmd *cmd); +#endif + +/******************************** Private Inlines *****************************/ +static __inline void ahd_assert_atn(struct ahd_softc *ahd); +static __inline int ahd_currently_packetized(struct ahd_softc *ahd); +static __inline int ahd_set_active_fifo(struct ahd_softc *ahd); + +static __inline void +ahd_assert_atn(struct ahd_softc *ahd) +{ + ahd_outb(ahd, SCSISIGO, ATNO); +} + +/* + * Determine if the current connection has a packetized + * agreement. This does not necessarily mean that we + * are currently in a packetized transfer. We could + * just as easily be sending or receiving a message. + */ +static __inline int +ahd_currently_packetized(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + int packetized; + + saved_modes = ahd_save_modes(ahd); + if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) { + /* + * The packetized bit refers to the last + * connection, not the current one. Check + * for non-zero LQISTATE instead. + */ + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + packetized = ahd_inb(ahd, LQISTATE) != 0; + } else { + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED; + } + ahd_restore_modes(ahd, saved_modes); + return (packetized); +} + +static __inline int +ahd_set_active_fifo(struct ahd_softc *ahd) +{ + u_int active_fifo; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO; + switch (active_fifo) { + case 0: + case 1: + ahd_set_modes(ahd, active_fifo, active_fifo); + return (1); + default: + return (0); + } +} + +/************************* Sequencer Execution Control ************************/ +/* + * Restart the sequencer program from address zero + */ +void +ahd_restart(struct ahd_softc *ahd) +{ + + ahd_pause(ahd); + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + /* No more pending messages */ + ahd_clear_msg_state(ahd); + ahd_outb(ahd, SCSISIGO, 0); /* De-assert BSY */ + ahd_outb(ahd, MSG_OUT, MSG_NOOP); /* No message to send */ + ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET); + ahd_outb(ahd, SEQINTCTL, 0); + ahd_outb(ahd, LASTPHASE, P_BUSFREE); + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_outb(ahd, SAVED_SCSIID, 0xFF); + ahd_outb(ahd, SAVED_LUN, 0xFF); + + /* + * Ensure that the sequencer's idea of TQINPOS + * matches our own. The sequencer increments TQINPOS + * only after it sees a DMA complete and a reset could + * occur before the increment leaving the kernel to believe + * the command arrived but the sequencer to not. + */ + ahd_outb(ahd, TQINPOS, ahd->tqinfifonext); + + /* Always allow reselection */ + ahd_outb(ahd, SCSISEQ1, + ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP)); + /* Ensure that no DMA operations are in progress */ + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + ahd_outb(ahd, SCBHCNT, 0); + ahd_outb(ahd, CCSCBCTL, CCSCBRESET); + ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); + ahd_unpause(ahd); +} + +void +ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) +{ + ahd_mode_state saved_modes; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_FIFOS) != 0) + printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo); +#endif + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, fifo, fifo); + ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT); + if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) + ahd_outb(ahd, CCSGCTL, CCSGRESET); + ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); + ahd_outb(ahd, SG_STATE, 0); + ahd_restore_modes(ahd, saved_modes); +} + +/************************* Input/Output Queues ********************************/ +/* + * Flush and completed commands that are sitting in the command + * complete queues down on the chip but have yet to be dma'ed back up. + */ +void +ahd_flush_qoutfifo(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int saved_scbptr; + u_int ccscbctl; + u_int scbid; + u_int next_scbid; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + saved_scbptr = ahd_get_scbptr(ahd); + + /* + * Wait for any inprogress DMA to complete and clear DMA state + * if this if for an SCB in the qinfifo. + */ + while ((ccscbctl = ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) { + + if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) { + if ((ccscbctl & ARRDONE) != 0) + break; + } else if ((ccscbctl & CCSCBDONE) != 0) + break; + ahd_delay(200); + } + if ((ccscbctl & CCSCBDIR) != 0) + ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN)); + + /* + * Complete any SCBs that just finished being + * DMA'ed into the qoutfifo. + */ + ahd_run_qoutfifo(ahd); + + /* + * Manually update/complete any completed SCBs that are waiting to be + * DMA'ed back up to the host. + */ + scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); + while (!SCBID_IS_NULL(scbid)) { + uint8_t *hscb_ptr; + u_int i; + + ahd_set_scbptr(ahd, scbid); + next_scbid = ahd_inw(ahd, SCB_NEXT_COMPLETE); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - DMA-up and complete " + "SCB %d invalid\n", ahd_name(ahd), scbid); + continue; + } + hscb_ptr = (uint8_t *)scb->hscb; + for (i = 0; i < sizeof(struct hardware_scb); i++) + *hscb_ptr++ = ahd_inb(ahd, SCB_BASE + i); + + ahd_complete_scb(ahd, scb); + scbid = next_scbid; + } + ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); + + scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD); + while (!SCBID_IS_NULL(scbid)) { + + ahd_set_scbptr(ahd, scbid); + next_scbid = ahd_inw(ahd, SCB_NEXT_COMPLETE); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - Complete SCB %d invalid\n", + ahd_name(ahd), scbid); + continue; + } + + ahd_complete_scb(ahd, scb); + scbid = next_scbid; + } + ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); + ahd_set_scbptr(ahd, saved_scbptr); + + /* + * Flush the good status FIFO for compelted packetized commands. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) { + scbid = (ahd_inb(ahd, GSFIFO+1) << 8) + | ahd_inb(ahd, GSFIFO); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - GSFIFO SCB %d invalid\n", + ahd_name(ahd), scbid); + continue; + } + ahd_complete_scb(ahd, scb); + } + + /* + * Restore state. + */ + ahd_restore_modes(ahd, saved_modes); + ahd->flags |= AHD_UPDATE_PEND_CMDS; +} + +void +ahd_run_qoutfifo(struct ahd_softc *ahd) +{ + struct scb *scb; + u_int scb_index; + + if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0) + panic("ahd_run_qoutfifo recursion"); + ahd->flags |= AHD_RUNNING_QOUTFIFO; + ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD); + while ((ahd->qoutfifo[ahd->qoutfifonext] + & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) { + + scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext] + & ~QOUTFIFO_ENTRY_VALID_LE); + scb = ahd_lookup_scb(ahd, scb_index); + if (scb == NULL) { + printf("%s: WARNING no command for scb %d " + "(cmdcmplt)\nQOUTPOS = %d\n", + ahd_name(ahd), scb_index, + ahd->qoutfifonext); + ahd_dump_card_state(ahd); + } else + ahd_complete_scb(ahd, scb); + + ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1); + if (ahd->qoutfifonext == 0) + ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE; + } + ahd->flags &= ~AHD_RUNNING_QOUTFIFO; +} + +/************************* Interrupt Handling *********************************/ +void +ahd_handle_hwerrint(struct ahd_softc *ahd) +{ + /* + * Some catastrophic hardware error has occurred. + * Print it for the user and disable the controller. + */ + int i; + int error; + + error = ahd_inb(ahd, ERROR); + for (i = 0; i < num_errors; i++) { + if ((error & ahd_hard_errors[i].errno) != 0) + printf("%s: hwerrint, %s\n", + ahd_name(ahd), ahd_hard_errors[i].errmesg); + } + + ahd_dump_card_state(ahd); + panic("BRKADRINT"); + + /* Tell everyone that this HBA is no longer availible */ + ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN, + CAM_NO_HBA); + + /* Tell the system that this controller has gone away. */ + ahd_free(ahd); +} + +void +ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) +{ + u_int seqintcode; + + /* + * Save the sequencer interrupt code and clear the SEQINT + * bit. We will unpause the sequencer, if appropriate, + * after servicing the request. + */ + seqintcode = ahd_inb(ahd, SEQINTCODE); + ahd_outb(ahd, CLRINT, CLRSEQINT); + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + /* + * Unpause the sequencer and let it clear + * SEQINT by writing NO_SEQINT to it. This + * will cause the sequencer to be paused again, + * which is the expected state of this routine. + */ + ahd_unpause(ahd); + while (!ahd_is_paused(ahd)) + ; + ahd_outb(ahd, CLRINT, CLRSEQINT); + } + ahd_update_modes(ahd); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: Handle Seqint Called for code %d\n", + ahd_name(ahd), seqintcode); +#endif + switch (seqintcode) { + case ENTERING_NONPACK: + { + struct scb *scb; + u_int scbid; + + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + /* + * Somehow need to know if this + * is from a selection or reselection. + * From that, we can termine target + * ID so we at least have an I_T nexus. + */ + } else { + ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); + ahd_outb(ahd, SAVED_LUN, scb->hscb->lun); + ahd_outb(ahd, SEQ_FLAGS, 0x0); + } + if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0 + && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) { + /* + * Phase change after read stream with + * CRC error with P0 asserted on last + * packet. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Assuming LQIPHASE_NLQ with " + "P0 assertion\n", ahd_name(ahd)); +#endif + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Entering NONPACK\n", ahd_name(ahd)); +#endif + break; + } + case INVALID_SEQINT: + printf("%s: Invalid Sequencer interrupt occurred.\n", + ahd_name(ahd)); + ahd_dump_card_state(ahd); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + break; + case STATUS_OVERRUN: + { + printf("%s: Status Overrun", ahd_name(ahd)); + ahd_dump_card_state(ahd); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + break; + } + case CFG4ISTAT_INTR: + { + struct scb *scb; + u_int scbid; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + ahd_dump_card_state(ahd); + printf("CFG4ISTAT: Free SCB %d referenced", scbid); + panic("For safety"); + } + ahd_outq(ahd, HADDR, scb->sense_busaddr); + ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE); + ahd_outb(ahd, HCNT + 2, 0); + ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG); + ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN); + break; + } + case ILLEGAL_PHASE: + { + u_int bus_phase; + + bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + printf("%s: ILLEGAL_PHASE 0x%x\n", + ahd_name(ahd), bus_phase); + + switch (bus_phase) { + case P_DATAOUT: + case P_DATAIN: + case P_DATAOUT_DT: + case P_DATAIN_DT: + case P_MESGOUT: + case P_STATUS: + case P_MESGIN: + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + printf("%s: Issued Bus Reset.\n", ahd_name(ahd)); + break; + case P_COMMAND: + { + struct ahd_devinfo devinfo; + struct scb *scb; + struct ahd_initiator_tinfo *targ_info; + struct ahd_tmode_tstate *tstate; + struct ahd_transinfo *tinfo; + u_int scbid; + + /* + * If a target takes us into the command phase + * assume that it has been externally reset and + * has thus lost our previous packetized negotiation + * agreement. Since we have not sent an identify + * message and may not have fully qualified the + * connection, we change our command to TUR, assert + * ATN and ABORT the task when we go to message in + * phase. The OSM will see the REQUEUE_REQUEST + * status and retry the command. + */ + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("Invalid phase with no valid SCB. " + "Resetting bus.\n"); + ahd_reset_channel(ahd, 'A', + /*Initiate Reset*/TRUE); + break; + } + ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb), + SCB_GET_TARGET(ahd, scb), + SCB_GET_LUN(scb), + SCB_GET_CHANNEL(ahd, scb), + ROLE_INITIATOR); + targ_info = ahd_fetch_transinfo(ahd, + devinfo.channel, + devinfo.our_scsiid, + devinfo.target, + &tstate); + tinfo = &targ_info->curr; + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_ACTIVE, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_ACTIVE, /*paused*/TRUE); + ahd_outb(ahd, SCB_CDB_STORE, 0); + ahd_outb(ahd, SCB_CDB_STORE+1, 0); + ahd_outb(ahd, SCB_CDB_STORE+2, 0); + ahd_outb(ahd, SCB_CDB_STORE+3, 0); + ahd_outb(ahd, SCB_CDB_STORE+4, 0); + ahd_outb(ahd, SCB_CDB_STORE+5, 0); + ahd_outb(ahd, SCB_CDB_LEN, 6); + scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); + scb->hscb->control |= MK_MESSAGE; + ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); + /* + * The lun is 0, regardless of the SCB's lun + * as we have not sent an identify message. + */ + ahd_outb(ahd, SAVED_LUN, 0); + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_assert_atn(ahd); + scb->flags &= ~(SCB_PACKETIZED); + scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); + ahd_freeze_scb(scb); + + /* + * Allow the sequencer to continue with + * non-pack processing. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { + ahd_outb(ahd, CLRLQOINT1, 0); + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + ahd_print_path(ahd, scb); + printf("Unexpected command phase from " + "packetized target\n"); + } +#endif + break; + } + } + break; + } + case CFG4OVERRUN: + { + struct scb *scb; + u_int scb_index; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd), + ahd_inb(ahd, MODE_PTR)); + } +#endif + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + if (scb == NULL) { + /* + * Attempt to transfer to an SCB that is + * not outstanding. + */ + ahd_assert_atn(ahd); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd->msgout_buf[0] = MSG_ABORT_TASK; + ahd->msgout_len = 1; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + /* + * Clear status received flag to prevent any + * attempt to complete this bogus SCB. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL) & ~STATUS_RCVD); + } + break; + } + case DUMP_CARD_STATE: + { + ahd_dump_card_state(ahd); + break; + } + case PDATA_REINIT: + { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: PDATA_REINIT - DFCNTRL = 0x%x " + "SG_CACHE_SHADOW = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, DFCNTRL), + ahd_inb(ahd, SG_CACHE_SHADOW)); + } +#endif + ahd_reinitialize_dataptrs(ahd); + break; + } + case HOST_MSG_LOOP: + { + struct ahd_devinfo devinfo; + + /* + * The sequencer has encountered a message phase + * that requires host assistance for completion. + * While handling the message phase(s), we will be + * notified by the sequencer after each byte is + * transfered so we can track bus phase changes. + * + * If this is the first time we've seen a HOST_MSG_LOOP + * interrupt, initialize the state of the host message + * loop. + */ + ahd_fetch_devinfo(ahd, &devinfo); + if (ahd->msg_type == MSG_TYPE_NONE) { + struct scb *scb; + u_int scb_index; + u_int bus_phase; + + bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + if (bus_phase != P_MESGIN + && bus_phase != P_MESGOUT) { + printf("ahd_intr: HOST_MSG_LOOP bad " + "phase 0x%x\n", bus_phase); + /* + * Probably transitioned to bus free before + * we got here. Just punt the message. + */ + ahd_dump_card_state(ahd); + ahd_clear_intstat(ahd); + ahd_restart(ahd); + return; + } + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + if (devinfo.role == ROLE_INITIATOR) { + if (bus_phase == P_MESGOUT) + ahd_setup_initiator_msgout(ahd, + &devinfo, + scb); + else { + ahd->msg_type = + MSG_TYPE_INITIATOR_MSGIN; + ahd->msgin_index = 0; + } + } +#if AHD_TARGET_MODE + else { + if (bus_phase == P_MESGOUT) { + ahd->msg_type = + MSG_TYPE_TARGET_MSGOUT; + ahd->msgin_index = 0; + } + else + ahd_setup_target_msgin(ahd, + &devinfo, + scb); + } +#endif + } + + ahd_handle_message_phase(ahd); + break; + } + case NO_MATCH: + { + /* Ensure we don't leave the selection hardware on */ + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + + printf("%s:%c:%d: no active SCB for reconnecting " + "target - issuing BUS DEVICE RESET\n", + ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4); + printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, " + "REG0 == 0x%x ACCUM = 0x%x\n", + ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN), + ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM)); + printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, " + "SINDEX == 0x%x\n", + ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd), + ahd_find_busy_tcl(ahd, + BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID), + ahd_inb(ahd, SAVED_LUN))), + ahd_inw(ahd, SINDEX)); + printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, " + "SCB_CONTROL == 0x%x\n", + ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID), + ahd_inb_scbram(ahd, SCB_LUN), + ahd_inb_scbram(ahd, SCB_CONTROL)); + printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n", + ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI)); + printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0)); + printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0)); + ahd_dump_card_state(ahd); + ahd->msgout_buf[0] = MSG_BUS_DEV_RESET; + ahd->msgout_len = 1; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_assert_atn(ahd); + break; + } + case PROTO_VIOLATION: + { + ahd_handle_proto_violation(ahd); + break; + } + case IGN_WIDE_RES: + { + struct ahd_devinfo devinfo; + + ahd_fetch_devinfo(ahd, &devinfo); + ahd_handle_ign_wide_residue(ahd, &devinfo); + break; + } + case BAD_PHASE: + { + u_int lastphase; + + lastphase = ahd_inb(ahd, LASTPHASE); + printf("%s:%c:%d: unknown scsi bus phase %x, " + "lastphase = 0x%x. Attempting to continue\n", + ahd_name(ahd), 'A', + SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), + lastphase, ahd_inb(ahd, SCSISIGI)); + break; + } + case MISSED_BUSFREE: + { + u_int lastphase; + + lastphase = ahd_inb(ahd, LASTPHASE); + printf("%s:%c:%d: Missed busfree. " + "Lastphase = 0x%x, Curphase = 0x%x\n", + ahd_name(ahd), 'A', + SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), + lastphase, ahd_inb(ahd, SCSISIGI)); + ahd_restart(ahd); + return; + } + case DATA_OVERRUN: + { + /* + * When the sequencer detects an overrun, it + * places the controller in "BITBUCKET" mode + * and allows the target to complete its transfer. + * Unfortunately, none of the counters get updated + * when the controller is in this mode, so we have + * no way of knowing how large the overrun was. + */ + struct scb *scb; + u_int scbindex; +#ifdef AHD_DEBUG + u_int lastphase; +#endif + + scbindex = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbindex); +#ifdef AHD_DEBUG + lastphase = ahd_inb(ahd, LASTPHASE); + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + ahd_print_path(ahd, scb); + printf("data overrun detected %s. Tag == 0x%x.\n", + ahd_lookup_phase_entry(lastphase)->phasemsg, + SCB_GET_TAG(scb)); + ahd_print_path(ahd, scb); + printf("%s seen Data Phase. Length = %ld. " + "NumSGs = %d.\n", + ahd_inb(ahd, SEQ_FLAGS) & DPHASE + ? "Have" : "Haven't", + ahd_get_transfer_length(scb), scb->sg_count); + ahd_dump_sglist(scb); + } +#endif + + /* + * Set this and it will take effect when the + * target does a command complete. + */ + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); + ahd_freeze_scb(scb); + break; + } + case MKMSG_FAILED: + { + struct ahd_devinfo devinfo; + struct scb *scb; + u_int scbid; + + ahd_fetch_devinfo(ahd, &devinfo); + printf("%s:%c:%d:%d: Attempt to issue message failed\n", + ahd_name(ahd), devinfo.channel, devinfo.target, + devinfo.lun); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL + && (scb->flags & SCB_RECOVERY_SCB) != 0) + /* + * Ensure that we didn't put a second instance of this + * SCB into the QINFIFO. + */ + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_GET_TAG(scb), + ROLE_INITIATOR, /*status*/0, + SEARCH_REMOVE); + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE); + break; + } + case TASKMGMT_FUNC_COMPLETE: + { + u_int scbid; + struct scb *scb; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + u_int lun; + u_int tag; + cam_status error; + + ahd_print_path(ahd, scb); + printf("Task Management Func 0x%x Complete\n", + scb->hscb->task_management); + lun = CAM_LUN_WILDCARD; + tag = SCB_LIST_NULL; + + switch (scb->hscb->task_management) { + case SIU_TASKMGMT_ABORT_TASK: + tag = scb->hscb->tag; + case SIU_TASKMGMT_ABORT_TASK_SET: + case SIU_TASKMGMT_CLEAR_TASK_SET: + lun = scb->hscb->lun; + error = CAM_REQ_ABORTED; + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + 'A', lun, tag, ROLE_INITIATOR, + error); + break; + case SIU_TASKMGMT_LUN_RESET: + lun = scb->hscb->lun; + case SIU_TASKMGMT_TARGET_RESET: + { + struct ahd_devinfo devinfo; + + ahd_scb_devinfo(ahd, &devinfo, scb); + error = CAM_BDR_SENT; + ahd_handle_devreset(ahd, &devinfo, lun, + CAM_BDR_SENT, + lun != CAM_LUN_WILDCARD + ? "Lun Reset" + : "Target Reset", + /*verbose_level*/0); + break; + } + default: + panic("Unexpected TaskMgmt Func\n"); + break; + } + } + break; + } + case TASKMGMT_CMD_CMPLT_OKAY: + { + u_int scbid; + struct scb *scb; + + /* + * An ABORT TASK TMF failed to be delivered before + * the targeted command completed normally. + */ + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + /* + * Remove the second instance of this SCB from + * the QINFIFO if it is still there. + */ + ahd_print_path(ahd, scb); + printf("SCB completes before TMF\n"); + /* + * Handle losing the race. Wait until any + * current selection completes. We will then + * set the TMF back to zero in this SCB so that + * the sequencer doesn't bother to issue another + * sequencer interrupt for its completion. + */ + while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0 + && (ahd_inb(ahd, SSTAT0) & SELDO) == 0 + && (ahd_inb(ahd, SSTAT1) & SELTO) == 0) + ; + ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0); + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), scb->hscb->tag, + ROLE_INITIATOR, /*status*/0, + SEARCH_REMOVE); + } + break; + } + case TRACEPOINT0: + case TRACEPOINT1: + case TRACEPOINT2: + case TRACEPOINT3: + printf("%s: Tracepoint %d\n", ahd_name(ahd), + seqintcode - TRACEPOINT0); + break; + case NO_SEQINT: + break; + case SAW_HWERR: + ahd_handle_hwerrint(ahd); + break; + default: + printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd), + seqintcode); + break; + } + /* + * The sequencer is paused immediately on + * a SEQINT, so we should restart it when + * we're done. + */ + ahd_unpause(ahd); +} + +void +ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) +{ + struct scb *scb; + u_int status0; + u_int status3; + u_int status; + u_int lqistat1; + u_int lqostat0; + u_int scbid; + u_int busfreetime; + + ahd_update_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR); + status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO); + status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR); + lqistat1 = ahd_inb(ahd, LQISTAT1); + lqostat0 = ahd_inb(ahd, LQOSTAT0); + busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; + if ((status0 & (SELDI|SELDO)) != 0) { + u_int simode0; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + simode0 = ahd_inb(ahd, SIMODE0); + status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + } + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL + && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) + scb = NULL; + + /* Make sure the sequencer is in a safe location. */ + ahd_clear_critical_section(ahd); + + if ((status0 & IOERR) != 0) { + u_int now_lvd; + + now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40; + printf("%s: Transceiver State Has Changed to %s mode\n", + ahd_name(ahd), now_lvd ? "LVD" : "SE"); + ahd_outb(ahd, CLRSINT0, CLRIOERR); + /* + * A change in I/O mode is equivalent to a bus reset. + */ + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); + ahd_pause(ahd); + ahd_setup_iocell_workaround(ahd); + ahd_unpause(ahd); + } else if ((status0 & OVERRUN) != 0) { + printf("%s: SCSI offset overrun detected. Resetting bus.\n", + ahd_name(ahd)); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + } else if ((status & SCSIRSTI) != 0) { + printf("%s: Someone reset channel A\n", ahd_name(ahd)); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); + } else if ((status & SCSIPERR) != 0) { + ahd_handle_transmission_error(ahd); + } else if (lqostat0 != 0) { + printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0); + ahd_outb(ahd, CLRLQOINT0, lqostat0); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { + ahd_outb(ahd, CLRLQOINT1, 0); + } + } else if ((status & SELTO) != 0) { + u_int scbid; + + /* Stop the selection */ + ahd_outb(ahd, SCSISEQ0, 0); + + /* No more pending messages */ + ahd_clear_msg_state(ahd); + + /* Clear interrupt state */ + ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR); + + /* + * Although the driver does not care about the + * 'Selection in Progress' status bit, the busy + * LED does. SELINGO is only cleared by a sucessfull + * selection, so we must manually clear it to insure + * the LED turns off just incase no future successful + * selections occur (e.g. no devices on the bus). + */ + ahd_outb(ahd, CLRSINT0, CLRSELINGO); + + scbid = ahd_inw(ahd, WAITING_TID_HEAD); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: ahd_intr - referenced scb not " + "valid during SELTO scb(0x%x)\n", + ahd_name(ahd), scbid); + ahd_dump_card_state(ahd); + } else { + struct ahd_devinfo devinfo; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SELTO) != 0) { + ahd_print_path(ahd, scb); + printf("Saw Selection Timeout for SCB 0x%x\n", + scbid); + } +#endif + /* + * Force a renegotiation with this target just in + * case the cable was pulled and will later be + * re-attached. The target may forget its negotiation + * settings with us should it attempt to reselect + * during the interruption. The target will not issue + * a unit attention in this case, so we must always + * renegotiate. + */ + ahd_scb_devinfo(ahd, &devinfo, scb); + ahd_force_renegotiation(ahd, &devinfo); + ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT); + ahd_freeze_devq(ahd, scb); + } + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_iocell_first_selection(ahd); + ahd_unpause(ahd); + } else if ((status0 & (SELDI|SELDO)) != 0) { + ahd_iocell_first_selection(ahd); + ahd_unpause(ahd); + } else if (status3 != 0) { + printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n", + ahd_name(ahd), status3); + ahd_outb(ahd, CLRSINT3, status3); + } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) { + ahd_handle_lqiphase_error(ahd, lqistat1); + } else if ((status & BUSFREE) != 0) { + u_int lqostat1; + int restart; + int clear_fifo; + int packetized; + u_int mode; + + /* + * Clear our selection hardware as soon as possible. + * We may have an entry in the waiting Q for this target, + * that is affected by this busfree and we don't want to + * go about selecting the target while we handle the event. + */ + ahd_outb(ahd, SCSISEQ0, 0); + + /* + * Determine what we were up to at the time of + * the busfree. + */ + mode = AHD_MODE_SCSI; + busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; + lqostat1 = ahd_inb(ahd, LQOSTAT1); + switch (busfreetime) { + case BUSFREE_DFF0: + case BUSFREE_DFF1: + { + u_int scbid; + struct scb *scb; + + mode = busfreetime == BUSFREE_DFF0 + ? AHD_MODE_DFF0 : AHD_MODE_DFF1; + ahd_set_modes(ahd, mode, mode); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Invalid SCB in DFF%d " + "during unexpected busfree\n", + ahd_name(ahd), mode); + packetized = 0; + } else + packetized = (scb->flags & SCB_PACKETIZED) != 0; + clear_fifo = 1; + break; + } + case BUSFREE_LQO: + clear_fifo = 0; + packetized = 1; + break; + default: + clear_fifo = 0; + packetized = (lqostat1 & LQOBUSFREE) != 0; + if (!packetized + && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) + packetized = 1; + break; + } + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("Saw Busfree. Busfreetime = 0x%x.\n", + busfreetime); +#endif + /* + * Busfrees that occur in non-packetized phases are + * handled by the nonpkt_busfree handler. + */ + if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) { + restart = ahd_handle_pkt_busfree(ahd, busfreetime); + } else { + packetized = 0; + restart = ahd_handle_nonpkt_busfree(ahd); + } + /* + * Clear the busfree interrupt status. The setting of + * the interrupt is a pulse, so in a perfect world, we + * would not need to muck with the ENBUSFREE logic. This + * would ensure that if the bus moves on to another + * connection, busfree protection is still in force. If + * BUSFREEREV is broken, however, we must manually clear + * the ENBUSFREE if the busfree occurred during a non-pack + * connection so that we don't get false positives during + * future, packetized, connections. + */ + ahd_outb(ahd, CLRSINT1, CLRBUSFREE); + if (packetized == 0 + && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0) + ahd_outb(ahd, SIMODE1, + ahd_inb(ahd, SIMODE1) & ~ENBUSFREE); + + if (clear_fifo) + ahd_clear_fifo(ahd, mode); + + ahd_clear_msg_state(ahd); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + if (restart) { + ahd_restart(ahd); + } else { + ahd_unpause(ahd); + } + } else { + printf("%s: Missing case in ahd_handle_scsiint. status = %x\n", + ahd_name(ahd), status); + ahd_dump_card_state(ahd); + ahd_clear_intstat(ahd); + ahd_unpause(ahd); + } +} + +static void +ahd_handle_transmission_error(struct ahd_softc *ahd) +{ + struct scb *scb; + u_int scbid; + u_int lqistat1; + u_int lqistat2; + u_int msg_out; + u_int curphase; + u_int lastphase; + u_int perrdiag; + u_int cur_col; + int silent; + + scb = NULL; + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ); + lqistat2 = ahd_inb(ahd, LQISTAT2); + if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0 + && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) { + u_int lqistate; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + lqistate = ahd_inb(ahd, LQISTATE); + if ((lqistate >= 0x1E && lqistate <= 0x24) + || (lqistate == 0x29)) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: NLQCRC found via LQISTATE\n", + ahd_name(ahd)); + } +#endif + lqistat1 |= LQICRCI_NLQ; + } + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + } + + ahd_outb(ahd, CLRLQIINT1, lqistat1); + lastphase = ahd_inb(ahd, LASTPHASE); + curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + perrdiag = ahd_inb(ahd, PERRDIAG); + msg_out = MSG_INITIATOR_DET_ERR; + ahd_outb(ahd, CLRSINT1, CLRSCSIPERR); + + /* + * Try to find the SCB associated with this error. + */ + silent = FALSE; + if (lqistat1 == 0 + || (lqistat1 & LQICRCI_NLQ) != 0) { + if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0) + ahd_set_active_fifo(ahd); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL && SCB_IS_SILENT(scb)) + silent = TRUE; + } + + cur_col = 0; + if (silent == FALSE) { + printf("%s: Transmission error detected\n", ahd_name(ahd)); + ahd_lqistat1_print(lqistat1, &cur_col, 50); + ahd_lastphase_print(lastphase, &cur_col, 50); + ahd_scsisigi_print(curphase, &cur_col, 50); + ahd_perrdiag_print(perrdiag, &cur_col, 50); + printf("\n"); + ahd_dump_card_state(ahd); + } + + if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) { + if (silent == FALSE) { + printf("%s: Gross protocol error during incoming " + "packet. lqistat1 == 0x%x. Resetting bus.\n", + ahd_name(ahd), lqistat1); + } + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + return; + } else if ((lqistat1 & LQICRCI_LQ) != 0) { + /* + * A CRC error has been detected on an incoming LQ. + * The bus is currently hung on the last ACK. + * Hit LQIRETRY to release the last ack, and + * wait for the sequencer to determine that ATNO + * is asserted while in message out to take us + * to our host message loop. No NONPACKREQ or + * LQIPHASE type errors will occur in this + * scenario. After this first LQIRETRY, the LQI + * manager will be in ISELO where it will + * happily sit until another packet phase begins. + * Unexpected bus free detection is enabled + * through any phases that occur after we release + * this last ack until the LQI manager sees a + * packet phase. This implies we may have to + * ignore a perfectly valid "unexected busfree" + * after our "initiator detected error" message is + * sent. A busfree is the expected response after + * we tell the target that it's L_Q was corrupted. + * (SPI4R09 10.7.3.3.3) + */ + ahd_outb(ahd, LQCTL2, LQIRETRY); + printf("LQIRetry for LQICRCI_LQ to release ACK\n"); + } else if ((lqistat1 & LQICRCI_NLQ) != 0) { + /* + * We detected a CRC error in a NON-LQ packet. + * The hardware has varying behavior in this situation + * depending on whether this packet was part of a + * stream or not. + * + * PKT by PKT mode: + * The hardware has already acked the complete packet. + * If the target honors our outstanding ATN condition, + * we should be (or soon will be) in MSGOUT phase. + * This will trigger the LQIPHASE_LQ status bit as the + * hardware was expecting another LQ. Unexpected + * busfree detection is enabled. Once LQIPHASE_LQ is + * true (first entry into host message loop is much + * the same), we must clear LQIPHASE_LQ and hit + * LQIRETRY so the hardware is ready to handle + * a future LQ. NONPACKREQ will not be asserted again + * once we hit LQIRETRY until another packet is + * processed. The target may either go busfree + * or start another packet in response to our message. + * + * Read Streaming P0 asserted: + * If we raise ATN and the target completes the entire + * stream (P0 asserted during the last packet), the + * hardware will ack all data and return to the ISTART + * state. When the target reponds to our ATN condition, + * LQIPHASE_LQ will be asserted. We should respond to + * this with an LQIRETRY to prepare for any future + * packets. NONPACKREQ will not be asserted again + * once we hit LQIRETRY until another packet is + * processed. The target may either go busfree or + * start another packet in response to our message. + * Busfree detection is enabled. + * + * Read Streaming P0 not asserted: + * If we raise ATN and the target transitions to + * MSGOUT in or after a packet where P0 is not + * asserted, the hardware will assert LQIPHASE_NLQ. + * We should respond to the LQIPHASE_NLQ with an + * LQIRETRY. Should the target stay in a non-pkt + * phase after we send our message, the hardware + * will assert LQIPHASE_LQ. Recovery is then just as + * listed above for the read streaming with P0 asserted. + * Busfree detection is enabled. + */ + if (silent == FALSE) + printf("LQICRC_NLQ\n"); + if (scb == NULL) { + printf("%s: No SCB valid for LQICRC_NLQ. " + "Resetting bus\n", ahd_name(ahd)); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + return; + } + } else if ((lqistat1 & LQIBADLQI) != 0) { + printf("Need to handle BADLQI!\n"); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + return; + } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) { + if ((curphase & ~P_DATAIN_DT) != 0) { + /* Ack the byte. So we can continue. */ + if (silent == FALSE) + printf("Acking %s to clear perror\n", + ahd_lookup_phase_entry(curphase)->phasemsg); + ahd_inb(ahd, SCSIDAT); + } + + if (curphase == P_MESGIN) + msg_out = MSG_PARITY_ERROR; + } + + /* + * We've set the hardware to assert ATN if we + * get a parity error on "in" phases, so all we + * need to do is stuff the message buffer with + * the appropriate message. "In" phases have set + * mesg_out to something other than MSG_NOP. + */ + ahd->send_msg_perror = msg_out; + if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR) + scb->flags |= SCB_TRANSMISSION_ERROR; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_unpause(ahd); +} + +static void +ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1) +{ + /* + * Clear the sources of the interrupts. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRLQIINT1, lqistat1); + + /* + * If the "illegal" phase changes were in response + * to our ATN to flag a CRC error, AND we ended up + * on packet boundaries, clear the error, restart the + * LQI manager as appropriate, and go on our merry + * way toward sending the message. Otherwise, reset + * the bus to clear the error. + */ + ahd_set_active_fifo(ahd); + if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0 + && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) { + if ((lqistat1 & LQIPHASE_LQ) != 0) { + printf("LQIRETRY for LQIPHASE_LQ\n"); + ahd_outb(ahd, LQCTL2, LQIRETRY); + } else if ((lqistat1 & LQIPHASE_NLQ) != 0) { + printf("LQIRETRY for LQIPHASE_NLQ\n"); + ahd_outb(ahd, LQCTL2, LQIRETRY); + } else + panic("ahd_handle_lqiphase_error: No phase errors\n"); + ahd_dump_card_state(ahd); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_unpause(ahd); + } else { + printf("Reseting Channel for LQI Phase error\n"); + ahd_dump_card_state(ahd); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + } +} + +/* + * Packetized unexpected or expected busfree. + * Entered in mode based on busfreetime. + */ +static int +ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) +{ + u_int lqostat1; + + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + lqostat1 = ahd_inb(ahd, LQOSTAT1); + if ((lqostat1 & LQOBUSFREE) != 0) { + struct scb *scb; + u_int scbid; + u_int saved_scbptr; + u_int waiting_h; + u_int waiting_t; + u_int next; + + if ((busfreetime & BUSFREE_LQO) == 0) + printf("%s: Warning, BUSFREE time is 0x%x. " + "Expected BUSFREE_LQO.\n", + ahd_name(ahd), busfreetime); + /* + * The LQO manager detected an unexpected busfree + * either: + * + * 1) During an outgoing LQ. + * 2) After an outgoing LQ but before the first + * REQ of the command packet. + * 3) During an outgoing command packet. + * + * In all cases, CURRSCB is pointing to the + * SCB that encountered the failure. Clean + * up the queue, clear SELDO and LQOBUSFREE, + * and allow the sequencer to restart the select + * out at its lesure. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + scbid = ahd_inw(ahd, CURRSCB); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) + panic("SCB not valid during LQOBUSFREE"); + /* + * Return the LQO manager to its idle loop. It will + * not do this automatically if the busfree occurs + * after the first REQ of either the LQ or command + * packet or between the LQ and command packet. + */ + ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE); + + /* + * Clear the status. + */ + ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) + ahd_outb(ahd, CLRLQOINT1, 0); + ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + ahd_outb(ahd, CLRSINT0, CLRSELDO); + + /* + * Update the waiting for selection queue so + * we restart on the correct SCB. + */ + waiting_h = ahd_inw(ahd, WAITING_TID_HEAD); + saved_scbptr = ahd_get_scbptr(ahd); + if (waiting_h != scbid) { + + ahd_outw(ahd, WAITING_TID_HEAD, scbid); + waiting_t = ahd_inw(ahd, WAITING_TID_TAIL); + next = SCB_LIST_NULL; + if (waiting_t == waiting_h) { + ahd_outw(ahd, WAITING_TID_TAIL, scbid); + } else { + ahd_set_scbptr(ahd, waiting_h); + next = ahd_inw(ahd, SCB_NEXT2); + } + ahd_set_scbptr(ahd, scbid); + ahd_outw(ahd, SCB_NEXT2, next); + } + ahd_set_scbptr(ahd, saved_scbptr); + if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) { + if (SCB_IS_SILENT(scb) == FALSE) { + ahd_print_path(ahd, scb); + printf("Probable outgoing LQ CRC error. " + "Retrying command\n"); + } + scb->crc_retry_count++; + } else { + ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); + ahd_freeze_scb(scb); + ahd_freeze_devq(ahd, scb); + } + /* Return unpausing the sequencer. */ + return (0); + } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) { + /* + * Ignore what are really parity errors that + * occur on the last REQ of a free running + * clock prior to going busfree. Some drives + * do not properly active negate just before + * going busfree resulting in a parity glitch. + */ + ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0) + printf("%s: Parity on last REQ detected " + "during busfree phase.\n", + ahd_name(ahd)); +#endif + /* Return unpausing the sequencer. */ + return (0); + } + if (ahd->src_mode != AHD_MODE_SCSI) { + u_int scbid; + struct scb *scb; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + ahd_print_path(ahd, scb); + printf("Unexpected PKT busfree condition\n"); + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A', + SCB_GET_LUN(scb), SCB_GET_TAG(scb), + ROLE_INITIATOR, CAM_UNEXP_BUSFREE); + + /* Return restarting the sequencer. */ + return (1); + } + printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd)); + ahd_dump_card_state(ahd); + /* Restart the sequencer. */ + return (1); +} + +/* + * Non-packetized unexpected or expected busfree. + */ +static int +ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) +{ + struct ahd_devinfo devinfo; + struct scb *scb; + u_int lastphase; + u_int saved_scsiid; + u_int saved_lun; + u_int target; + u_int initiator_role_id; + u_int scbid; + u_int ppr_busfree; + int printerror; + + /* + * Look at what phase we were last in. If its message out, + * chances are pretty good that the busfree was in response + * to one of our abort requests. + */ + lastphase = ahd_inb(ahd, LASTPHASE); + saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); + saved_lun = ahd_inb(ahd, SAVED_LUN); + target = SCSIID_TARGET(ahd, saved_scsiid); + initiator_role_id = SCSIID_OUR_ID(saved_scsiid); + ahd_compile_devinfo(&devinfo, initiator_role_id, + target, saved_lun, 'A', ROLE_INITIATOR); + printerror = 1; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL + && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) + scb = NULL; + + ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0; + if (lastphase == P_MESGOUT) { + u_int tag; + + tag = SCB_LIST_NULL; + if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE) + || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) { + int found; + int sent_msg; + + if (scb == NULL) { + ahd_print_devinfo(ahd, &devinfo); + printf("Abort for unidentified " + "connection completed.\n"); + /* restart the sequencer. */ + return (1); + } + sent_msg = ahd->msgout_buf[ahd->msgout_index - 1]; + ahd_print_path(ahd, scb); + printf("SCB %d - Abort%s Completed.\n", + SCB_GET_TAG(scb), + sent_msg == MSG_ABORT_TAG ? "" : " Tag"); + + if (sent_msg == MSG_ABORT_TAG) + tag = SCB_GET_TAG(scb); + + if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) { + /* + * This abort is in response to an + * unexpected switch to command phase + * for a packetized connection. Since + * the identify message was never sent, + * "saved lun" is 0. We really want to + * abort only the SCB that encountered + * this error, which could have a different + * lun. The SCB will be retried so the OS + * will see the UA after renegotiating to + * packetized. + */ + tag = SCB_GET_TAG(scb); + saved_lun = scb->hscb->lun; + } + found = ahd_abort_scbs(ahd, target, 'A', saved_lun, + tag, ROLE_INITIATOR, + CAM_REQ_ABORTED); + printf("found == 0x%x\n", found); + printerror = 0; + } else if (ahd_sent_msg(ahd, AHDMSG_1B, + MSG_BUS_DEV_RESET, TRUE)) { +#ifdef __FreeBSD__ + /* + * Don't mark the user's request for this BDR + * as completing with CAM_BDR_SENT. CAM3 + * specifies CAM_REQ_CMP. + */ + if (scb != NULL + && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV + && ahd_match_scb(ahd, scb, target, 'A', + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR)) + ahd_set_transaction_status(scb, CAM_REQ_CMP); +#endif + ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD, + CAM_BDR_SENT, "Bus Device Reset", + /*verbose_level*/0); + printerror = 0; + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE) + && ppr_busfree == 0) { + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + /* + * PPR Rejected. Try non-ppr negotiation + * and retry command. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("PPR negotiation rejected busfree.\n"); +#endif + tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, + devinfo.our_scsiid, + devinfo.target, &tstate); + tinfo->curr.transport_version = 2; + tinfo->goal.transport_version = 2; + tinfo->goal.ppr_options = 0; + ahd_qinfifo_requeue_tail(ahd, scb); + printerror = 0; + } else if ((ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) + || ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)) + && ppr_busfree == 0) { + /* + * Negotiation Rejected. Go-async and + * retry command. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Negotiation rejected busfree.\n"); +#endif + ahd_set_width(ahd, &devinfo, + MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, + /*period*/0, /*offset*/0, + /*ppr_options*/0, + AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + ahd_qinfifo_requeue_tail(ahd, scb); + printerror = 0; + } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 + && ahd_sent_msg(ahd, AHDMSG_1B, + MSG_INITIATOR_DET_ERR, TRUE)) { + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Expected IDE Busfree\n"); +#endif + printerror = 0; + } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE) + && ahd_sent_msg(ahd, AHDMSG_1B, + MSG_MESSAGE_REJECT, TRUE)) { + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Expected QAS Reject Busfree\n"); +#endif + printerror = 0; + } + } + + /* + * The busfree required flag is honored at the end of + * the message phases. We check it last in case we + * had to send some other message that caused a busfree. + */ + if (printerror != 0 + && (lastphase == P_MESGIN || lastphase == P_MESGOUT) + && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { + + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); + ahd_freeze_scb(scb); + if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) { + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQ_ABORTED); + } else { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("PPR Negotiation Busfree.\n"); +#endif + ahd_done(ahd, scb); + } + printerror = 0; + } + if (printerror != 0) { + int aborted; + + aborted = 0; + if (scb != NULL) { + u_int tag; + + if ((scb->hscb->control & TAG_ENB) != 0) + tag = SCB_GET_TAG(scb); + else + tag = SCB_LIST_NULL; + ahd_print_path(ahd, scb); + aborted = ahd_abort_scbs(ahd, target, 'A', + SCB_GET_LUN(scb), tag, + ROLE_INITIATOR, + CAM_UNEXP_BUSFREE); + } else { + /* + * We had not fully identified this connection, + * so we cannot abort anything. + */ + printf("%s: ", ahd_name(ahd)); + } + if (lastphase != P_BUSFREE) + ahd_force_renegotiation(ahd, &devinfo); + printf("Unexpected busfree %s, %d SCBs aborted, " + "PRGMCNT == 0x%x\n", + ahd_lookup_phase_entry(lastphase)->phasemsg, + aborted, + ahd_inb(ahd, PRGMCNT) + | (ahd_inb(ahd, PRGMCNT+1) << 8)); + ahd_dump_card_state(ahd); + } + /* Always restart the sequencer. */ + return (1); +} + +static void +ahd_handle_proto_violation(struct ahd_softc *ahd) +{ + struct ahd_devinfo devinfo; + struct scb *scb; + u_int scbid; + u_int seq_flags; + u_int curphase; + u_int lastphase; + int found; + + ahd_fetch_devinfo(ahd, &devinfo); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + seq_flags = ahd_inb(ahd, SEQ_FLAGS); + curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + lastphase = ahd_inb(ahd, LASTPHASE); + if ((seq_flags & NOT_IDENTIFIED) != 0) { + + /* + * The reconnecting target either did not send an + * identify message, or did, but we didn't find an SCB + * to match. + */ + ahd_print_devinfo(ahd, &devinfo); + printf("Target did not send an IDENTIFY message. " + "LASTPHASE = 0x%x.\n", lastphase); + scb = NULL; + } else if (scb == NULL) { + /* + * We don't seem to have an SCB active for this + * transaction. Print an error and reset the bus. + */ + ahd_print_devinfo(ahd, &devinfo); + printf("No SCB found during protocol violation\n"); + goto proto_violation_reset; + } else { + ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL); + if ((seq_flags & NO_CDB_SENT) != 0) { + ahd_print_path(ahd, scb); + printf("No or incomplete CDB sent to device.\n"); + } else if ((ahd_inb(ahd, SCB_CONTROL) & STATUS_RCVD) == 0) { + /* + * The target never bothered to provide status to + * us prior to completing the command. Since we don't + * know the disposition of this command, we must attempt + * to abort it. Assert ATN and prepare to send an abort + * message. + */ + ahd_print_path(ahd, scb); + printf("Completed command without status.\n"); + } else { + ahd_print_path(ahd, scb); + printf("Unknown protocol violation.\n"); + ahd_dump_card_state(ahd); + } + } + if ((lastphase & ~P_DATAIN_DT) == 0 + || lastphase == P_COMMAND) { +proto_violation_reset: + /* + * Target either went directly to data + * phase or didn't respond to our ATN. + * The only safe thing to do is to blow + * it away with a bus reset. + */ + found = ahd_reset_channel(ahd, 'A', TRUE); + printf("%s: Issued Channel %c Bus Reset. " + "%d SCBs aborted\n", ahd_name(ahd), 'A', found); + } else { + /* + * Leave the selection hardware off in case + * this abort attempt will affect yet to + * be sent commands. + */ + ahd_outb(ahd, SCSISEQ0, + ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + ahd_assert_atn(ahd); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + if (scb == NULL) { + ahd_print_devinfo(ahd, &devinfo); + ahd->msgout_buf[0] = MSG_ABORT_TASK; + ahd->msgout_len = 1; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + } else { + ahd_print_path(ahd, scb); + scb->flags |= SCB_ABORT; + } + printf("Protocol violation %s. Attempting to abort.\n", + ahd_lookup_phase_entry(curphase)->phasemsg); + } +} + +/* + * Force renegotiation to occur the next time we initiate + * a command to the current device. + */ +static void +ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct ahd_initiator_tinfo *targ_info; + struct ahd_tmode_tstate *tstate; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, devinfo); + printf("Forcing renegotiation\n"); + } +#endif + targ_info = ahd_fetch_transinfo(ahd, + devinfo->channel, + devinfo->our_scsiid, + devinfo->target, + &tstate); + ahd_update_neg_request(ahd, devinfo, tstate, + targ_info, AHD_NEG_IF_NON_ASYNC); +} + +#define AHD_MAX_STEPS 2000 +void +ahd_clear_critical_section(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + int stepping; + int steps; + int first_instr; + u_int simode0; + u_int simode1; + u_int simode3; + u_int lqimode0; + u_int lqimode1; + u_int lqomode0; + u_int lqomode1; + + if (ahd->num_critical_sections == 0) + return; + + stepping = FALSE; + steps = 0; + first_instr = 0; + simode0 = 0; + simode1 = 0; + simode3 = 0; + lqimode0 = 0; + lqimode1 = 0; + lqomode0 = 0; + lqomode1 = 0; + saved_modes = ahd_save_modes(ahd); + for (;;) { + struct cs *cs; + u_int seqaddr; + u_int i; + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + seqaddr = ahd_inb(ahd, CURADDR) + | (ahd_inb(ahd, CURADDR+1) << 8); + + cs = ahd->critical_sections; + for (i = 0; i < ahd->num_critical_sections; i++, cs++) { + + if (cs->begin < seqaddr && cs->end >= seqaddr) + break; + } + + if (i == ahd->num_critical_sections) + break; + + if (steps > AHD_MAX_STEPS) { + printf("%s: Infinite loop in critical section\n" + "%s: First Instruction 0x%x now 0x%x\n", + ahd_name(ahd), ahd_name(ahd), first_instr, + seqaddr); + ahd_dump_card_state(ahd); + panic("critical section loop"); + } + + steps++; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: Single stepping at 0x%x\n", ahd_name(ahd), + seqaddr); +#endif + if (stepping == FALSE) { + + first_instr = seqaddr; + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + simode0 = ahd_inb(ahd, SIMODE0); + simode3 = ahd_inb(ahd, SIMODE3); + lqimode0 = ahd_inb(ahd, LQIMODE0); + lqimode1 = ahd_inb(ahd, LQIMODE1); + lqomode0 = ahd_inb(ahd, LQOMODE0); + lqomode1 = ahd_inb(ahd, LQOMODE1); + ahd_outb(ahd, SIMODE0, 0); + ahd_outb(ahd, SIMODE3, 0); + ahd_outb(ahd, LQIMODE0, 0); + ahd_outb(ahd, LQIMODE1, 0); + ahd_outb(ahd, LQOMODE0, 0); + ahd_outb(ahd, LQOMODE1, 0); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + simode1 = ahd_inb(ahd, SIMODE1); + ahd_outb(ahd, SIMODE1, ENBUSFREE); + ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP); + stepping = TRUE; + } + ahd_outb(ahd, CLRSINT1, CLRBUSFREE); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); + ahd_outb(ahd, HCNTRL, ahd->unpause); + do { + ahd_delay(200); + } while (!ahd_is_paused(ahd)); + ahd_update_modes(ahd); + } + if (stepping) { + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + ahd_outb(ahd, SIMODE0, simode0); + ahd_outb(ahd, SIMODE3, simode3); + ahd_outb(ahd, LQIMODE0, lqimode0); + ahd_outb(ahd, LQIMODE1, lqimode1); + ahd_outb(ahd, LQOMODE0, lqomode0); + ahd_outb(ahd, LQOMODE1, lqomode1); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP); + ahd_outb(ahd, SIMODE1, simode1); + } + ahd_restore_modes(ahd, saved_modes); +} + +/* + * Clear any pending interrupt status. + */ +void +ahd_clear_intstat(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + /* Clear any interrupt conditions this may have caused */ + ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2 + |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD); + ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT + |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI + |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ); + ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ + |CLRLQOATNPKT|CLRLQOTCRC); + ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS + |CLRLQOBUSFREE|CLRLQOPHACHGINPKT); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { + ahd_outb(ahd, CLRLQOINT0, 0); + ahd_outb(ahd, CLRLQOINT1, 0); + } + ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR); + ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI + |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT); + ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO + |CLRIOERR|CLROVERRUN); + ahd_outb(ahd, CLRINT, CLRSCSIINT); +} + +/**************************** Debugging Routines ******************************/ +#ifdef AHD_DEBUG +uint32_t ahd_debug = AHD_DEBUG_OPTS; +#endif +void +ahd_print_scb(struct scb *scb) +{ + struct hardware_scb *hscb; + int i; + + hscb = scb->hscb; + printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n", + (void *)scb, + hscb->control, + hscb->scsiid, + hscb->lun, + hscb->cdb_len); + printf("Shared Data: "); + for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++) + printf("%#02x", hscb->shared_data.idata.cdb[i]); + printf(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n", + (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF), + (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF), + ahd_le32toh(hscb->datacnt), + ahd_le32toh(hscb->sgptr), + SCB_GET_TAG(scb)); + ahd_dump_sglist(scb); +} + +void +ahd_dump_sglist(struct scb *scb) +{ + int i; + + if (scb->sg_count > 0) { + if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg_list; + + sg_list = (struct ahd_dma64_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint64_t addr; + uint32_t len; + + addr = ahd_le64toh(sg_list[i].addr); + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (uint32_t)((addr >> 32) & 0xFFFFFFFF), + (uint32_t)(addr & 0xFFFFFFFF), + sg_list[i].len & AHD_SG_LEN_MASK, + (sg_list[i].len & AHD_DMA_LAST_SEG) + ? " Last" : ""); + } + } else { + struct ahd_dma_seg *sg_list; + + sg_list = (struct ahd_dma_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint32_t len; + + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (len >> 24) & SG_HIGH_ADDR_BITS, + ahd_le32toh(sg_list[i].addr), + len & AHD_SG_LEN_MASK, + len & AHD_DMA_LAST_SEG ? " Last" : ""); + } + } + } +} + +/************************* Transfer Negotiation *******************************/ +/* + * Allocate per target mode instance (ID we respond to as a target) + * transfer negotiation data structures. + */ +static struct ahd_tmode_tstate * +ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel) +{ + struct ahd_tmode_tstate *master_tstate; + struct ahd_tmode_tstate *tstate; + int i; + + master_tstate = ahd->enabled_targets[ahd->our_id]; + if (ahd->enabled_targets[scsi_id] != NULL + && ahd->enabled_targets[scsi_id] != master_tstate) + panic("%s: ahd_alloc_tstate - Target already allocated", + ahd_name(ahd)); + tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT); + if (tstate == NULL) + return (NULL); + + /* + * If we have allocated a master tstate, copy user settings from + * the master tstate (taken from SRAM or the EEPROM) for this + * channel, but reset our current and goal settings to async/narrow + * until an initiator talks to us. + */ + if (master_tstate != NULL) { + memcpy(tstate, master_tstate, sizeof(*tstate)); + memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns)); + for (i = 0; i < 16; i++) { + memset(&tstate->transinfo[i].curr, 0, + sizeof(tstate->transinfo[i].curr)); + memset(&tstate->transinfo[i].goal, 0, + sizeof(tstate->transinfo[i].goal)); + } + } else + memset(tstate, 0, sizeof(*tstate)); + ahd->enabled_targets[scsi_id] = tstate; + return (tstate); +} + +#ifdef AHD_TARGET_MODE +/* + * Free per target mode instance (ID we respond to as a target) + * transfer negotiation data structures. + */ +static void +ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force) +{ + struct ahd_tmode_tstate *tstate; + + /* + * Don't clean up our "master" tstate. + * It has our default user settings. + */ + if (scsi_id == ahd->our_id + && force == FALSE) + return; + + tstate = ahd->enabled_targets[scsi_id]; + if (tstate != NULL) + free(tstate, M_DEVBUF); + ahd->enabled_targets[scsi_id] = NULL; +} +#endif + +/* + * Called when we have an active connection to a target on the bus, + * this function finds the nearest period to the input period limited + * by the capabilities of the bus connectivity of and sync settings for + * the target. + */ +void +ahd_devlimited_syncrate(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int *period, u_int *ppr_options, role_t role) +{ + struct ahd_transinfo *transinfo; + u_int maxsync; + + if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0 + && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) { + maxsync = AHD_SYNCRATE_PACED; + } else { + maxsync = AHD_SYNCRATE_ULTRA; + /* Can't do DT related options on an SE bus */ + *ppr_options &= MSG_EXT_PPR_QAS_REQ; + } + /* + * Never allow a value higher than our current goal + * period otherwise we may allow a target initiated + * negotiation to go above the limit as set by the + * user. In the case of an initiator initiated + * sync negotiation, we limit based on the user + * setting. This allows the system to still accept + * incoming negotiations even if target initiated + * negotiation is not performed. + */ + if (role == ROLE_TARGET) + transinfo = &tinfo->user; + else + transinfo = &tinfo->goal; + *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); + if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { + maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2); + *ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } + if (transinfo->period == 0) { + *period = 0; + *ppr_options = 0; + } else { + *period = MAX(*period, transinfo->period); + ahd_find_syncrate(ahd, period, ppr_options, maxsync); + } +} + +/* + * Look up the valid period to SCSIRATE conversion in our table. + * Return the period and offset that should be sent to the target + * if this was the beginning of an SDTR. + */ +void +ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, + u_int *ppr_options, u_int maxsync) +{ + if (*period < maxsync) + *period = maxsync; + + if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0 + && *period > AHD_SYNCRATE_MIN_DT) + *ppr_options &= ~MSG_EXT_PPR_DT_REQ; + + if (*period > AHD_SYNCRATE_MIN) + *period = 0; + + /* Honor PPR option conformance rules. */ + if (*period > AHD_SYNCRATE_PACED) + *ppr_options &= ~MSG_EXT_PPR_RTI; + + if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0) + *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ); + + if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0) + *ppr_options &= MSG_EXT_PPR_QAS_REQ; + + /* Skip all PACED only entries if IU is not available */ + if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0 + && *period < AHD_SYNCRATE_DT) + *period = AHD_SYNCRATE_DT; + + /* Skip all DT only entries if DT is not available */ + if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0 + && *period < AHD_SYNCRATE_ULTRA2) + *period = AHD_SYNCRATE_ULTRA2; +} + +/* + * Truncate the given synchronous offset to a value the + * current adapter type and syncrate are capable of. + */ +void +ahd_validate_offset(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int period, u_int *offset, int wide, + role_t role) +{ + u_int maxoffset; + + /* Limit offset to what we can do */ + if (period == 0) + maxoffset = 0; + else if (period <= AHD_SYNCRATE_PACED) { + if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) + maxoffset = MAX_OFFSET_PACED_BUG; + else + maxoffset = MAX_OFFSET_PACED; + } else + maxoffset = MAX_OFFSET_NON_PACED; + *offset = MIN(*offset, maxoffset); + if (tinfo != NULL) { + if (role == ROLE_TARGET) + *offset = MIN(*offset, tinfo->user.offset); + else + *offset = MIN(*offset, tinfo->goal.offset); + } +} + +/* + * Truncate the given transfer width parameter to a value the + * current adapter type is capable of. + */ +void +ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, + u_int *bus_width, role_t role) +{ + switch (*bus_width) { + default: + if (ahd->features & AHD_WIDE) { + /* Respond Wide */ + *bus_width = MSG_EXT_WDTR_BUS_16_BIT; + break; + } + /* FALLTHROUGH */ + case MSG_EXT_WDTR_BUS_8_BIT: + *bus_width = MSG_EXT_WDTR_BUS_8_BIT; + break; + } + if (tinfo != NULL) { + if (role == ROLE_TARGET) + *bus_width = MIN(tinfo->user.width, *bus_width); + else + *bus_width = MIN(tinfo->goal.width, *bus_width); + } +} + +/* + * Update the bitmask of targets for which the controller should + * negotiate with at the next convenient oportunity. This currently + * means the next time we send the initial identify messages for + * a new transaction. + */ +int +ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct ahd_tmode_tstate *tstate, + struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type) +{ + u_int auto_negotiate_orig; + + auto_negotiate_orig = tstate->auto_negotiate; + if (neg_type == AHD_NEG_ALWAYS) { + /* + * Force our "current" settings to be + * unknown so that unless a bus reset + * occurs the need to renegotiate is + * recorded persistently. + */ + if ((ahd->features & AHD_WIDE) != 0) + tinfo->curr.width = AHD_WIDTH_UNKNOWN; + tinfo->curr.period = AHD_PERIOD_UNKNOWN; + tinfo->curr.offset = AHD_OFFSET_UNKNOWN; + } + if (tinfo->curr.period != tinfo->goal.period + || tinfo->curr.width != tinfo->goal.width + || tinfo->curr.offset != tinfo->goal.offset + || tinfo->curr.ppr_options != tinfo->goal.ppr_options + || (neg_type == AHD_NEG_IF_NON_ASYNC + && (tinfo->goal.offset != 0 + || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT + || tinfo->goal.ppr_options != 0))) + tstate->auto_negotiate |= devinfo->target_mask; + else + tstate->auto_negotiate &= ~devinfo->target_mask; + + return (auto_negotiate_orig != tstate->auto_negotiate); +} + +/* + * Update the user/goal/curr tables of synchronous negotiation + * parameters as well as, in the case of a current or active update, + * any data structures on the host controller. In the case of an + * active update, the specified target is currently talking to us on + * the bus, so the transfer parameter update must take effect + * immediately. + */ +void +ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int period, u_int offset, u_int ppr_options, + u_int type, int paused) +{ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int old_period; + u_int old_offset; + u_int old_ppr; + int active; + int update_needed; + + active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE; + update_needed = 0; + + if (period == 0 || offset == 0) { + period = 0; + offset = 0; + } + + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + + if ((type & AHD_TRANS_USER) != 0) { + tinfo->user.period = period; + tinfo->user.offset = offset; + tinfo->user.ppr_options = ppr_options; + } + + if ((type & AHD_TRANS_GOAL) != 0) { + tinfo->goal.period = period; + tinfo->goal.offset = offset; + tinfo->goal.ppr_options = ppr_options; + } + + old_period = tinfo->curr.period; + old_offset = tinfo->curr.offset; + old_ppr = tinfo->curr.ppr_options; + + if ((type & AHD_TRANS_CUR) != 0 + && (old_period != period + || old_offset != offset + || old_ppr != ppr_options)) { + + update_needed++; + + tinfo->curr.period = period; + tinfo->curr.offset = offset; + tinfo->curr.ppr_options = ppr_options; + + ahd_send_async(ahd, devinfo->channel, devinfo->target, + CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); + if (bootverbose) { + if (offset != 0) { + int options; + + printf("%s: target %d synchronous with " + "period = 0x%x, offset = 0x%x", + ahd_name(ahd), devinfo->target, + period, offset); + options = 0; + if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + printf("(DT"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + printf("%s", options ? "|IU" : "(IU"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_RTI) != 0) { + printf("%s", options ? "|RTI" : "(RTI"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { + printf("%s", options ? "|QAS" : "(QAS"); + options++; + } + if (options != 0) + printf(")\n"); + else + printf("\n"); + } else { + printf("%s: target %d using " + "asynchronous transfers%s\n", + ahd_name(ahd), devinfo->target, + (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0 + ? "(QAS)" : ""); + } + } + } + /* + * Always refresh the neg-table to handle the case of the + * sequencer setting the ENATNO bit for a MK_MESSAGE request. + * We will always renegotiate in that case if this is a + * packetized request. Also manage the busfree expected flag + * from this common routine so that we catch changes due to + * WDTR or SDTR messages. + */ + if ((type & AHD_TRANS_CUR) != 0) { + if (!paused) + ahd_pause(ahd); + ahd_update_neg_table(ahd, devinfo, &tinfo->curr); + if (!paused) + ahd_unpause(ahd); + if (ahd->msg_type != MSG_TYPE_NONE) { + if ((old_ppr & MSG_EXT_PPR_IU_REQ) + != (ppr_options & MSG_EXT_PPR_IU_REQ)) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, devinfo); + printf("Expecting IU Change busfree\n"); + } +#endif + ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE + | MSG_FLAG_IU_REQ_CHANGED; + } + if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("PPR with IU_REQ outstanding\n"); +#endif + ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE; + } + } + } + + update_needed += ahd_update_neg_request(ahd, devinfo, tstate, + tinfo, AHD_NEG_TO_GOAL); + + if (update_needed && active) + ahd_update_pending_scbs(ahd); +} + +/* + * Update the user/goal/curr tables of wide negotiation + * parameters as well as, in the case of a current or active update, + * any data structures on the host controller. In the case of an + * active update, the specified target is currently talking to us on + * the bus, so the transfer parameter update must take effect + * immediately. + */ +void +ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int width, u_int type, int paused) +{ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int oldwidth; + int active; + int update_needed; + + active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE; + update_needed = 0; + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + + if ((type & AHD_TRANS_USER) != 0) + tinfo->user.width = width; + + if ((type & AHD_TRANS_GOAL) != 0) + tinfo->goal.width = width; + + oldwidth = tinfo->curr.width; + if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) { + + update_needed++; + + tinfo->curr.width = width; + ahd_send_async(ahd, devinfo->channel, devinfo->target, + CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); + if (bootverbose) { + printf("%s: target %d using %dbit transfers\n", + ahd_name(ahd), devinfo->target, + 8 * (0x01 << width)); + } + } + + if ((type & AHD_TRANS_CUR) != 0) { + if (!paused) + ahd_pause(ahd); + ahd_update_neg_table(ahd, devinfo, &tinfo->curr); + if (!paused) + ahd_unpause(ahd); + } + + update_needed += ahd_update_neg_request(ahd, devinfo, tstate, + tinfo, AHD_NEG_TO_GOAL); + if (update_needed && active) + ahd_update_pending_scbs(ahd); + +} + +/* + * Update the current state of tagged queuing for a given target. + */ +void +ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + ahd_queue_alg alg) +{ + ahd_platform_set_tags(ahd, devinfo, alg); + ahd_send_async(ahd, devinfo->channel, devinfo->target, + devinfo->lun, AC_TRANSFER_NEG, &alg); +} + +static void +ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct ahd_transinfo *tinfo) +{ + ahd_mode_state saved_modes; + u_int period; + u_int ppr_opts; + u_int con_opts; + u_int offset; + u_int saved_negoaddr; + uint8_t iocell_opts[sizeof(ahd->iocell_opts)]; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + saved_negoaddr = ahd_inb(ahd, NEGOADDR); + ahd_outb(ahd, NEGOADDR, devinfo->target); + period = tinfo->period; + offset = tinfo->offset; + memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts)); + ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ + |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI); + con_opts = 0; + if (period == 0) + period = AHD_SYNCRATE_ASYNC; + if (period == AHD_SYNCRATE_160) { + + if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) { + /* + * When the SPI4 spec was finalized, PACE transfers + * was not made a configurable option in the PPR + * message. Instead it is assumed to be enabled for + * any syncrate faster than 80MHz. Nevertheless, + * Harpoon2A4 allows this to be configurable. + * + * Harpoon2A4 also assumes at most 2 data bytes per + * negotiated REQ/ACK offset. Paced transfers take + * 4, so we must adjust our offset. + */ + ppr_opts |= PPROPT_PACE; + offset *= 2; + + /* + * Harpoon2A assumed that there would be a + * fallback rate between 160MHz and 80Mhz, + * so 7 is used as the period factor rather + * than 8 for 160MHz. + */ + period = AHD_SYNCRATE_REVA_160; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0) + iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= + ~AHD_PRECOMP_MASK; + } else { + /* + * Precomp should be disabled for non-paced transfers. + */ + iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; + + if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0 + && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) { + /* + * Slow down our CRC interval to be + * compatible with devices that can't + * handle a CRC at full speed. + */ + con_opts |= ENSLOWCRC; + } + } + + ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW); + ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]); + ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE); + ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]); + + ahd_outb(ahd, NEGPERIOD, period); + ahd_outb(ahd, NEGPPROPTS, ppr_opts); + ahd_outb(ahd, NEGOFFSET, offset); + + if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT) + con_opts |= WIDEXFER; + + /* + * During packetized transfers, the target will + * give us the oportunity to send command packets + * without us asserting attention. + */ + if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0) + con_opts |= ENAUTOATNO; + ahd_outb(ahd, NEGCONOPTS, con_opts); + ahd_outb(ahd, NEGOADDR, saved_negoaddr); + ahd_restore_modes(ahd, saved_modes); +} + +/* + * When the transfer settings for a connection change, setup for + * negotiation in pending SCBs to effect the change as quickly as + * possible. We also cancel any negotiations that are scheduled + * for inflight SCBs that have not been started yet. + */ +static void +ahd_update_pending_scbs(struct ahd_softc *ahd) +{ + struct scb *pending_scb; + int pending_scb_count; + int i; + int paused; + u_int saved_scbptr; + ahd_mode_state saved_modes; + + /* + * Traverse the pending SCB list and ensure that all of the + * SCBs there have the proper settings. We can only safely + * clear the negotiation required flag (setting requires the + * execution queue to be modified) and this is only possible + * if we are not already attempting to select out for this + * SCB. For this reason, all callers only call this routine + * if we are changing the negotiation settings for the currently + * active transaction on the bus. + */ + pending_scb_count = 0; + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + struct ahd_devinfo devinfo; + struct hardware_scb *pending_hscb; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + ahd_scb_devinfo(ahd, &devinfo, pending_scb); + tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, + devinfo.our_scsiid, + devinfo.target, &tstate); + pending_hscb = pending_scb->hscb; + if ((tstate->auto_negotiate & devinfo.target_mask) == 0 + && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) { + pending_scb->flags &= ~SCB_AUTO_NEGOTIATE; + pending_hscb->control &= ~MK_MESSAGE; + } + ahd_sync_scb(ahd, pending_scb, + BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + pending_scb_count++; + } + + if (pending_scb_count == 0) + return; + + if (ahd_is_paused(ahd)) { + paused = 1; + } else { + paused = 0; + ahd_pause(ahd); + } + + /* + * Force the sequencer to reinitialize the selection for + * the command at the head of the execution queue if it + * has already been setup. The negotiation changes may + * effect whether we select-out with ATN. + */ + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + saved_scbptr = ahd_get_scbptr(ahd); + /* Ensure that the hscbs down on the card match the new information */ + for (i = 0; i < ahd->scb_data.maxhscbs; i++) { + struct hardware_scb *pending_hscb; + u_int control; + u_int scb_tag; + + ahd_set_scbptr(ahd, i); + scb_tag = i; + pending_scb = ahd_lookup_scb(ahd, scb_tag); + if (pending_scb == NULL) + continue; + + pending_hscb = pending_scb->hscb; + control = ahd_inb_scbram(ahd, SCB_CONTROL); + control &= ~MK_MESSAGE; + control |= pending_hscb->control & MK_MESSAGE; + ahd_outb(ahd, SCB_CONTROL, control); + } + ahd_set_scbptr(ahd, saved_scbptr); + ahd_restore_modes(ahd, saved_modes); + + if (paused == 0) + ahd_unpause(ahd); +} + +/**************************** Pathing Information *****************************/ +static void +ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + ahd_mode_state saved_modes; + u_int saved_scsiid; + role_t role; + int our_id; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + if (ahd_inb(ahd, SSTAT0) & TARGET) + role = ROLE_TARGET; + else + role = ROLE_INITIATOR; + + if (role == ROLE_TARGET + && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) { + /* We were selected, so pull our id from TARGIDIN */ + our_id = ahd_inb(ahd, TARGIDIN) & OID; + } else if (role == ROLE_TARGET) + our_id = ahd_inb(ahd, TOWNID); + else + our_id = ahd_inb(ahd, IOWNID); + + saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); + ahd_compile_devinfo(devinfo, + our_id, + SCSIID_TARGET(ahd, saved_scsiid), + ahd_inb(ahd, SAVED_LUN), + SCSIID_CHANNEL(ahd, saved_scsiid), + role); + ahd_restore_modes(ahd, saved_modes); +} + +void +ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + printf("%s:%c:%d:%d: ", ahd_name(ahd), 'A', + devinfo->target, devinfo->lun); +} + +struct ahd_phase_table_entry* +ahd_lookup_phase_entry(int phase) +{ + struct ahd_phase_table_entry *entry; + struct ahd_phase_table_entry *last_entry; + + /* + * num_phases doesn't include the default entry which + * will be returned if the phase doesn't match. + */ + last_entry = &ahd_phase_table[num_phases]; + for (entry = ahd_phase_table; entry < last_entry; entry++) { + if (phase == entry->phase) + break; + } + return (entry); +} + +void +ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target, + u_int lun, char channel, role_t role) +{ + devinfo->our_scsiid = our_id; + devinfo->target = target; + devinfo->lun = lun; + devinfo->target_offset = target; + devinfo->channel = channel; + devinfo->role = role; + if (channel == 'B') + devinfo->target_offset += 8; + devinfo->target_mask = (0x01 << devinfo->target_offset); +} + +static void +ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct scb *scb) +{ + role_t role; + int our_id; + + our_id = SCSIID_OUR_ID(scb->hscb->scsiid); + role = ROLE_INITIATOR; + if ((scb->hscb->control & TARGET_SCB) != 0) + role = ROLE_TARGET; + ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb), + SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role); +} + + +/************************ Message Phase Processing ****************************/ +/* + * When an initiator transaction with the MK_MESSAGE flag either reconnects + * or enters the initial message out phase, we are interrupted. Fill our + * outgoing message buffer with the appropriate message and beging handing + * the message phase(s) manually. + */ +static void +ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct scb *scb) +{ + /* + * To facilitate adding multiple messages together, + * each routine should increment the index and len + * variables instead of setting them explicitly. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + + if (ahd_currently_packetized(ahd)) + ahd->msg_flags |= MSG_FLAG_PACKETIZED; + + if (ahd->send_msg_perror + && ahd_inb(ahd, MSG_OUT) == HOST_MSG) { + ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror; + ahd->msgout_len++; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Setting up for Parity Error delivery\n"); +#endif + return; + } else if (scb == NULL) { + printf("%s: WARNING. No pending message for " + "I_T msgin. Issuing NO-OP\n", ahd_name(ahd)); + ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP; + ahd->msgout_len++; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + return; + } + + if ((scb->flags & SCB_DEVICE_RESET) == 0 + && (scb->flags & SCB_PACKETIZED) == 0 + && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) { + u_int identify_msg; + + identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb); + if ((scb->hscb->control & DISCENB) != 0) + identify_msg |= MSG_IDENTIFY_DISCFLAG; + ahd->msgout_buf[ahd->msgout_index++] = identify_msg; + ahd->msgout_len++; + + if ((scb->hscb->control & TAG_ENB) != 0) { + ahd->msgout_buf[ahd->msgout_index++] = + scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE); + ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb); + ahd->msgout_len += 2; + } + } + + if (scb->flags & SCB_DEVICE_RESET) { + ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET; + ahd->msgout_len++; + ahd_print_path(ahd, scb); + printf("Bus Device Reset Message Sent\n"); + /* + * Clear our selection hardware in advance of + * the busfree. We may have an entry in the waiting + * Q for this target, and we don't want to go about + * selecting while we handle the busfree and blow it + * away. + */ + ahd_outb(ahd, SCSISEQ0, 0); + } else if ((scb->flags & SCB_ABORT) != 0) { + + if ((scb->hscb->control & TAG_ENB) != 0) { + ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG; + } else { + ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT; + } + ahd->msgout_len++; + ahd_print_path(ahd, scb); + printf("Abort%s Message Sent\n", + (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : ""); + /* + * Clear our selection hardware in advance of + * the busfree. We may have an entry in the waiting + * Q for this target, and we don't want to go about + * selecting while we handle the busfree and blow it + * away. + */ + ahd_outb(ahd, SCSISEQ0, 0); + } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) { + ahd_build_transfer_msg(ahd, devinfo); + /* + * Clear our selection hardware in advance of potential + * PPR IU status change busfree. We may have an entry in + * the waiting Q for this target, and we don't want to go + * about selecting while we handle the busfree and blow + * it away. + */ + ahd_outb(ahd, SCSISEQ0, 0); + } else { + printf("ahd_intr: AWAITING_MSG for an SCB that " + "does not have a waiting message\n"); + printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid, + devinfo->target_mask); + panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x " + "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control, + ahd_inb(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT), + scb->flags); + } + + /* + * Clear the MK_MESSAGE flag from the SCB so we aren't + * asked to send this message again. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE); + scb->hscb->control &= ~MK_MESSAGE; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; +} + +/* + * Build an appropriate transfer negotiation message for the + * currently active target. + */ +static void +ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + /* + * We need to initiate transfer negotiations. + * If our current and goal settings are identical, + * we want to renegotiate due to a check condition. + */ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + int dowide; + int dosync; + int doppr; + u_int period; + u_int ppr_options; + u_int offset; + + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + /* + * Filter our period based on the current connection. + * If we can't perform DT transfers on this segment (not in LVD + * mode for instance), then our decision to issue a PPR message + * may change. + */ + period = tinfo->goal.period; + ppr_options = tinfo->goal.ppr_options; + /* Target initiated PPR is not allowed in the SCSI spec */ + if (devinfo->role == ROLE_TARGET) + ppr_options = 0; + ahd_devlimited_syncrate(ahd, tinfo, &period, + &ppr_options, devinfo->role); + dowide = tinfo->curr.width != tinfo->goal.width; + dosync = tinfo->curr.period != period; + /* + * Only use PPR if we have options that need it, even if the device + * claims to support it. There might be an expander in the way + * that doesn't. + */ + doppr = ppr_options != 0; + + if (!dowide && !dosync && !doppr) { + dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT; + dosync = tinfo->goal.period != 0; + } + + if (!dowide && !dosync && !doppr) { + /* + * Force async with a WDTR message if we have a wide bus, + * or just issue an SDTR with a 0 offset. + */ + if ((ahd->features & AHD_WIDE) != 0) + dowide = 1; + else + dosync = 1; + + if (bootverbose) { + ahd_print_devinfo(ahd, devinfo); + printf("Ensuring async\n"); + } + } + /* Target initiated PPR is not allowed in the SCSI spec */ + if (devinfo->role == ROLE_TARGET) + doppr = 0; + + /* + * Both the PPR message and SDTR message require the + * goal syncrate to be limited to what the target device + * is capable of handling (based on whether an LVD->SE + * expander is on the bus), so combine these two cases. + * Regardless, guarantee that if we are using WDTR and SDTR + * messages that WDTR comes first. + */ + if (doppr || (dosync && !dowide)) { + + offset = tinfo->goal.offset; + ahd_validate_offset(ahd, tinfo, period, &offset, + doppr ? tinfo->goal.width + : tinfo->curr.width, + devinfo->role); + if (doppr) { + ahd_construct_ppr(ahd, devinfo, period, offset, + tinfo->goal.width, ppr_options); + } else { + ahd_construct_sdtr(ahd, devinfo, period, offset); + } + } else { + ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width); + } +} + +/* + * Build a synchronous negotiation message in our message + * buffer based on the input parameters. + */ +static void +ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int period, u_int offset) +{ + if (offset == 0) + period = AHD_ASYNC_XFER_PERIOD; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR; + ahd->msgout_buf[ahd->msgout_index++] = period; + ahd->msgout_buf[ahd->msgout_index++] = offset; + ahd->msgout_len += 5; + if (bootverbose) { + printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + devinfo->lun, period, offset); + } +} + +/* + * Build a wide negotiateion message in our message + * buffer based on the input parameters. + */ +static void +ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int bus_width) +{ + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR; + ahd->msgout_buf[ahd->msgout_index++] = bus_width; + ahd->msgout_len += 4; + if (bootverbose) { + printf("(%s:%c:%d:%d): Sending WDTR %x\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + devinfo->lun, bus_width); + } +} + +/* + * Build a parallel protocol request message in our message + * buffer based on the input parameters. + */ +static void +ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int period, u_int offset, u_int bus_width, + u_int ppr_options) +{ + /* + * Always request precompensation from + * the other target if we are running + * at paced syncrates. + */ + if (period <= AHD_SYNCRATE_PACED) + ppr_options |= MSG_EXT_PPR_PCOMP_EN; + if (offset == 0) + period = AHD_ASYNC_XFER_PERIOD; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR; + ahd->msgout_buf[ahd->msgout_index++] = period; + ahd->msgout_buf[ahd->msgout_index++] = 0; + ahd->msgout_buf[ahd->msgout_index++] = offset; + ahd->msgout_buf[ahd->msgout_index++] = bus_width; + ahd->msgout_buf[ahd->msgout_index++] = ppr_options; + ahd->msgout_len += 8; + if (bootverbose) { + printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " + "offset %x, ppr_options %x\n", ahd_name(ahd), + devinfo->channel, devinfo->target, devinfo->lun, + bus_width, period, offset, ppr_options); + } +} + +/* + * Clear any active message state. + */ +static void +ahd_clear_msg_state(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd->send_msg_perror = 0; + ahd->msg_flags = MSG_FLAG_NONE; + ahd->msgout_len = 0; + ahd->msgin_index = 0; + ahd->msg_type = MSG_TYPE_NONE; + if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) { + /* + * The target didn't care to respond to our + * message request, so clear ATN. + */ + ahd_outb(ahd, CLRSINT1, CLRATNO); + } + ahd_outb(ahd, MSG_OUT, MSG_NOOP); + ahd_outb(ahd, SEQ_FLAGS2, + ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING); + ahd_restore_modes(ahd, saved_modes); +} + +/* + * Manual message loop handler. + */ +static void +ahd_handle_message_phase(struct ahd_softc *ahd) +{ + struct ahd_devinfo devinfo; + u_int bus_phase; + int end_session; + + ahd_fetch_devinfo(ahd, &devinfo); + end_session = FALSE; + bus_phase = ahd_inb(ahd, LASTPHASE); + + if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) { + printf("LQIRETRY for LQIPHASE_OUTPKT\n"); + ahd_outb(ahd, LQCTL2, LQIRETRY); + } +reswitch: + switch (ahd->msg_type) { + case MSG_TYPE_INITIATOR_MSGOUT: + { + int lastbyte; + int phasemis; + int msgdone; + + if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0) + panic("HOST_MSG_LOOP interrupt with no active message"); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("INITIATOR_MSG_OUT"); + } +#endif + phasemis = bus_phase != P_MESGOUT; + if (phasemis) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahd_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif + if (bus_phase == P_MESGIN) { + /* + * Change gears and see if + * this messages is of interest to + * us or should be passed back to + * the sequencer. + */ + ahd_outb(ahd, CLRSINT1, CLRATNO); + ahd->send_msg_perror = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN; + ahd->msgin_index = 0; + goto reswitch; + } + end_session = TRUE; + break; + } + + if (ahd->send_msg_perror) { + ahd_outb(ahd, CLRSINT1, CLRATNO); + ahd_outb(ahd, CLRSINT1, CLRREQINIT); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", ahd->send_msg_perror); +#endif + /* + * If we are notifying the target of a CRC error + * during packetized operations, the target is + * within its rights to acknowledge our message + * with a busfree. + */ + if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0 + && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR) + ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE; + + ahd_outb(ahd, RETURN_2, ahd->send_msg_perror); + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE); + break; + } + + msgdone = ahd->msgout_index == ahd->msgout_len; + if (msgdone) { + /* + * The target has requested a retry. + * Re-assert ATN, reset our message index to + * 0, and try again. + */ + ahd->msgout_index = 0; + ahd_assert_atn(ahd); + } + + lastbyte = ahd->msgout_index == (ahd->msgout_len - 1); + if (lastbyte) { + /* Last byte is signified by dropping ATN */ + ahd_outb(ahd, CLRSINT1, CLRATNO); + } + + /* + * Clear our interrupt status and present + * the next byte on the bus. + */ + ahd_outb(ahd, CLRSINT1, CLRREQINIT); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahd->msgout_buf[ahd->msgout_index]); +#endif + ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]); + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE); + break; + } + case MSG_TYPE_INITIATOR_MSGIN: + { + int phasemis; + int message_done; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("INITIATOR_MSG_IN"); + } +#endif + phasemis = bus_phase != P_MESGIN; + if (phasemis) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahd_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif + ahd->msgin_index = 0; + if (bus_phase == P_MESGOUT + && (ahd->send_msg_perror != 0 + || (ahd->msgout_len != 0 + && ahd->msgout_index == 0))) { + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + goto reswitch; + } + end_session = TRUE; + break; + } + + /* Pull the byte in without acking it */ + ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahd->msgin_buf[ahd->msgin_index]); +#endif + + message_done = ahd_parse_msg(ahd, &devinfo); + + if (message_done) { + /* + * Clear our incoming message buffer in case there + * is another message following this one. + */ + ahd->msgin_index = 0; + + /* + * If this message illicited a response, + * assert ATN so the target takes us to the + * message out phase. + */ + if (ahd->msgout_len != 0) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("Asserting ATN for response\n"); + } +#endif + ahd_assert_atn(ahd); + } + } else + ahd->msgin_index++; + + if (message_done == MSGLOOP_TERMINATED) { + end_session = TRUE; + } else { + /* Ack the byte */ + ahd_outb(ahd, CLRSINT1, CLRREQINIT); + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ); + } + break; + } + case MSG_TYPE_TARGET_MSGIN: + { + int msgdone; + int msgout_request; + + /* + * By default, the message loop will continue. + */ + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); + + if (ahd->msgout_len == 0) + panic("Target MSGIN with no active message"); + + /* + * If we interrupted a mesgout session, the initiator + * will not know this until our first REQ. So, we + * only honor mesgout requests after we've sent our + * first byte. + */ + if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0 + && ahd->msgout_index > 0) + msgout_request = TRUE; + else + msgout_request = FALSE; + + if (msgout_request) { + + /* + * Change gears and see if + * this messages is of interest to + * us or should be passed back to + * the sequencer. + */ + ahd->msg_type = MSG_TYPE_TARGET_MSGOUT; + ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO); + ahd->msgin_index = 0; + /* Dummy read to REQ for first byte */ + ahd_inb(ahd, SCSIDAT); + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) | SPIOEN); + break; + } + + msgdone = ahd->msgout_index == ahd->msgout_len; + if (msgdone) { + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) & ~SPIOEN); + end_session = TRUE; + break; + } + + /* + * Present the next byte on the bus. + */ + ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN); + ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]); + break; + } + case MSG_TYPE_TARGET_MSGOUT: + { + int lastbyte; + int msgdone; + + /* + * By default, the message loop will continue. + */ + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); + + /* + * The initiator signals that this is + * the last byte by dropping ATN. + */ + lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0; + + /* + * Read the latched byte, but turn off SPIOEN first + * so that we don't inadvertently cause a REQ for the + * next byte. + */ + ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN); + ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT); + msgdone = ahd_parse_msg(ahd, &devinfo); + if (msgdone == MSGLOOP_TERMINATED) { + /* + * The message is *really* done in that it caused + * us to go to bus free. The sequencer has already + * been reset at this point, so pull the ejection + * handle. + */ + return; + } + + ahd->msgin_index++; + + /* + * XXX Read spec about initiator dropping ATN too soon + * and use msgdone to detect it. + */ + if (msgdone == MSGLOOP_MSGCOMPLETE) { + ahd->msgin_index = 0; + + /* + * If this message illicited a response, transition + * to the Message in phase and send it. + */ + if (ahd->msgout_len != 0) { + ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO); + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) | SPIOEN); + ahd->msg_type = MSG_TYPE_TARGET_MSGIN; + ahd->msgin_index = 0; + break; + } + } + + if (lastbyte) + end_session = TRUE; + else { + /* Ask for the next byte. */ + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) | SPIOEN); + } + + break; + } + default: + panic("Unknown REQINIT message type"); + } + + if (end_session) { + if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) { + printf("%s: Returning to Idle Loop\n", + ahd_name(ahd)); + ahd_outb(ahd, LASTPHASE, P_BUSFREE); + ahd_clear_msg_state(ahd); + ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); + } else { + ahd_clear_msg_state(ahd); + ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP); + } + } +} + +/* + * See if we sent a particular extended message to the target. + * If "full" is true, return true only if the target saw the full + * message. If "full" is false, return true if the target saw at + * least the first byte of the message. + */ +static int +ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full) +{ + int found; + u_int index; + + found = FALSE; + index = 0; + + while (index < ahd->msgout_len) { + if (ahd->msgout_buf[index] == MSG_EXTENDED) { + u_int end_index; + + end_index = index + 1 + ahd->msgout_buf[index + 1]; + if (ahd->msgout_buf[index+2] == msgval + && type == AHDMSG_EXT) { + + if (full) { + if (ahd->msgout_index > end_index) + found = TRUE; + } else if (ahd->msgout_index > index) + found = TRUE; + } + index = end_index; + } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK + && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) { + + /* Skip tag type and tag id or residue param*/ + index += 2; + } else { + /* Single byte message */ + if (type == AHDMSG_1B + && ahd->msgout_index > index + && (ahd->msgout_buf[index] == msgval + || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0 + && msgval == MSG_IDENTIFYFLAG))) + found = TRUE; + index++; + } + + if (found) + break; + } + return (found); +} + +/* + * Wait for a complete incoming message, parse it, and respond accordingly. + */ +static int +ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + int reject; + int done; + int response; + + done = MSGLOOP_IN_PROG; + response = FALSE; + reject = FALSE; + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + + /* + * Parse as much of the message as is availible, + * rejecting it if we don't support it. When + * the entire message is availible and has been + * handled, return MSGLOOP_MSGCOMPLETE, indicating + * that we have parsed an entire message. + * + * In the case of extended messages, we accept the length + * byte outright and perform more checking once we know the + * extended message type. + */ + switch (ahd->msgin_buf[0]) { + case MSG_DISCONNECT: + case MSG_SAVEDATAPOINTER: + case MSG_CMDCOMPLETE: + case MSG_RESTOREPOINTERS: + case MSG_IGN_WIDE_RESIDUE: + /* + * End our message loop as these are messages + * the sequencer handles on its own. + */ + done = MSGLOOP_TERMINATED; + break; + case MSG_MESSAGE_REJECT: + response = ahd_handle_msg_reject(ahd, devinfo); + /* FALLTHROUGH */ + case MSG_NOOP: + done = MSGLOOP_MSGCOMPLETE; + break; + case MSG_EXTENDED: + { + /* Wait for enough of the message to begin validation */ + if (ahd->msgin_index < 2) + break; + switch (ahd->msgin_buf[2]) { + case MSG_EXT_SDTR: + { + u_int period; + u_int ppr_options; + u_int offset; + u_int saved_offset; + + if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) { + reject = TRUE; + break; + } + + /* + * Wait until we have both args before validating + * and acting on this message. + * + * Add one to MSG_EXT_SDTR_LEN to account for + * the extended message preamble. + */ + if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1)) + break; + + period = ahd->msgin_buf[3]; + ppr_options = 0; + saved_offset = offset = ahd->msgin_buf[4]; + ahd_devlimited_syncrate(ahd, tinfo, &period, + &ppr_options, devinfo->role); + ahd_validate_offset(ahd, tinfo, period, &offset, + tinfo->curr.width, devinfo->role); + if (bootverbose) { + printf("(%s:%c:%d:%d): Received " + "SDTR period %x, offset %x\n\t" + "Filtered to period %x, offset %x\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + ahd->msgin_buf[3], saved_offset, + period, offset); + } + ahd_set_syncrate(ahd, devinfo, period, + offset, ppr_options, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + + /* + * See if we initiated Sync Negotiation + * and didn't have to fall down to async + * transfers. + */ + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) { + /* We started it */ + if (saved_offset != offset) { + /* Went too low - force async */ + reject = TRUE; + } + } else { + /* + * Send our own SDTR in reply + */ + if (bootverbose + && devinfo->role == ROLE_INITIATOR) { + printf("(%s:%c:%d:%d): Target " + "Initiated SDTR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_construct_sdtr(ahd, devinfo, + period, offset); + ahd->msgout_index = 0; + response = TRUE; + } + done = MSGLOOP_MSGCOMPLETE; + break; + } + case MSG_EXT_WDTR: + { + u_int bus_width; + u_int saved_width; + u_int sending_reply; + + sending_reply = FALSE; + if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) { + reject = TRUE; + break; + } + + /* + * Wait until we have our arg before validating + * and acting on this message. + * + * Add one to MSG_EXT_WDTR_LEN to account for + * the extended message preamble. + */ + if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1)) + break; + + bus_width = ahd->msgin_buf[3]; + saved_width = bus_width; + ahd_validate_width(ahd, tinfo, &bus_width, + devinfo->role); + if (bootverbose) { + printf("(%s:%c:%d:%d): Received WDTR " + "%x filtered to %x\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + saved_width, bus_width); + } + + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) { + /* + * Don't send a WDTR back to the + * target, since we asked first. + * If the width went higher than our + * request, reject it. + */ + if (saved_width > bus_width) { + reject = TRUE; + printf("(%s:%c:%d:%d): requested %dBit " + "transfers. Rejecting...\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + 8 * (0x01 << bus_width)); + bus_width = 0; + } + } else { + /* + * Send our own WDTR in reply + */ + if (bootverbose + && devinfo->role == ROLE_INITIATOR) { + printf("(%s:%c:%d:%d): Target " + "Initiated WDTR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_construct_wdtr(ahd, devinfo, bus_width); + ahd->msgout_index = 0; + response = TRUE; + sending_reply = TRUE; + } + ahd_set_width(ahd, devinfo, bus_width, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + /* After a wide message, we are async */ + ahd_set_syncrate(ahd, devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_ACTIVE, /*paused*/TRUE); + if (sending_reply == FALSE && reject == FALSE) { + + if (tinfo->goal.offset) { + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = TRUE; + } + } + done = MSGLOOP_MSGCOMPLETE; + break; + } + case MSG_EXT_PPR: + { + u_int period; + u_int offset; + u_int bus_width; + u_int ppr_options; + u_int saved_width; + u_int saved_offset; + u_int saved_ppr_options; + + if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) { + reject = TRUE; + break; + } + + /* + * Wait until we have all args before validating + * and acting on this message. + * + * Add one to MSG_EXT_PPR_LEN to account for + * the extended message preamble. + */ + if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1)) + break; + + period = ahd->msgin_buf[3]; + offset = ahd->msgin_buf[5]; + bus_width = ahd->msgin_buf[6]; + saved_width = bus_width; + ppr_options = ahd->msgin_buf[7]; + /* + * According to the spec, a DT only + * period factor with no DT option + * set implies async. + */ + if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0 + && period <= 9) + offset = 0; + saved_ppr_options = ppr_options; + saved_offset = offset; + + /* + * Transfer options are only available if we + * are negotiating wide. + */ + if (bus_width == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + + ahd_validate_width(ahd, tinfo, &bus_width, + devinfo->role); + ahd_devlimited_syncrate(ahd, tinfo, &period, + &ppr_options, devinfo->role); + ahd_validate_offset(ahd, tinfo, period, &offset, + bus_width, devinfo->role); + + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) { + /* + * If we are unable to do any of the + * requested options (we went too low), + * then we'll have to reject the message. + */ + if (saved_width > bus_width + || saved_offset != offset + || saved_ppr_options != ppr_options) { + reject = TRUE; + period = 0; + offset = 0; + bus_width = 0; + ppr_options = 0; + } + } else { + if (devinfo->role != ROLE_TARGET) + printf("(%s:%c:%d:%d): Target " + "Initiated PPR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + else + printf("(%s:%c:%d:%d): Initiator " + "Initiated PPR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_construct_ppr(ahd, devinfo, period, offset, + bus_width, ppr_options); + ahd->msgout_index = 0; + response = TRUE; + } + if (bootverbose) { + printf("(%s:%c:%d:%d): Received PPR width %x, " + "period %x, offset %x,options %x\n" + "\tFiltered to width %x, period %x, " + "offset %x, options %x\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + saved_width, ahd->msgin_buf[3], + saved_offset, saved_ppr_options, + bus_width, period, offset, ppr_options); + } + ahd_set_width(ahd, devinfo, bus_width, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + ahd_set_syncrate(ahd, devinfo, period, + offset, ppr_options, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + + done = MSGLOOP_MSGCOMPLETE; + break; + } + default: + /* Unknown extended message. Reject it. */ + reject = TRUE; + break; + } + break; + } +#ifdef AHD_TARGET_MODE + case MSG_BUS_DEV_RESET: + ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD, + CAM_BDR_SENT, + "Bus Device Reset Received", + /*verbose_level*/0); + ahd_restart(ahd); + done = MSGLOOP_TERMINATED; + break; + case MSG_ABORT_TAG: + case MSG_ABORT: + case MSG_CLEAR_QUEUE: + { + int tag; + + /* Target mode messages */ + if (devinfo->role != ROLE_TARGET) { + reject = TRUE; + break; + } + tag = SCB_LIST_NULL; + if (ahd->msgin_buf[0] == MSG_ABORT_TAG) + tag = ahd_inb(ahd, INITIATOR_TAG); + ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, + devinfo->lun, tag, ROLE_TARGET, + CAM_REQ_ABORTED); + + tstate = ahd->enabled_targets[devinfo->our_scsiid]; + if (tstate != NULL) { + struct ahd_tmode_lstate* lstate; + + lstate = tstate->enabled_luns[devinfo->lun]; + if (lstate != NULL) { + ahd_queue_lstate_event(ahd, lstate, + devinfo->our_scsiid, + ahd->msgin_buf[0], + /*arg*/tag); + ahd_send_lstate_events(ahd, lstate); + } + } + ahd_restart(ahd); + done = MSGLOOP_TERMINATED; + break; + } +#endif + case MSG_QAS_REQUEST: +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("%s: QAS request. SCSISIGI == 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, SCSISIGI)); +#endif + ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE; + /* FALLTHROUGH */ + case MSG_TERM_IO_PROC: + default: + reject = TRUE; + break; + } + + if (reject) { + /* + * Setup to reject the message. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 1; + ahd->msgout_buf[0] = MSG_MESSAGE_REJECT; + done = MSGLOOP_MSGCOMPLETE; + response = TRUE; + } + + if (done != MSGLOOP_IN_PROG && !response) + /* Clear the outgoing message buffer */ + ahd->msgout_len = 0; + + return (done); +} + +/* + * Process a message reject message. + */ +static int +ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + /* + * What we care about here is if we had an + * outstanding SDTR or WDTR message for this + * target. If we did, this is a signal that + * the target is refusing negotiation. + */ + struct scb *scb; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int scb_index; + u_int last_msg; + int response = 0; + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + /* Might be necessary */ + last_msg = ahd_inb(ahd, LAST_MSG); + + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) { + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE) + && tinfo->goal.period <= AHD_SYNCRATE_PACED) { + /* + * Target may not like our SPI-4 PPR Options. + * Attempt to negotiate 80MHz which will turn + * off these options. + */ + if (bootverbose) { + printf("(%s:%c:%d:%d): PPR Rejected. " + "Trying simple U160 PPR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + tinfo->goal.period = AHD_SYNCRATE_DT; + tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ + | MSG_EXT_PPR_QAS_REQ + | MSG_EXT_PPR_DT_REQ; + } else { + /* + * Target does not support the PPR message. + * Attempt to negotiate SPI-2 style. + */ + if (bootverbose) { + printf("(%s:%c:%d:%d): PPR Rejected. " + "Trying WDTR/SDTR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + tinfo->goal.ppr_options = 0; + tinfo->curr.transport_version = 2; + tinfo->goal.transport_version = 2; + } + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = 1; + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) { + + /* note 8bit xfers */ + printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using " + "8bit transfers\n", ahd_name(ahd), + devinfo->channel, devinfo->target, devinfo->lun); + ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + /* + * No need to clear the sync rate. If the target + * did not accept the command, our syncrate is + * unaffected. If the target started the negotiation, + * but rejected our response, we already cleared the + * sync rate before sending our WDTR. + */ + if (tinfo->goal.offset != tinfo->curr.offset) { + + /* Start the sync negotiation */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = 1; + } + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) { + /* note asynch xfers and clear flag */ + ahd_set_syncrate(ahd, devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + printf("(%s:%c:%d:%d): refuses synchronous negotiation. " + "Using asynchronous transfers\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) { + int tag_type; + int mask; + + tag_type = (scb->hscb->control & MSG_SIMPLE_TASK); + + if (tag_type == MSG_SIMPLE_TASK) { + printf("(%s:%c:%d:%d): refuses tagged commands. " + "Performing non-tagged I/O\n", ahd_name(ahd), + devinfo->channel, devinfo->target, devinfo->lun); + ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE); + mask = ~0x23; + } else { + printf("(%s:%c:%d:%d): refuses %s tagged commands. " + "Performing simple queue tagged I/O only\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + devinfo->lun, tag_type == MSG_ORDERED_TASK + ? "ordered" : "head of queue"); + ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC); + mask = ~0x03; + } + + /* + * Resend the identify for this CCB as the target + * may believe that the selection is invalid otherwise. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb_scbram(ahd, SCB_CONTROL) & mask); + scb->hscb->control &= mask; + ahd_set_transaction_tag(scb, /*enabled*/FALSE, + /*type*/MSG_SIMPLE_TASK); + ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG); + ahd_assert_atn(ahd); + ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun), + SCB_GET_TAG(scb)); + + /* + * Requeue all tagged commands for this target + * currently in our posession so they can be + * converted to untagged commands. + */ + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ, + SEARCH_COMPLETE); + } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) { + /* + * Most likely the device believes that we had + * previously negotiated packetized. + */ + ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE + | MSG_FLAG_IU_REQ_CHANGED; + + ahd_force_renegotiation(ahd, devinfo); + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = 1; + } else { + /* + * Otherwise, we ignore it. + */ + printf("%s:%c:%d: Message reject for %x -- ignored\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + last_msg); + } + return (response); +} + +/* + * Process an ingnore wide residue message. + */ +static void +ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + u_int scb_index; + struct scb *scb; + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + /* + * XXX Actually check data direction in the sequencer? + * Perhaps add datadir to some spare bits in the hscb? + */ + if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0 + || ahd_get_transfer_dir(scb) != CAM_DIR_IN) { + /* + * Ignore the message if we haven't + * seen an appropriate data phase yet. + */ + } else { + /* + * If the residual occurred on the last + * transfer and the transfer request was + * expected to end on an odd count, do + * nothing. Otherwise, subtract a byte + * and update the residual count accordingly. + */ + uint32_t sgptr; + + sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); + if ((sgptr & SG_LIST_NULL) != 0 + && ahd_inb(ahd, DATA_COUNT_ODD) == 1) { + /* + * If the residual occurred on the last + * transfer and the transfer request was + * expected to end on an odd count, do + * nothing. + */ + } else { + uint32_t data_cnt; + uint64_t data_addr; + uint32_t sglen; + + /* Pull in the rest of the sgptr */ + sgptr |= + (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8); + sgptr &= SG_PTR_MASK; + data_cnt = + (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+2) << 16) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+1) << 8) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT)); + + data_addr = (((uint64_t)ahd_inb(ahd, SHADDR + 7)) << 56) + | (((uint64_t)ahd_inb(ahd, SHADDR + 6)) << 48) + | (((uint64_t)ahd_inb(ahd, SHADDR + 5)) << 40) + | (((uint64_t)ahd_inb(ahd, SHADDR + 4)) << 32) + | (ahd_inb(ahd, SHADDR + 3) << 24) + | (ahd_inb(ahd, SHADDR + 2) << 16) + | (ahd_inb(ahd, SHADDR + 1) << 8) + | (ahd_inb(ahd, SHADDR)); + + data_cnt += 1; + data_addr -= 1; + + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* + * The residual sg ptr points to the next S/G + * to load so we must go back one. + */ + sg--; + sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; + if (sg != scb->sg_list + && sglen < (data_cnt & AHD_SG_LEN_MASK)) { + + sg--; + sglen = ahd_le32toh(sg->len); + /* + * Preserve High Address and SG_LIST + * bits while setting the count to 1. + */ + data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK)); + data_addr = ahd_le64toh(sg->addr) + + (sglen & AHD_SG_LEN_MASK) + - 1; + + /* + * Increment sg so it points to the + * "next" sg. + */ + sg++; + sgptr = ahd_sg_virt_to_bus(ahd, scb, + sg); + } + } else { + struct ahd_dma_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* + * The residual sg ptr points to the next S/G + * to load so we must go back one. + */ + sg--; + sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; + if (sg != scb->sg_list + && sglen < (data_cnt & AHD_SG_LEN_MASK)) { + + sg--; + sglen = ahd_le32toh(sg->len); + /* + * Preserve High Address and SG_LIST + * bits while setting the count to 1. + */ + data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK)); + data_addr = ahd_le32toh(sg->addr) + + (sglen & AHD_SG_LEN_MASK) + - 1; + + /* + * Increment sg so it points to the + * "next" sg. + */ + sg++; + sgptr = ahd_sg_virt_to_bus(ahd, scb, + sg); + } + } + ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 3, sgptr >> 24); + ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 2, sgptr >> 16); + ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 1, sgptr >> 8); + ahd_outb(ahd, SCB_RESIDUAL_SGPTR, sgptr); + + ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24); + ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16); + ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8); + ahd_outb(ahd, SCB_RESIDUAL_DATACNT, data_cnt); + + /* + * The FIFO's pointers will be updated if/when the + * sequencer re-enters a data phase. + */ + } + } +} + + +/* + * Reinitialize the data pointers for the active transfer + * based on its current residual. + */ +static void +ahd_reinitialize_dataptrs(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int scb_index; + u_int wait; + uint32_t sgptr; + uint32_t resid; + uint64_t dataptr; + + AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK, + AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK); + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + + /* + * Release and reacquire the FIFO so we + * have a clean slate. + */ + ahd_outb(ahd, DFFSXFRCTL, CLRCHN); + wait = 1000; + do { + ahd_delay(100); + } while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE)); + if (wait == 0) { + ahd_print_path(ahd, scb); + printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n"); + ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT); + } + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, DFFSTAT, + ahd_inb(ahd, DFFSTAT) + | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0)); + + /* + * Determine initial values for data_addr and data_cnt + * for resuming the data phase. + */ + sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8) + | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); + sgptr &= SG_PTR_MASK; + + resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8) + | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT); + + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* The residual sg_ptr always points to the next sg */ + sg--; + + dataptr = ahd_le64toh(sg->addr) + + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) + - resid; + ahd_outb(ahd, HADDR + 7, dataptr >> 56); + ahd_outb(ahd, HADDR + 6, dataptr >> 48); + ahd_outb(ahd, HADDR + 5, dataptr >> 40); + ahd_outb(ahd, HADDR + 4, dataptr >> 32); + } else { + struct ahd_dma_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* The residual sg_ptr always points to the next sg */ + sg--; + + dataptr = ahd_le32toh(sg->addr) + + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) + - resid; + ahd_outb(ahd, HADDR + 4, + (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24); + } + ahd_outb(ahd, HADDR + 3, dataptr >> 24); + ahd_outb(ahd, HADDR + 2, dataptr >> 16); + ahd_outb(ahd, HADDR + 1, dataptr >> 8); + ahd_outb(ahd, HADDR, dataptr); + ahd_outb(ahd, HCNT + 2, resid >> 16); + ahd_outb(ahd, HCNT + 1, resid >> 8); + ahd_outb(ahd, HCNT, resid); +} + +/* + * Handle the effects of issuing a bus device reset message. + */ +static void +ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int lun, cam_status status, char *message, + int verbose_level) +{ +#ifdef AHD_TARGET_MODE + struct ahd_tmode_tstate* tstate; +#endif + int found; + + found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, + lun, SCB_LIST_NULL, devinfo->role, + status); + +#ifdef AHD_TARGET_MODE + /* + * Send an immediate notify ccb to all target mord peripheral + * drivers affected by this action. + */ + tstate = ahd->enabled_targets[devinfo->our_scsiid]; + if (tstate != NULL) { + u_int cur_lun; + u_int max_lun; + + if (lun != CAM_LUN_WILDCARD) { + cur_lun = 0; + max_lun = AHD_NUM_LUNS - 1; + } else { + cur_lun = lun; + max_lun = lun; + } + for (cur_lun <= max_lun; cur_lun++) { + struct ahd_tmode_lstate* lstate; + + lstate = tstate->enabled_luns[cur_lun]; + if (lstate == NULL) + continue; + + ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid, + MSG_BUS_DEV_RESET, /*arg*/0); + ahd_send_lstate_events(ahd, lstate); + } + } +#endif + + /* + * Go back to async/narrow transfers and renegotiate. + */ + ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR, /*paused*/TRUE); + ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0, + /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE); + + ahd_send_async(ahd, devinfo->channel, devinfo->target, + lun, AC_SENT_BDR, NULL); + + if (message != NULL + && (verbose_level <= bootverbose)) + printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), + message, devinfo->channel, devinfo->target, found); +} + +#ifdef AHD_TARGET_MODE +static void +ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct scb *scb) +{ + + /* + * To facilitate adding multiple messages together, + * each routine should increment the index and len + * variables instead of setting them explicitly. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + + if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0) + ahd_build_transfer_msg(ahd, devinfo); + else + panic("ahd_intr: AWAITING target message with no message"); + + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_TARGET_MSGIN; +} +#endif +/**************************** Initialization **********************************/ +static u_int +ahd_sglist_size(struct ahd_softc *ahd) +{ + bus_size_t list_size; + + list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG; + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG; + return (list_size); +} + +/* + * Calculate the optimum S/G List allocation size. S/G elements used + * for a given transaction must be physically contiguous. Assume the + * OS will allocate full pages to us, so it doesn't make sense to request + * less than a page. + */ +static u_int +ahd_sglist_allocsize(struct ahd_softc *ahd) +{ + bus_size_t sg_list_increment; + bus_size_t sg_list_size; + bus_size_t max_list_size; + bus_size_t best_list_size; + + /* Start out with the minimum required for AHD_NSEG. */ + sg_list_increment = ahd_sglist_size(ahd); + sg_list_size = sg_list_increment; + + /* Get us as close as possible to a page in size. */ + while ((sg_list_size + sg_list_increment) <= PAGE_SIZE) + sg_list_size += sg_list_increment; + + /* + * Try to reduce the amount of wastage by allocating + * multiple pages. + */ + best_list_size = sg_list_size; + max_list_size = roundup(sg_list_increment, PAGE_SIZE); + if (max_list_size < 4 * PAGE_SIZE) + max_list_size = 4 * PAGE_SIZE; + if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment)) + max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment); + while ((sg_list_size + sg_list_increment) <= max_list_size + && (sg_list_size % PAGE_SIZE) != 0) { + bus_size_t new_mod; + bus_size_t best_mod; + + sg_list_size += sg_list_increment; + new_mod = sg_list_size % PAGE_SIZE; + best_mod = best_list_size % PAGE_SIZE; + if (new_mod > best_mod || new_mod == 0) { + best_list_size = sg_list_size; + } + } + return (best_list_size); +} + +/* + * Allocate a controller structure for a new device + * and perform initial initializion. + */ +struct ahd_softc * +ahd_alloc(void *platform_arg, char *name) +{ + struct ahd_softc *ahd; + +#ifndef __FreeBSD__ + ahd = malloc(sizeof(*ahd), M_DEVBUF, M_NOWAIT); + if (!ahd) { + printf("aic7xxx: cannot malloc softc!\n"); + free(name, M_DEVBUF); + return NULL; + } +#else + ahd = device_get_softc((device_t)platform_arg); +#endif + memset(ahd, 0, sizeof(*ahd)); + ahd->seep_config = malloc(sizeof(*ahd->seep_config), + M_DEVBUF, M_NOWAIT); + if (ahd->seep_config == NULL) { +#ifndef __FreeBSD__ + free(ahd, M_DEVBUF); +#endif + free(name, M_DEVBUF); + return (NULL); + } + LIST_INIT(&ahd->pending_scbs); + /* We don't know our unit number until the OSM sets it */ + ahd->name = name; + ahd->unit = -1; + ahd->description = NULL; + ahd->bus_description = NULL; + ahd->channel = 'A'; + ahd->chip = AHD_NONE; + ahd->features = AHD_FENONE; + ahd->bugs = AHD_BUGNONE; + ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A + | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A; + ahd_timer_init(&ahd->reset_timer); + ahd_timer_init(&ahd->stat_timer); + ahd->int_coalessing_timer = AHD_INT_COALESSING_TIMER_DEFAULT; + ahd->int_coalessing_maxcmds = AHD_INT_COALESSING_MAXCMDS_DEFAULT; + ahd->int_coalessing_mincmds = AHD_INT_COALESSING_MINCMDS_DEFAULT; + ahd->int_coalessing_threshold = AHD_INT_COALESSING_THRESHOLD_DEFAULT; + ahd->int_coalessing_stop_threshold = + AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT; + + if (ahd_platform_alloc(ahd, platform_arg) != 0) { + ahd_free(ahd); + ahd = NULL; + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MEMORY) != 0) { + printf("%s: scb size = 0x%x, hscb size = 0x%x\n", + ahd_name(ahd), (u_int)sizeof(struct scb), + (u_int)sizeof(struct hardware_scb)); + } +#endif + return (ahd); +} + +int +ahd_softc_init(struct ahd_softc *ahd) +{ + + ahd->unpause = 0; + ahd->pause = PAUSE; + return (0); +} + +void +ahd_softc_insert(struct ahd_softc *ahd) +{ + struct ahd_softc *list_ahd; + +#if AHD_PCI_CONFIG > 0 + /* + * Second Function PCI devices need to inherit some + * settings from function 0. + */ + if ((ahd->features & AHD_MULTI_FUNC) != 0) { + TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { + ahd_dev_softc_t list_pci; + ahd_dev_softc_t pci; + + list_pci = list_ahd->dev_softc; + pci = ahd->dev_softc; + if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci) + && ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) { + struct ahd_softc *master; + struct ahd_softc *slave; + + if (ahd_get_pci_function(list_pci) == 0) { + master = list_ahd; + slave = ahd; + } else { + master = ahd; + slave = list_ahd; + } + slave->flags &= ~AHD_BIOS_ENABLED; + slave->flags |= + master->flags & AHD_BIOS_ENABLED; + slave->flags &= ~AHD_PRIMARY_CHANNEL; + slave->flags |= + master->flags & AHD_PRIMARY_CHANNEL; + break; + } + } + } +#endif + + /* + * Insertion sort into our list of softcs. + */ + list_ahd = TAILQ_FIRST(&ahd_tailq); + while (list_ahd != NULL + && ahd_softc_comp(list_ahd, ahd) <= 0) + list_ahd = TAILQ_NEXT(list_ahd, links); + if (list_ahd != NULL) + TAILQ_INSERT_BEFORE(list_ahd, ahd, links); + else + TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links); + ahd->init_level++; +} + +/* + * Verify that the passed in softc pointer is for a + * controller that is still configured. + */ +struct ahd_softc * +ahd_find_softc(struct ahd_softc *ahd) +{ + struct ahd_softc *list_ahd; + + TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { + if (list_ahd == ahd) + return (ahd); + } + return (NULL); +} + +void +ahd_set_unit(struct ahd_softc *ahd, int unit) +{ + ahd->unit = unit; +} + +void +ahd_set_name(struct ahd_softc *ahd, char *name) +{ + if (ahd->name != NULL) + free(ahd->name, M_DEVBUF); + ahd->name = name; +} + +void +ahd_free(struct ahd_softc *ahd) +{ + int i; + + ahd_fini_scbdata(ahd); + switch (ahd->init_level) { + default: + case 5: + ahd_shutdown(ahd); + TAILQ_REMOVE(&ahd_tailq, ahd, links); + /* FALLTHROUGH */ + case 4: + ahd_dmamap_unload(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap); + /* FALLTHROUGH */ + case 3: + ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, + ahd->shared_data_dmamap); + ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap); + /* FALLTHROUGH */ + case 2: + ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); + case 1: +#ifndef __linux__ + ahd_dma_tag_destroy(ahd, ahd->buffer_dmat); +#endif + break; + case 0: + break; + } + +#ifndef __linux__ + ahd_dma_tag_destroy(ahd, ahd->parent_dmat); +#endif + ahd_platform_free(ahd); + for (i = 0; i < AHD_NUM_TARGETS; i++) { + struct ahd_tmode_tstate *tstate; + + tstate = ahd->enabled_targets[i]; + if (tstate != NULL) { +#if AHD_TARGET_MODE + int j; + + for (j = 0; j < AHD_NUM_LUNS; j++) { + struct ahd_tmode_lstate *lstate; + + lstate = tstate->enabled_luns[j]; + if (lstate != NULL) { + xpt_free_path(lstate->path); + free(lstate, M_DEVBUF); + } + } +#endif + free(tstate, M_DEVBUF); + } + } +#if AHD_TARGET_MODE + if (ahd->black_hole != NULL) { + xpt_free_path(ahd->black_hole->path); + free(ahd->black_hole, M_DEVBUF); + } +#endif + if (ahd->name != NULL) + free(ahd->name, M_DEVBUF); + if (ahd->seep_config != NULL) + free(ahd->seep_config, M_DEVBUF); + if (ahd->saved_stack != NULL) + free(ahd->saved_stack, M_DEVBUF); +#ifndef __FreeBSD__ + free(ahd, M_DEVBUF); +#endif + return; +} + +void +ahd_shutdown(void *arg) +{ + struct ahd_softc *ahd; + + ahd = (struct ahd_softc *)arg; + + /* + * Stop periodic timer callbacks. + */ + ahd_timer_stop(&ahd->reset_timer); + ahd_timer_stop(&ahd->stat_timer); + + /* This will reset most registers to 0, but not all */ + ahd_reset(ahd); +} + +/* + * Reset the controller and record some information about it + * that is only available just after a reset. + */ +int +ahd_reset(struct ahd_softc *ahd) +{ + u_int sxfrctl1; + int wait; + uint32_t cmd; + + /* + * Preserve the value of the SXFRCTL1 register for all channels. + * It contains settings that affect termination and we don't want + * to disturb the integrity of the bus. + */ + ahd_pause(ahd); + sxfrctl1 = ahd_inb(ahd, SXFRCTL1); + + cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); + if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) { + uint32_t mod_cmd; + + /* + * A4 Razor #632 + * During the assertion of CHIPRST, the chip + * does not disable its parity logic prior to + * the start of the reset. This may cause a + * parity error to be detected and thus a + * spurious SERR or PERR assertion. Disble + * PERR and SERR responses during the CHIPRST. + */ + mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + mod_cmd, /*bytes*/2); + } + ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause); + + /* + * Ensure that the reset has finished. We delay 1000us + * prior to reading the register to make sure the chip + * has sufficiently completed its reset to handle register + * accesses. + */ + wait = 1000; + do { + ahd_delay(1000); + } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK)); + + if (wait == 0) { + printf("%s: WARNING - Failed chip reset! " + "Trying to initialize anyway.\n", ahd_name(ahd)); + } + ahd_outb(ahd, HCNTRL, ahd->pause); + + if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) { + /* + * Clear any latched PCI error status and restore + * previous SERR and PERR response enables. + */ + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + 0xFF, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + cmd, /*bytes*/2); + } + /* After a reset, we know the state of the mode register. */ + ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + /* Determine chip configuration */ + ahd->features &= ~AHD_WIDE; + if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0) + ahd->features |= AHD_WIDE; + + /* + * Restore SXFRCTL1. + * + * We must always initialize STPWEN to 1 before we + * restore the saved values. STPWEN is initialized + * to a tri-state condition which can only be cleared + * by turning it on. + */ + ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); + ahd_outb(ahd, SXFRCTL1, sxfrctl1); + + /* + * If a recovery action has forced a chip reset, + * re-initialize the chip to our likeing. + */ + if (ahd->init_level > 0) + ahd_chip_init(ahd); + + return (0); +} + +/* + * Determine the number of SCBs available on the controller + */ +int +ahd_probe_scbs(struct ahd_softc *ahd) { + int i; + + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + for (i = 0; i < AHD_SCB_MAX; i++) { + int j; + + ahd_set_scbptr(ahd, i); + ahd_outw(ahd, SCB_BASE, i); + for (j = 2; j < 64; j++) + ahd_outb(ahd, SCB_BASE+j, 0); + /* Start out life as unallocated (needing an abort) */ + ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE); + if (ahd_inw_scbram(ahd, SCB_BASE) != i) + break; + ahd_set_scbptr(ahd, 0); + if (ahd_inw_scbram(ahd, SCB_BASE) != 0) + break; + } + return (i); +} + +static void +ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *baddr; + + baddr = (bus_addr_t *)arg; + *baddr = segs->ds_addr; +} + +static void +ahd_initialize_hscbs(struct ahd_softc *ahd) +{ + int i; + + for (i = 0; i < ahd->scb_data.maxhscbs; i++) { + ahd_set_scbptr(ahd, i); + + /* Clear the control byte. */ + ahd_outb(ahd, SCB_CONTROL, 0); + + /* Set the next pointer */ + ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL); + } +} + +static int +ahd_init_scbdata(struct ahd_softc *ahd) +{ + struct scb_data *scb_data; + int i; + + scb_data = &ahd->scb_data; + TAILQ_INIT(&scb_data->free_scbs); + for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++) + LIST_INIT(&scb_data->free_scb_lists[i]); + LIST_INIT(&scb_data->any_dev_free_scb_list); + SLIST_INIT(&scb_data->hscb_maps); + SLIST_INIT(&scb_data->sg_maps); + SLIST_INIT(&scb_data->sense_maps); + + /* Determine the number of hardware SCBs and initialize them */ + scb_data->maxhscbs = ahd_probe_scbs(ahd); + if (scb_data->maxhscbs == 0) { + printf("%s: No SCB space found\n", ahd_name(ahd)); + return (ENXIO); + } + + ahd_initialize_hscbs(ahd); + + /* + * Create our DMA tags. These tags define the kinds of device + * accessible memory allocations and memory mappings we will + * need to perform during normal operation. + * + * Unless we need to further restrict the allocation, we rely + * on the restrictions of the parent dmat, hence the common + * use of MAXADDR and MAXSIZE. + */ + + /* DMA tag for our hardware scb structures */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + PAGE_SIZE, /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &scb_data->hscb_dmat) != 0) { + goto error_exit; + } + + scb_data->init_level++; + + /* DMA tag for our S/G structures. */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + ahd_sglist_allocsize(ahd), /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &scb_data->sg_dmat) != 0) { + goto error_exit; + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MEMORY) != 0) + printf("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd), + ahd_sglist_allocsize(ahd)); +#endif + + scb_data->init_level++; + + /* DMA tag for our sense buffers. We allocate in page sized chunks */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + PAGE_SIZE, /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &scb_data->sense_dmat) != 0) { + goto error_exit; + } + + scb_data->init_level++; + + /* Perform initial CCB allocation */ + ahd_alloc_scbs(ahd); + + if (scb_data->numscbs == 0) { + printf("%s: ahd_init_scbdata - " + "Unable to allocate initial scbs\n", + ahd_name(ahd)); + goto error_exit; + } + + /* + * Note that we were successfull + */ + return (0); + +error_exit: + + return (ENOMEM); +} + +static struct scb * +ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag) +{ + struct scb *scb; + + /* + * Look on the pending list. + */ + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + if (SCB_GET_TAG(scb) == tag) + return (scb); + } + + /* + * Then on all of the collision free lists. + */ + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { + struct scb *list_scb; + + list_scb = scb; + do { + if (SCB_GET_TAG(list_scb) == tag) + return (list_scb); + list_scb = LIST_NEXT(list_scb, collision_links); + } while (list_scb); + } + + /* + * And finally on the generic free list. + */ + LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { + if (SCB_GET_TAG(scb) == tag) + return (scb); + } + + return (NULL); +} + +static void +ahd_fini_scbdata(struct ahd_softc *ahd) +{ + struct scb_data *scb_data; + + scb_data = &ahd->scb_data; + if (scb_data == NULL) + return; + + switch (scb_data->init_level) { + default: + case 7: + { + struct map_node *sns_map; + + while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) { + SLIST_REMOVE_HEAD(&scb_data->sense_maps, links); + ahd_dmamap_unload(ahd, scb_data->sense_dmat, + sns_map->dmamap); + ahd_dmamem_free(ahd, scb_data->sense_dmat, + sns_map->vaddr, sns_map->dmamap); + free(sns_map, M_DEVBUF); + } + ahd_dma_tag_destroy(ahd, scb_data->sense_dmat); + /* FALLTHROUGH */ + } + case 6: + { + struct map_node *sg_map; + + while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) { + SLIST_REMOVE_HEAD(&scb_data->sg_maps, links); + ahd_dmamap_unload(ahd, scb_data->sg_dmat, + sg_map->dmamap); + ahd_dmamem_free(ahd, scb_data->sg_dmat, + sg_map->vaddr, sg_map->dmamap); + free(sg_map, M_DEVBUF); + } + ahd_dma_tag_destroy(ahd, scb_data->sg_dmat); + /* FALLTHROUGH */ + } + case 5: + { + struct map_node *hscb_map; + + while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) { + SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links); + ahd_dmamap_unload(ahd, scb_data->hscb_dmat, + hscb_map->dmamap); + ahd_dmamem_free(ahd, scb_data->hscb_dmat, + hscb_map->vaddr, hscb_map->dmamap); + free(hscb_map, M_DEVBUF); + } + ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat); + /* FALLTHROUGH */ + } + case 4: + case 3: + case 2: + case 1: + case 0: + break; + } +} + +/* + * DSP filter Bypass must be enabled until the first selection + * after a change in bus mode (Razor #491 and #493). + */ +static void +ahd_setup_iocell_workaround(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL) + | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS); + ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI)); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: Setting up iocell workaround\n", ahd_name(ahd)); +#endif + ahd_restore_modes(ahd, saved_modes); +} + +static void +ahd_iocell_first_selection(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + u_int sblkctl; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + sblkctl = ahd_inb(ahd, SBLKCTL); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: iocell first selection\n", ahd_name(ahd)); +#endif + if ((sblkctl & ENAB40) != 0) { + ahd_outb(ahd, DSPDATACTL, + ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: BYPASS now disabled\n", ahd_name(ahd)); +#endif + } + ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI)); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_restore_modes(ahd, saved_modes); +} + +/*************************** SCB Management ***********************************/ +static void +ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx) +{ + struct scb_list *free_list; + struct scb_tailq *free_tailq; + struct scb *first_scb; + + scb->flags |= SCB_ON_COL_LIST; + AHD_SET_SCB_COL_IDX(scb, col_idx); + free_list = &ahd->scb_data.free_scb_lists[col_idx]; + free_tailq = &ahd->scb_data.free_scbs; + first_scb = LIST_FIRST(free_list); + if (first_scb != NULL) { + LIST_INSERT_AFTER(first_scb, scb, collision_links); + } else { + LIST_INSERT_HEAD(free_list, scb, collision_links); + TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe); + } +} + +static void +ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb) +{ + struct scb_list *free_list; + struct scb_tailq *free_tailq; + struct scb *first_scb; + u_int col_idx; + + scb->flags &= ~SCB_ON_COL_LIST; + col_idx = AHD_GET_SCB_COL_IDX(ahd, scb); + free_list = &ahd->scb_data.free_scb_lists[col_idx]; + free_tailq = &ahd->scb_data.free_scbs; + first_scb = LIST_FIRST(free_list); + if (first_scb == scb) { + struct scb *next_scb; + + /* + * Maintain order in the collision free + * lists for fairness if this device has + * other colliding tags active. + */ + next_scb = LIST_NEXT(scb, collision_links); + if (next_scb != NULL) { + TAILQ_INSERT_AFTER(free_tailq, scb, + next_scb, links.tqe); + } + TAILQ_REMOVE(free_tailq, scb, links.tqe); + } + LIST_REMOVE(scb, collision_links); +} + +/* + * Get a free scb. If there are none, see if we can allocate a new SCB. + */ +struct scb * +ahd_get_scb(struct ahd_softc *ahd, u_int col_idx) +{ + struct scb *scb; + int tries; + + tries = 0; +look_again: + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { + if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) { + ahd_rem_col_list(ahd, scb); + goto found; + } + } + if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) { + + if (tries++ != 0) + return (NULL); + ahd_alloc_scbs(ahd); + goto look_again; + } + LIST_REMOVE(scb, links.le); + if (col_idx != AHD_NEVER_COL_IDX + && (scb->col_scb != NULL) + && (scb->col_scb->flags & SCB_ACTIVE) == 0) { + LIST_REMOVE(scb->col_scb, links.le); + ahd_add_col_list(ahd, scb->col_scb, col_idx); + } +found: + scb->flags |= SCB_ACTIVE; + return (scb); +} + +/* + * Return an SCB resource to the free list. + */ +void +ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) +{ + + /* Clean up for the next user */ + scb->flags = SCB_FLAG_NONE; + scb->hscb->control = 0; + ahd->scb_data.scbindex[scb->hscb->tag] = NULL; + + if (scb->col_scb == NULL) { + + /* + * No collision possible. Just free normally. + */ + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb, links.le); + } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) { + + /* + * The SCB we might have collided with is on + * a free collision list. Put both SCBs on + * the generic list. + */ + ahd_rem_col_list(ahd, scb->col_scb); + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb, links.le); + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb->col_scb, links.le); + } else if ((scb->col_scb->flags + & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE + && (scb->col_scb->hscb->control & TAG_ENB) != 0) { + + /* + * The SCB we might collide with on the next allocation + * is still active in a non-packetized, tagged, context. + * Put us on the SCB collision list. + */ + ahd_add_col_list(ahd, scb, + AHD_GET_SCB_COL_IDX(ahd, scb->col_scb)); + } else { + /* + * The SCB we might collide with on the next allocation + * is either active in a packetized context, or free. + * Since we can't collide, put this SCB on the generic + * free list. + */ + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb, links.le); + } + + ahd_platform_scb_free(ahd, scb); +} + +void +ahd_alloc_scbs(struct ahd_softc *ahd) +{ + struct scb_data *scb_data; + struct scb *next_scb; + struct hardware_scb *hscb; + struct map_node *hscb_map; + struct map_node *sg_map; + struct map_node *sense_map; + uint8_t *segs; + uint8_t *sense_data; + bus_addr_t hscb_busaddr; + bus_addr_t sg_busaddr; + bus_addr_t sense_busaddr; + int newcount; + int i; + + scb_data = &ahd->scb_data; + if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC) + /* Can't allocate any more */ + return; + + if (scb_data->scbs_left != 0) { + int offset; + + offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left; + hscb_map = SLIST_FIRST(&scb_data->hscb_maps); + hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset]; + hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb)); + } else { + hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT); + + if (hscb_map == NULL) + return; + + /* Allocate the next batch of hardware SCBs */ + if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat, + (void **)&hscb_map->vaddr, + BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) { + free(hscb_map, M_DEVBUF); + return; + } + + SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links); + + ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap, + hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb, + &hscb_map->physaddr, /*flags*/0); + + hscb = (struct hardware_scb *)hscb_map->vaddr; + hscb_busaddr = hscb_map->physaddr; + scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb); + } + + if (scb_data->sgs_left != 0) { + int offset; + + offset = ahd_sglist_allocsize(ahd) + - (scb_data->sgs_left * ahd_sglist_size(ahd)); + sg_map = SLIST_FIRST(&scb_data->sg_maps); + segs = sg_map->vaddr + offset; + sg_busaddr = sg_map->physaddr + offset; + } else { + sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); + + if (sg_map == NULL) + return; + + /* Allocate the next batch of S/G lists */ + if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat, + (void **)&sg_map->vaddr, + BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) { + free(sg_map, M_DEVBUF); + return; + } + + SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links); + + ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap, + sg_map->vaddr, ahd_sglist_allocsize(ahd), + ahd_dmamap_cb, &sg_map->physaddr, /*flags*/0); + + segs = sg_map->vaddr; + sg_busaddr = sg_map->physaddr; + scb_data->sgs_left = + ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_MEMORY) + printf("Mapped SG data\n"); +#endif + } + + if (scb_data->sense_left != 0) { + int offset; + + offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left); + sense_map = SLIST_FIRST(&scb_data->sense_maps); + sense_data = sense_map->vaddr + offset; + sense_busaddr = sense_map->physaddr + offset; + } else { + sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT); + + if (sense_map == NULL) + return; + + /* Allocate the next batch of sense buffers */ + if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat, + (void **)&sense_map->vaddr, + BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) { + free(sense_map, M_DEVBUF); + return; + } + + SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links); + + ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap, + sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb, + &sense_map->physaddr, /*flags*/0); + + sense_data = sense_map->vaddr; + sense_busaddr = sense_map->physaddr; + scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_MEMORY) + printf("Mapped sense data\n"); +#endif + } + + newcount = MIN(scb_data->sense_left, scb_data->scbs_left); + newcount = MIN(newcount, scb_data->sgs_left); + newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); + scb_data->sense_left -= newcount; + scb_data->scbs_left -= newcount; + scb_data->sgs_left -= newcount; + for (i = 0; i < newcount; i++) { + u_int col_tag; + + struct scb_platform_data *pdata; +#ifndef __linux__ + int error; +#endif + next_scb = (struct scb *)malloc(sizeof(*next_scb), + M_DEVBUF, M_NOWAIT); + if (next_scb == NULL) + break; + + pdata = (struct scb_platform_data *)malloc(sizeof(*pdata), + M_DEVBUF, M_NOWAIT); + if (pdata == NULL) { + free(next_scb, M_DEVBUF); + break; + } + next_scb->platform_data = pdata; + next_scb->hscb_map = hscb_map; + next_scb->sg_map = sg_map; + next_scb->sense_map = sense_map; + next_scb->sg_list = segs; + next_scb->sense_data = sense_data; + next_scb->sense_busaddr = sense_busaddr; + next_scb->hscb = hscb; + hscb->hscb_busaddr = ahd_htole32(hscb_busaddr); + + /* + * The sequencer always starts with the second entry. + * The first entry is embedded in the scb. + */ + next_scb->sg_list_busaddr = sg_busaddr; + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + next_scb->sg_list_busaddr + += sizeof(struct ahd_dma64_seg); + else + next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg); + next_scb->ahd_softc = ahd; + next_scb->flags = SCB_FLAG_NONE; +#ifndef __linux__ + error = ahd_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0, + &next_scb->dmamap); + if (error != 0) { + free(next_scb, M_DEVBUF); + free(pdata, M_DEVBUF); + break; + } +#endif + next_scb->hscb->tag = ahd_htole16(scb_data->numscbs); + col_tag = scb_data->numscbs ^ 0x100; + next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag); + if (next_scb->col_scb != NULL) + next_scb->col_scb->col_scb = next_scb; + ahd_free_scb(ahd, next_scb); + hscb++; + hscb_busaddr += sizeof(*hscb); + segs += ahd_sglist_size(ahd); + sg_busaddr += ahd_sglist_size(ahd); + sense_data += AHD_SENSE_BUFSIZE; + sense_busaddr += AHD_SENSE_BUFSIZE; + scb_data->numscbs++; + } +} + +void +ahd_controller_info(struct ahd_softc *ahd, char *buf) +{ + const char *speed; + const char *type; + int len; + + len = sprintf(buf, "%s: ", ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]); + buf += len; + + speed = "Ultra320 "; + if ((ahd->features & AHD_WIDE) != 0) { + type = "Wide "; + } else { + type = "Single "; + } + len = sprintf(buf, "%s%sChannel %c, SCSI Id=%d, ", + speed, type, ahd->channel, ahd->our_id); + buf += len; + + sprintf(buf, "%s, %d SCBs", ahd->bus_description, + ahd->scb_data.maxhscbs); +} + +static const char *channel_strings[] = { + "Primary Low", + "Primary High", + "Secondary Low", + "Secondary High" +}; + +static const char *termstat_strings[] = { + "Terminated Correctly", + "Over Terminated", + "Under Terminated", + "Not Configured" +}; + +/* + * Start the board, ready for normal operation + */ +int +ahd_init(struct ahd_softc *ahd) +{ + uint8_t *base_vaddr; + uint8_t *next_vaddr; + bus_addr_t next_baddr; + size_t driver_data_size; + int i; + int error; + u_int warn_user; + uint8_t current_sensing; + uint8_t fstat; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + + ahd->stack_size = ahd_probe_stack_size(ahd); + ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t), + M_DEVBUF, M_NOWAIT); + if (ahd->saved_stack == NULL) + return (ENOMEM); + + /* + * Verify that the compiler hasn't over-agressively + * padded important structures. + */ + if (sizeof(struct hardware_scb) != 64) + panic("Hardware SCB size is incorrect"); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0) + ahd->flags |= AHD_SEQUENCER_DEBUG; +#endif + + /* + * Default to allowing initiator operations. + */ + ahd->flags |= AHD_INITIATORROLE; + + /* + * Only allow target mode features if this unit has them enabled. + */ + if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0) + ahd->features &= ~AHD_TARGETMODE; + +#ifndef __linux__ + /* DMA tag for mapping buffers into device visible space. */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/(AHD_NSEG - 1) * PAGE_SIZE, + /*nsegments*/AHD_NSEG, + /*maxsegsz*/AHD_MAXTRANSFER_SIZE, + /*flags*/BUS_DMA_ALLOCNOW, + &ahd->buffer_dmat) != 0) { + return (ENOMEM); + } +#endif + + ahd->init_level++; + + /* + * DMA tag for our command fifos and other data in system memory + * the card's sequencer must be able to access. For initiator + * roles, we need to allocate space for the qoutfifo. When providing + * for the target mode role, we must additionally provide space for + * the incoming target command fifo. + */ + driver_data_size = AHD_SCB_MAX * sizeof(uint16_t) + + sizeof(struct hardware_scb); + if ((ahd->features & AHD_TARGETMODE) != 0) + driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd); + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) + driver_data_size += PKT_OVERRUN_BUFSIZE; + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + driver_data_size, + /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &ahd->shared_data_dmat) != 0) { + return (ENOMEM); + } + + ahd->init_level++; + + /* Allocation of driver data */ + if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, + (void **)&base_vaddr, + BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) { + return (ENOMEM); + } + + ahd->init_level++; + + /* And permanently map it in */ + ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, + base_vaddr, driver_data_size, ahd_dmamap_cb, + &ahd->shared_data_busaddr, /*flags*/0); + ahd->qoutfifo = (uint16_t *)base_vaddr; + next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; + next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t); + if ((ahd->features & AHD_TARGETMODE) != 0) { + ahd->targetcmds = (struct target_cmd *)next_vaddr; + next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); + next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); + } + + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { + ahd->overrun_buf = next_vaddr; + next_vaddr += PKT_OVERRUN_BUFSIZE; + next_baddr += PKT_OVERRUN_BUFSIZE; + } + + /* + * We need one SCB to serve as the "next SCB". Since the + * tag identifier in this SCB will never be used, there is + * no point in using a valid HSCB tag from an SCB pulled from + * the standard free pool. So, we allocate this "sentinel" + * specially from the DMA safe memory chunk used for the QOUTFIFO. + */ + ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; + ahd->next_queued_hscb->hscb_busaddr = next_baddr; + + ahd->init_level++; + + /* Allocate SCB data now that buffer_dmat is initialized */ + if (ahd_init_scbdata(ahd) != 0) + return (ENOMEM); + + if ((ahd->flags & AHD_INITIATORROLE) == 0) + ahd->flags &= ~AHD_RESET_BUS_A; + + /* + * Before committing these settings to the chip, give + * the OSM one last chance to modify our configuration. + */ + ahd_platform_init(ahd); + + /* Bring up the chip. */ + ahd_chip_init(ahd); + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + + if ((ahd->flags & AHD_CURRENT_SENSING) == 0) + goto init_done; + + /* + * Verify termination based on current draw and + * warn user if the bus is over/under terminated. + */ + error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, + CURSENSE_ENB); + if (error != 0) { + printf("%s: current sensing timeout 1\n", ahd_name(ahd)); + goto init_done; + } + for (i = 20, fstat = FLX_FSTAT_BUSY; + (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) { + error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat); + if (error != 0) { + printf("%s: current sensing timeout 2\n", + ahd_name(ahd)); + goto init_done; + } + } + if (i == 0) { + printf("%s: Timedout during current-sensing test\n", + ahd_name(ahd)); + goto init_done; + } + + /* Latch Current Sensing status. */ + error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, ¤t_sensing); + if (error != 0) { + printf("%s: current sensing timeout 3\n", ahd_name(ahd)); + goto init_done; + } + + /* Diable current sensing. */ + ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) { + printf("%s: current_sensing == 0x%x\n", + ahd_name(ahd), current_sensing); + } +#endif + warn_user = 0; + for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) { + u_int term_stat; + + term_stat = (current_sensing & FLX_CSTAT_MASK); + switch (term_stat) { + case FLX_CSTAT_OVER: + case FLX_CSTAT_UNDER: + warn_user++; + case FLX_CSTAT_INVALID: + case FLX_CSTAT_OKAY: + if (warn_user == 0 && bootverbose == 0) + break; + printf("%s: %s Channel %s\n", ahd_name(ahd), + channel_strings[i], termstat_strings[term_stat]); + break; + } + } + if (warn_user) { + printf("%s: WARNING. Termination is not configured correctly.\n" + "%s: WARNING. SCSI bus operations may FAIL.\n", + ahd_name(ahd), ahd_name(ahd)); + } +init_done: + ahd_restart(ahd); + ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, + ahd_stat_timer, ahd); + return (0); +} + +/* + * (Re)initialize chip state after a chip reset. + */ +static void +ahd_chip_init(struct ahd_softc *ahd) +{ + uint32_t busaddr; + u_int sxfrctl1; + u_int scsiseq_template; + u_int wait; + u_int i; + u_int target; + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + /* + * Take the LED out of diagnostic mode + */ + ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON)); + + /* + * Return HS_MAILBOX to its default value. + */ + ahd->hs_mailbox = 0; + ahd_outb(ahd, HS_MAILBOX, 0); + + /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1. */ + ahd_outb(ahd, IOWNID, ahd->our_id); + ahd_outb(ahd, TOWNID, ahd->our_id); + sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0; + sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0; + if ((ahd->bugs & AHD_LONG_SETIMO_BUG) + && (ahd->seltime != STIMESEL_MIN)) { + /* + * The selection timer duration is twice as long + * as it should be. Halve it by adding "1" to + * the user specified setting. + */ + sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ; + } else { + sxfrctl1 |= ahd->seltime; + } + + ahd_outb(ahd, SXFRCTL0, DFON); + ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN); + ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); + + /* + * Now that termination is set, wait for up + * to 500ms for our transceivers to settle. If + * the adapter does not have a cable attached, + * the tranceivers may never settle, so don't + * complain if we fail here. + */ + for (wait = 10000; + (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait; + wait--) + ahd_delay(100); + + /* Clear any false bus resets due to the transceivers settling */ + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + + /* Initialize mode specific S/G state. */ + for (i = 0; i < 2; i++) { + ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); + ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); + ahd_outw(ahd, LONGJMP_SCB, SCB_LIST_NULL); + ahd_outb(ahd, SG_STATE, 0); + ahd_outb(ahd, CLRSEQINTSRC, 0xFF); + ahd_outb(ahd, SEQIMODE, + ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT + |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD); + } + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN); + ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75); + ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN); + ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR); + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE); + } else { + ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE); + } + ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN); + if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX) + /* + * Do not issue a target abort when a split completion + * error occurs. Let our PCIX interrupt handler deal + * with it instead. H2A4 Razor #625 + */ + ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS); + + if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0) + ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER); + + /* + * Tweak IOCELL settings. + */ + if ((ahd->flags & AHD_HP_BOARD) != 0) { + for (i = 0; i < NUMDSPS; i++) { + ahd_outb(ahd, DSPSELECT, i); + ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT); + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd), + WRTBIASCTL_HP_DEFAULT); +#endif + } + ahd_setup_iocell_workaround(ahd); + + /* + * Enable LQI Manager interrupts. + */ + ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT + | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI + | ENLQIOVERI_LQ|ENLQIOVERI_NLQ); + ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC); + /* + * An interrupt from LQOBUSFREE is made redundant by the + * BUSFREE interrupt. We choose to have the sequencer catch + * LQOPHCHGINPKT errors manually for the command phase at the + * start of a packetized selection case. + ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT); + */ + ahd_outb(ahd, LQOMODE1, 0); + + /* + * Setup sequencer interrupt handlers. + */ + ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr)); + ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr)); + + /* + * Setup SCB Offset registers. + */ + if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { + ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, + pkt_long_lun)); + } else { + ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun)); + } + ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len)); + ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute)); + ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management)); + ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb, + shared_data.idata.cdb)); + ahd_outb(ahd, QNEXTPTR, + offsetof(struct hardware_scb, next_hscb_busaddr)); + ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET); + ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control)); + if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { + ahd_outb(ahd, LUNLEN, + sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1); + } else { + ahd_outb(ahd, LUNLEN, sizeof(ahd->next_queued_hscb->lun) - 1); + } + ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1); + ahd_outb(ahd, MAXCMD, 0xFF); + ahd_outb(ahd, SCBAUTOPTR, + AUSCBPTR_EN | offsetof(struct hardware_scb, tag)); + + /* We haven't been enabled for target mode yet. */ + ahd_outb(ahd, MULTARGID, 0); + ahd_outb(ahd, MULTARGID + 1, 0); + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + /* Initialize the negotiation table. */ + if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) { + /* + * Clear the spare bytes in the neg table to avoid + * spurious parity errors. + */ + for (target = 0; target < AHD_NUM_TARGETS; target++) { + ahd_outb(ahd, NEGOADDR, target); + ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0); + for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++) + ahd_outb(ahd, ANNEXDAT, 0); + } + } + for (target = 0; target < AHD_NUM_TARGETS; target++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + target, &tstate); + ahd_compile_devinfo(&devinfo, ahd->our_id, + target, CAM_LUN_WILDCARD, + 'A', ROLE_INITIATOR); + ahd_update_neg_table(ahd, &devinfo, &tinfo->curr); + } + + ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + + /* + * Always enable abort on incoming L_Qs if this feature is + * supported. We use this to catch invalid SCB references. + */ + if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0) + ahd_outb(ahd, LQCTL1, ABORTPENDING); + else + ahd_outb(ahd, LQCTL1, 0); + + /* All of our queues are empty */ + ahd->qoutfifonext = 0; + ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE; + ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8); + for (i = 0; i < AHD_QOUT_SIZE; i++) + ahd->qoutfifo[i] = 0; + ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD); + + ahd->qinfifonext = 0; + for (i = 0; i < AHD_QIN_SIZE; i++) + ahd->qinfifo[i] = SCB_LIST_NULL; + + if ((ahd->features & AHD_TARGETMODE) != 0) { + /* All target command blocks start out invalid. */ + for (i = 0; i < AHD_TMODE_CMDS; i++) + ahd->targetcmds[i].cmd_valid = 0; + ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD); + ahd->tqinfifonext = 1; + ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1); + ahd_outb(ahd, TQINPOS, ahd->tqinfifonext); + } + + /* Initialize Scratch Ram. */ + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_outb(ahd, SEQ_FLAGS2, 0); + + /* We don't have any waiting selections */ + ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL); + ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL); + for (i = 0; i < AHD_NUM_TARGETS; i++) + ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL); + + /* + * Nobody is waiting to be DMAed into the QOUTFIFO. + */ + ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); + ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL); + ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); + + /* + * The Freeze Count is 0. + */ + ahd_outw(ahd, QFREEZE_COUNT, 0); + + /* + * Tell the sequencer where it can find our arrays in memory. + */ + busaddr = ahd->shared_data_busaddr; + ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); + ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF); + + /* + * Setup the allowed SCSI Sequences based on operational mode. + * If we are a target, we'll enable select in operations once + * we've had a lun enabled. + */ + scsiseq_template = ENAUTOATNP; + if ((ahd->flags & AHD_INITIATORROLE) != 0) + scsiseq_template |= ENRSELI; + ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template); + + /* There are no busy SCBs yet. */ + for (target = 0; target < AHD_NUM_TARGETS; target++) { + int lun; + + for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++) + ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun)); + } + + /* + * Initialize the group code to command length table. + * Vendor Unique codes are set to 0 so we only capture + * the first byte of the cdb. These can be overridden + * when target mode is enabled. + */ + ahd_outb(ahd, CMDSIZE_TABLE, 5); + ahd_outb(ahd, CMDSIZE_TABLE + 1, 9); + ahd_outb(ahd, CMDSIZE_TABLE + 2, 9); + ahd_outb(ahd, CMDSIZE_TABLE + 3, 0); + ahd_outb(ahd, CMDSIZE_TABLE + 4, 15); + ahd_outb(ahd, CMDSIZE_TABLE + 5, 11); + ahd_outb(ahd, CMDSIZE_TABLE + 6, 0); + ahd_outb(ahd, CMDSIZE_TABLE + 7, 0); + + /* Tell the sequencer of our initial queue positions */ + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512); + ahd->qinfifonext = 0; + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); + ahd_set_hescb_qoff(ahd, 0); + ahd_set_snscb_qoff(ahd, 0); + ahd_set_sescb_qoff(ahd, 0); + ahd_set_sdscb_qoff(ahd, 0); + + /* + * Tell the sequencer which SCB will be the next one it receives. + */ + busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); + + /* + * Default to coalessing disabled. + */ + ahd_outw(ahd, INT_COALESSING_CMDCOUNT, 0); + ahd_outw(ahd, CMDS_PENDING, 0); + ahd_update_coalessing_values(ahd, ahd->int_coalessing_timer, + ahd->int_coalessing_maxcmds, + ahd->int_coalessing_mincmds); + ahd_enable_coalessing(ahd, FALSE); + + ahd_loadseq(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); +} + +/* + * Setup default device and controller settings. + * This should only be called if our probe has + * determined that no configuration data is available. + */ +int +ahd_default_config(struct ahd_softc *ahd) +{ + int targ; + + ahd->our_id = 7; + + /* + * Allocate a tstate to house information for our + * initiator presence on the bus as well as the user + * data for any target mode initiator. + */ + if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { + printf("%s: unable to allocate ahd_tmode_tstate. " + "Failing attach\n", ahd_name(ahd)); + return (ENOMEM); + } + + for (targ = 0; targ < AHD_NUM_TARGETS; targ++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + uint16_t target_mask; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + targ, &tstate); + /* + * We support SPC2 and SPI4. + */ + tinfo->user.protocol_version = 4; + tinfo->user.transport_version = 4; + + target_mask = 0x01 << targ; + ahd->user_discenable |= target_mask; + tstate->discenable |= target_mask; + ahd->user_tagenable |= target_mask; +#ifdef AHD_FORCE_160 + tinfo->user.period = AHD_SYNCRATE_DT; +#else + tinfo->user.period = AHD_SYNCRATE_160; +#endif + tinfo->user.offset= ~0; + tinfo->user.ppr_options = MSG_EXT_PPR_RD_STRM + | MSG_EXT_PPR_WR_FLOW + | MSG_EXT_PPR_HOLD_MCS + | MSG_EXT_PPR_IU_REQ + | MSG_EXT_PPR_QAS_REQ + | MSG_EXT_PPR_DT_REQ; + if ((ahd->features & AHD_RTI) != 0) + tinfo->user.ppr_options |= MSG_EXT_PPR_RTI; + + tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT; + + /* + * Start out Async/Narrow/Untagged and with + * conservative protocol support. + */ + tinfo->goal.protocol_version = 2; + tinfo->goal.transport_version = 2; + tinfo->curr.protocol_version = 2; + tinfo->curr.transport_version = 2; + ahd_compile_devinfo(&devinfo, ahd->our_id, + targ, CAM_LUN_WILDCARD, + 'A', ROLE_INITIATOR); + tstate->tagenable &= ~target_mask; + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, + /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + } + return (0); +} + +/* + * Parse device configuration information. + */ +int +ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc) +{ + int targ; + int max_targ; + + max_targ = sc->max_targets & CFMAXTARG; + ahd->our_id = sc->brtime_id & CFSCSIID; + + /* + * Allocate a tstate to house information for our + * initiator presence on the bus as well as the user + * data for any target mode initiator. + */ + if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { + printf("%s: unable to allocate ahd_tmode_tstate. " + "Failing attach\n", ahd_name(ahd)); + return (ENOMEM); + } + + for (targ = 0; targ < max_targ; targ++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_transinfo *user_tinfo; + struct ahd_tmode_tstate *tstate; + uint16_t target_mask; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + targ, &tstate); + user_tinfo = &tinfo->user; + + /* + * We support SPC2 and SPI4. + */ + tinfo->user.protocol_version = 4; + tinfo->user.transport_version = 4; + + target_mask = 0x01 << targ; + ahd->user_discenable &= ~target_mask; + tstate->discenable &= ~target_mask; + ahd->user_tagenable &= ~target_mask; + if (sc->device_flags[targ] & CFDISC) { + tstate->discenable |= target_mask; + ahd->user_discenable |= target_mask; + ahd->user_tagenable |= target_mask; + } else { + /* + * Cannot be packetized without disconnection. + */ + sc->device_flags[targ] &= ~CFPACKETIZED; + } + + user_tinfo->ppr_options = 0; + user_tinfo->period = (sc->device_flags[targ] & CFXFER); + if (user_tinfo->period < CFXFER_ASYNC) { + if (user_tinfo->period <= AHD_PERIOD_10MHz) + user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ; + user_tinfo->offset = MAX_OFFSET; + } else { + user_tinfo->offset = 0; + user_tinfo->period = AHD_ASYNC_XFER_PERIOD; + } +#ifdef AHD_FORCE_160 + if (user_tinfo->period <= AHD_SYNCRATE_160) + user_tinfo->period = AHD_SYNCRATE_DT; +#endif + + if ((sc->device_flags[targ] & CFPACKETIZED) != 0) { + user_tinfo->ppr_options |= MSG_EXT_PPR_RD_STRM + | MSG_EXT_PPR_WR_FLOW + | MSG_EXT_PPR_HOLD_MCS + | MSG_EXT_PPR_IU_REQ; + if ((ahd->features & AHD_RTI) != 0) + user_tinfo->ppr_options |= MSG_EXT_PPR_RTI; + } + + if ((sc->device_flags[targ] & CFQAS) != 0) + user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ; + + if ((sc->device_flags[targ] & CFWIDEB) != 0) + user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT; + else + user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width, + user_tinfo->period, user_tinfo->offset, + user_tinfo->ppr_options); +#endif + /* + * Start out Async/Narrow/Untagged and with + * conservative protocol support. + */ + tstate->tagenable &= ~target_mask; + tinfo->goal.protocol_version = 2; + tinfo->goal.transport_version = 2; + tinfo->curr.protocol_version = 2; + tinfo->curr.transport_version = 2; + ahd_compile_devinfo(&devinfo, ahd->our_id, + targ, CAM_LUN_WILDCARD, + 'A', ROLE_INITIATOR); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, + /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + } + + ahd->flags &= ~AHD_SPCHK_ENB_A; + if (sc->bios_control & CFSPARITY) + ahd->flags |= AHD_SPCHK_ENB_A; + + ahd->flags &= ~AHD_RESET_BUS_A; + if (sc->bios_control & CFRESETB) + ahd->flags |= AHD_RESET_BUS_A; + + ahd->flags &= ~AHD_EXTENDED_TRANS_A; + if (sc->bios_control & CFEXTEND) + ahd->flags |= AHD_EXTENDED_TRANS_A; + + ahd->flags &= ~AHD_BIOS_ENABLED; + if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED) + ahd->flags |= AHD_BIOS_ENABLED; + + ahd->flags &= ~AHD_STPWLEVEL_A; + if ((sc->adapter_control & CFSTPWLEVEL) != 0) + ahd->flags |= AHD_STPWLEVEL_A; + + return (0); +} + +void +ahd_intr_enable(struct ahd_softc *ahd, int enable) +{ + u_int hcntrl; + + hcntrl = ahd_inb(ahd, HCNTRL); + hcntrl &= ~INTEN; + ahd->pause &= ~INTEN; + ahd->unpause &= ~INTEN; + if (enable) { + hcntrl |= INTEN; + ahd->pause |= INTEN; + ahd->unpause |= INTEN; + } + ahd_outb(ahd, HCNTRL, hcntrl); +} + +void +ahd_update_coalessing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, + u_int mincmds) +{ + if (timer > AHD_TIMER_MAX_US) + timer = AHD_TIMER_MAX_US; + ahd->int_coalessing_timer = timer; + + if (maxcmds > AHD_INT_COALESSING_MAXCMDS_MAX) + maxcmds = AHD_INT_COALESSING_MAXCMDS_MAX; + if (mincmds > AHD_INT_COALESSING_MINCMDS_MAX) + mincmds = AHD_INT_COALESSING_MINCMDS_MAX; + ahd->int_coalessing_maxcmds = maxcmds; + ahd_outw(ahd, INT_COALESSING_TIMER, timer / AHD_TIMER_US_PER_TICK); + ahd_outb(ahd, INT_COALESSING_MAXCMDS, -maxcmds); + ahd_outb(ahd, INT_COALESSING_MINCMDS, -mincmds); +} + +void +ahd_enable_coalessing(struct ahd_softc *ahd, int enable) +{ + + ahd->hs_mailbox &= ~ENINT_COALESS; + if (enable) + ahd->hs_mailbox |= ENINT_COALESS; + ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox); + ahd_flush_device_writes(ahd); + ahd_run_qoutfifo(ahd); +} + +/* + * Ensure that the card is paused in a location + * outside of all critical sections and that all + * pending work is completed prior to returning. + * This routine should only be called from outside + * an interrupt context. + */ +void +ahd_pause_and_flushwork(struct ahd_softc *ahd) +{ + u_int intstat; + u_int maxloops; + int paused; + + maxloops = 1000; + ahd->flags |= AHD_ALL_INTERRUPTS; + intstat = 0; + paused = FALSE; + do { + struct scb *waiting_scb; + + if (paused) + ahd_unpause(ahd); + ahd_intr(ahd); + ahd_pause(ahd); + paused = TRUE; + ahd_clear_critical_section(ahd); + if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0) + ahd_outb(ahd, SCSISEQ0, + ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + /* + * In the non-packetized case, the sequencer (for Rev A), + * relies on ENSELO remaining set after SELDO. The hardware + * auto-clears ENSELO in the packetized case. + */ + waiting_scb = ahd_lookup_scb(ahd, + ahd_inw(ahd, WAITING_TID_HEAD)); + if (waiting_scb != NULL + && (waiting_scb->flags & SCB_PACKETIZED) == 0 + && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0) + ahd_outb(ahd, SCSISEQ0, + ahd_inb(ahd, SCSISEQ0) | ENSELO); + + if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) + break; + } while (--maxloops + && (((intstat = ahd_inb(ahd, INTSTAT)) & INT_PEND) != 0 + || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)))); + if (maxloops == 0) { + printf("Infinite interrupt loop, INTSTAT = %x", + ahd_inb(ahd, INTSTAT)); + } + + ahd_flush_qoutfifo(ahd); + + ahd_platform_flushwork(ahd); + ahd->flags &= ~AHD_ALL_INTERRUPTS; +} + +int +ahd_suspend(struct ahd_softc *ahd) +{ +#if 0 + uint8_t *ptr; + int i; + + ahd_pause_and_flushwork(ahd); + + if (LIST_FIRST(&ahd->pending_scbs) != NULL) + return (EBUSY); + +#if AHD_TARGET_MODE + /* + * XXX What about ATIOs that have not yet been serviced? + * Perhaps we should just refuse to be suspended if we + * are acting in a target role. + */ + if (ahd->pending_device != NULL) + return (EBUSY); +#endif + + /* Save volatile registers */ + ahd->suspend_state.channel[0].scsiseq = ahd_inb(ahd, SCSISEQ0); + ahd->suspend_state.channel[0].sxfrctl0 = ahd_inb(ahd, SXFRCTL0); + ahd->suspend_state.channel[0].sxfrctl1 = ahd_inb(ahd, SXFRCTL1); + ahd->suspend_state.channel[0].simode0 = ahd_inb(ahd, SIMODE0); + ahd->suspend_state.channel[0].simode1 = ahd_inb(ahd, SIMODE1); + ahd->suspend_state.channel[0].seltimer = ahd_inb(ahd, SELTIMER); + ahd->suspend_state.channel[0].seqctl = ahd_inb(ahd, SEQCTL0); + ahd->suspend_state.dscommand0 = ahd_inb(ahd, DSCOMMAND0); + ahd->suspend_state.dspcistatus = ahd_inb(ahd, DSPCISTATUS); + + if ((ahd->features & AHD_DT) != 0) { + u_int sfunct; + + sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE; + ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE); + ahd->suspend_state.optionmode = ahd_inb(ahd, OPTIONMODE); + ahd_outb(ahd, SFUNCT, sfunct); + ahd->suspend_state.crccontrol1 = ahd_inb(ahd, CRCCONTROL1); + } + + if ((ahd->features & AHD_MULTI_FUNC) != 0) + ahd->suspend_state.scbbaddr = ahd_inb(ahd, SCBBADDR); + + if ((ahd->features & AHD_ULTRA2) != 0) + ahd->suspend_state.dff_thrsh = ahd_inb(ahd, DFF_THRSH); + + ptr = ahd->suspend_state.scratch_ram; + for (i = 0; i < 64; i++) + *ptr++ = ahd_inb(ahd, SRAM_BASE + i); + + if ((ahd->features & AHD_MORE_SRAM) != 0) { + for (i = 0; i < 16; i++) + *ptr++ = ahd_inb(ahd, TARG_OFFSET + i); + } + + ptr = ahd->suspend_state.btt; + for (i = 0;i < AHD_NUM_TARGETS; i++) { + int j; + + for (j = 0;j < AHD_NUM_LUNS_NONPKT; j++) { + u_int tcl; + + tcl = BUILD_TCL_RAW(i, 'A', j); + *ptr = ahd_find_busy_tcl(ahd, tcl); + } + } + ahd_shutdown(ahd); +#endif + return (0); +} + +int +ahd_resume(struct ahd_softc *ahd) +{ +#if 0 + uint8_t *ptr; + int i; + + ahd_reset(ahd); + + ahd_build_free_scb_list(ahd); + + /* Restore volatile registers */ + ahd_outb(ahd, SCSISEQ0, ahd->suspend_state.channel[0].scsiseq); + ahd_outb(ahd, SXFRCTL0, ahd->suspend_state.channel[0].sxfrctl0); + ahd_outb(ahd, SXFRCTL1, ahd->suspend_state.channel[0].sxfrctl1); + ahd_outb(ahd, SIMODE0, ahd->suspend_state.channel[0].simode0); + ahd_outb(ahd, SIMODE1, ahd->suspend_state.channel[0].simode1); + ahd_outb(ahd, SELTIMER, ahd->suspend_state.channel[0].seltimer); + ahd_outb(ahd, SEQCTL0, ahd->suspend_state.channel[0].seqctl); + if ((ahd->features & AHD_ULTRA2) != 0) + ahd_outb(ahd, SCSIID_ULTRA2, ahd->our_id); + else + ahd_outb(ahd, SCSIID, ahd->our_id); + + ahd_outb(ahd, DSCOMMAND0, ahd->suspend_state.dscommand0); + ahd_outb(ahd, DSPCISTATUS, ahd->suspend_state.dspcistatus); + + if ((ahd->features & AHD_DT) != 0) { + u_int sfunct; + + sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE; + ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE); + ahd_outb(ahd, OPTIONMODE, ahd->suspend_state.optionmode); + ahd_outb(ahd, SFUNCT, sfunct); + ahd_outb(ahd, CRCCONTROL1, ahd->suspend_state.crccontrol1); + } + + if ((ahd->features & AHD_MULTI_FUNC) != 0) + ahd_outb(ahd, SCBBADDR, ahd->suspend_state.scbbaddr); + + if ((ahd->features & AHD_ULTRA2) != 0) + ahd_outb(ahd, DFF_THRSH, ahd->suspend_state.dff_thrsh); + + ptr = ahd->suspend_state.scratch_ram; + for (i = 0; i < 64; i++) + ahd_outb(ahd, SRAM_BASE + i, *ptr++); + + if ((ahd->features & AHD_MORE_SRAM) != 0) { + for (i = 0; i < 16; i++) + ahd_outb(ahd, TARG_OFFSET + i, *ptr++); + } + + ptr = ahd->suspend_state.btt; + for (i = 0;i < AHD_NUM_TARGETS; i++) { + int j; + + for (j = 0;j < AHD_NUM_LUNS; j++) { + u_int tcl; + + tcl = BUILD_TCL(i << 4, j); + ahd_busy_tcl(ahd, tcl, *ptr); + } + } +#endif + return (0); +} + +/************************** Busy Target Table *********************************/ +/* + * Set SCBPTR to the SCB that contains the busy + * table entry for TCL. Return the offset into + * the SCB that contains the entry for TCL. + * saved_scbid is dereferenced and set to the + * scbid that should be restored once manipualtion + * of the TCL entry is complete. + */ +static __inline u_int +ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) +{ + /* + * Index to the SCB that contains the busy entry. + */ + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + *saved_scbid = ahd_get_scbptr(ahd); + ahd_set_scbptr(ahd, TCL_LUN(tcl) + | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4)); + + /* + * And now calculate the SCB offset to the entry. + * Each entry is 2 bytes wide, hence the + * multiplication by 2. + */ + return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS); +} + +/* + * Return the untagged transaction id for a given target/channel lun. + * Optionally, clear the entry. + */ +u_int +ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) +{ + u_int scbid; + u_int scb_offset; + u_int saved_scbptr; + + scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl); + scbid = ahd_inw_scbram(ahd, scb_offset); + ahd_set_scbptr(ahd, saved_scbptr); + return (scbid); +} + +void +ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) +{ + u_int scb_offset; + u_int saved_scbptr; + + scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl); + ahd_outw(ahd, scb_offset, scbid); + ahd_set_scbptr(ahd, saved_scbptr); +} + +/************************** SCB and SCB queue management **********************/ +int +ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, + char channel, int lun, u_int tag, role_t role) +{ + int targ = SCB_GET_TARGET(ahd, scb); + char chan = SCB_GET_CHANNEL(ahd, scb); + int slun = SCB_GET_LUN(scb); + int match; + + match = ((chan == channel) || (channel == ALL_CHANNELS)); + if (match != 0) + match = ((targ == target) || (target == CAM_TARGET_WILDCARD)); + if (match != 0) + match = ((lun == slun) || (lun == CAM_LUN_WILDCARD)); + if (match != 0) { +#if AHD_TARGET_MODE + int group; + + group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code); + if (role == ROLE_INITIATOR) { + match = (group != XPT_FC_GROUP_TMODE) + && ((tag == SCB_GET_TAG(scb)) + || (tag == SCB_LIST_NULL)); + } else if (role == ROLE_TARGET) { + match = (group == XPT_FC_GROUP_TMODE) + && ((tag == scb->io_ctx->csio.tag_id) + || (tag == SCB_LIST_NULL)); + } +#else /* !AHD_TARGET_MODE */ + match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL)); +#endif /* AHD_TARGET_MODE */ + } + + return match; +} + +void +ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) +{ + int target; + char channel; + int lun; + + target = SCB_GET_TARGET(ahd, scb); + lun = SCB_GET_LUN(scb); + channel = SCB_GET_CHANNEL(ahd, scb); + + ahd_search_qinfifo(ahd, target, channel, lun, + /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN, + CAM_REQUEUE_REQ, SEARCH_COMPLETE); + + ahd_platform_freeze_devq(ahd, scb); +} + +void +ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb) +{ + struct scb *prev_scb; + ahd_mode_state saved_modes; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + prev_scb = NULL; + if (ahd_qinfifo_count(ahd) != 0) { + u_int prev_tag; + u_int prev_pos; + + prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1); + prev_tag = ahd->qinfifo[prev_pos]; + prev_scb = ahd_lookup_scb(ahd, prev_tag); + } + ahd_qinfifo_requeue(ahd, prev_scb, scb); + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); + ahd_restore_modes(ahd, saved_modes); +} + +static void +ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb, + struct scb *scb) +{ + if (prev_scb == NULL) { + uint32_t busaddr; + + busaddr = ahd_le32toh(scb->hscb->hscb_busaddr); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); + } else { + prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; + ahd_sync_scb(ahd, prev_scb, + BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + } + ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); + ahd->qinfifonext++; + scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr; + ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); +} + +static int +ahd_qinfifo_count(struct ahd_softc *ahd) +{ + u_int qinpos; + u_int wrap_qinpos; + u_int wrap_qinfifonext; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + qinpos = ahd_get_snscb_qoff(ahd); + wrap_qinpos = AHD_QIN_WRAP(qinpos); + wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext); + if (wrap_qinfifonext >= wrap_qinpos) + return (wrap_qinfifonext - wrap_qinpos); + else + return (wrap_qinfifonext + + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos); +} + +void +ahd_reset_cmds_pending(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int pending_cmds; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + + /* + * Don't count any commands as outstanding that the + * sequencer has already marked for completion. + */ + ahd_flush_qoutfifo(ahd); + + pending_cmds = 0; + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + pending_cmds++; + } + ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd)); + ahd_restore_modes(ahd, saved_modes); + ahd->flags &= ~AHD_UPDATE_PEND_CMDS; +} + +int +ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status, + ahd_search_action action) +{ + struct scb *scb; + struct scb *prev_scb; + ahd_mode_state saved_modes; + u_int qinstart; + u_int qinpos; + u_int qintail; + u_int tid_next; + u_int tid_prev; + u_int scbid; + u_int savedscbptr; + uint32_t busaddr; + int found; + int targets; + + /* Must be in CCHAN mode */ + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + + /* + * Halt any pending SCB DMA. The sequencer will reinitiate + * this dma if the qinfifo is not empty once we unpause. + */ + if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR)) + == (CCARREN|CCSCBEN|CCSCBDIR)) { + ahd_outb(ahd, CCSCBCTL, + ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN)); + while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) + ; + } + /* Determine sequencer's position in the qinfifo. */ + qintail = AHD_QIN_WRAP(ahd->qinfifonext); + qinstart = ahd_get_snscb_qoff(ahd); + qinpos = AHD_QIN_WRAP(qinstart); + found = 0; + prev_scb = NULL; + + if (action == SEARCH_PRINT) { + printf("qinstart = %d qinfifonext = %d\nQINFIFO:", + qinstart, ahd->qinfifonext); + } + + /* + * Start with an empty queue. Entries that are not chosen + * for removal will be re-added to the queue as we go. + */ + ahd->qinfifonext = qinstart; + busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); + + while (qinpos != qintail) { + scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]); + if (scb == NULL) { + printf("qinpos = %d, SCB index = %d\n", + qinpos, ahd->qinfifo[qinpos]); + panic("Loop 1\n"); + } + + if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) { + /* + * We found an scb that needs to be acted on. + */ + found++; + switch (action) { + case SEARCH_COMPLETE: + { + cam_status ostat; + cam_status cstat; + + ostat = ahd_get_transaction_status(scb); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scb, + status); + cstat = ahd_get_transaction_status(scb); + if (cstat != CAM_REQ_CMP) + ahd_freeze_scb(scb); + if ((scb->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB in qinfifo\n"); + ahd_done(ahd, scb); + + /* FALLTHROUGH */ + } + case SEARCH_REMOVE: + break; + case SEARCH_PRINT: + printf(" 0x%x", ahd->qinfifo[qinpos]); + /* FALLTHROUGH */ + case SEARCH_COUNT: + ahd_qinfifo_requeue(ahd, prev_scb, scb); + prev_scb = scb; + break; + } + } else { + ahd_qinfifo_requeue(ahd, prev_scb, scb); + prev_scb = scb; + } + qinpos = AHD_QIN_WRAP(qinpos+1); + } + + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); + + if (action == SEARCH_PRINT) + printf("\nWAITING_TID_QUEUES:\n"); + + /* + * Search waiting for selection lists. We traverse the + * list of "their ids" waiting for selection and, if + * appropriate, traverse the SCBs of each "their id" + * looking for matches. + */ + savedscbptr = ahd_get_scbptr(ahd); + tid_next = ahd_inw(ahd, WAITING_TID_HEAD); + tid_prev = SCB_LIST_NULL; + targets = 0; + for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) { + u_int tid_head; + + /* + * We limit based on the number of SCBs since + * MK_MESSAGE SCBs are not in the per-tid lists. + */ + targets++; + if (targets > AHD_SCB_MAX) { + panic("TID LIST LOOP"); + } + if (scbid >= ahd->scb_data.numscbs) { + printf("%s: Waiting TID List inconsistency. " + "SCB index == 0x%x, yet numscbs == 0x%x.", + ahd_name(ahd), scbid, ahd->scb_data.numscbs); + ahd_dump_card_state(ahd); + panic("for safety"); + } + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: SCB = 0x%x Not Active!\n", + ahd_name(ahd), scbid); + panic("Waiting TID List traversal\n"); + } + ahd_set_scbptr(ahd, scbid); + tid_next = ahd_inw_scbram(ahd, SCB_NEXT2); + if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD, + SCB_LIST_NULL, ROLE_UNKNOWN) == 0) { + tid_prev = scbid; + continue; + } + + /* + * We found a list of scbs that needs to be searched. + */ + if (action == SEARCH_PRINT) + printf(" %d ( ", SCB_GET_TARGET(ahd, scb)); + tid_head = scbid; + found += ahd_search_scb_list(ahd, target, channel, + lun, tag, role, status, + action, &tid_head, + SCB_GET_TARGET(ahd, scb)); + if (tid_head != scbid) + ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next); + if (!SCBID_IS_NULL(tid_head)) + tid_prev = tid_head; + if (action == SEARCH_PRINT) + printf(")\n"); + } + ahd_set_scbptr(ahd, savedscbptr); + ahd_restore_modes(ahd, saved_modes); + return (found); +} + +static int +ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status, + ahd_search_action action, u_int *list_head, u_int tid) +{ + struct scb *scb; + u_int scbid; + u_int next; + u_int prev; + int found; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + found = 0; + prev = SCB_LIST_NULL; + next = *list_head; + for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) { + if (scbid >= ahd->scb_data.numscbs) { + printf("%s:SCB List inconsistency. " + "SCB == 0x%x, yet numscbs == 0x%x.", + ahd_name(ahd), scbid, ahd->scb_data.numscbs); + ahd_dump_card_state(ahd); + panic("for safety"); + } + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: SCB = %d Not Active!\n", + ahd_name(ahd), scbid); + panic("Waiting List traversal\n"); + } + ahd_set_scbptr(ahd, scbid); + next = ahd_inw_scbram(ahd, SCB_NEXT); + if (ahd_match_scb(ahd, scb, target, channel, + lun, SCB_LIST_NULL, role) == 0) { + prev = scbid; + continue; + } + found++; + switch (action) { + case SEARCH_COMPLETE: + { + cam_status ostat; + cam_status cstat; + + ostat = ahd_get_transaction_status(scb); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scb, status); + cstat = ahd_get_transaction_status(scb); + if (cstat != CAM_REQ_CMP) + ahd_freeze_scb(scb); + if ((scb->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB in Waiting List\n"); + ahd_done(ahd, scb); + /* FALLTHROUGH */ + } + case SEARCH_REMOVE: + ahd_rem_wscb(ahd, scbid, prev, next, tid); + if (prev == SCB_LIST_NULL) + *list_head = next; + break; + case SEARCH_PRINT: + printf("0x%x ", scbid); + case SEARCH_COUNT: + prev = scbid; + break; + } + if (found > AHD_SCB_MAX) + panic("SCB LIST LOOP"); + } + if (action == SEARCH_COMPLETE + || action == SEARCH_REMOVE) + ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found); + return (found); +} + +static void +ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev, + u_int tid_cur, u_int tid_next) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + + if (SCBID_IS_NULL(tid_cur)) { + + /* Bypass current TID list */ + if (SCBID_IS_NULL(tid_prev)) { + ahd_outw(ahd, WAITING_TID_HEAD, tid_next); + } else { + ahd_set_scbptr(ahd, tid_prev); + ahd_outw(ahd, SCB_NEXT2, tid_next); + } + if (SCBID_IS_NULL(tid_next)) + ahd_outw(ahd, WAITING_TID_TAIL, tid_prev); + } else { + + /* Stitch through tid_cur */ + if (SCBID_IS_NULL(tid_prev)) { + ahd_outw(ahd, WAITING_TID_HEAD, tid_cur); + } else { + ahd_set_scbptr(ahd, tid_prev); + ahd_outw(ahd, SCB_NEXT2, tid_cur); + } + ahd_set_scbptr(ahd, tid_cur); + ahd_outw(ahd, SCB_NEXT2, tid_next); + + if (SCBID_IS_NULL(tid_next)) + ahd_outw(ahd, WAITING_TID_TAIL, tid_cur); + } +} + +/* + * Manipulate the waiting for selection list and return the + * scb that follows the one that we remove. + */ +static u_int +ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, + u_int prev, u_int next, u_int tid) +{ + u_int tail_offset; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + if (!SCBID_IS_NULL(prev)) { + ahd_set_scbptr(ahd, prev); + ahd_outw(ahd, SCB_NEXT, next); + } + + /* + * SCBs that had MK_MESSAGE set in them will not + * be queued to the per-target lists, so don't + * blindly clear the tail pointer. + */ + tail_offset = WAITING_SCB_TAILS + (2 * tid); + if (SCBID_IS_NULL(next) + && ahd_inw(ahd, tail_offset) == scbid) + ahd_outw(ahd, tail_offset, prev); + ahd_add_scb_to_free_list(ahd, scbid); + return (next); +} + +/* + * Add the SCB as selected by SCBPTR onto the on chip list of + * free hardware SCBs. This list is empty/unused if we are not + * performing SCB paging. + */ +static void +ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid) +{ +/* XXX Need some other mechanism to designate "free". */ + /* + * Invalidate the tag so that our abort + * routines don't think it's active. + ahd_outb(ahd, SCB_TAG, SCB_LIST_NULL); + */ +} + +/******************************** Error Handling ******************************/ +/* + * Abort all SCBs that match the given description (target/channel/lun/tag), + * setting their status to the passed in status if the status has not already + * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer + * is paused before it is called. + */ +int +ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status) +{ + struct scb *scbp; + struct scb *scbp_next; + u_int active_scb; + u_int i, j; + u_int maxtarget; + u_int minlun; + u_int maxlun; + int found; + ahd_mode_state saved_modes; + + /* restore these when we're done */ + active_scb = ahd_get_scbptr(ahd); + saved_modes = ahd_save_modes(ahd); + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL, + role, CAM_REQUEUE_REQ, SEARCH_COMPLETE); + + /* + * Clean out the busy target table for any untagged commands. + */ + i = 0; + maxtarget = 16; + if (target != CAM_TARGET_WILDCARD) { + i = target; + if (channel == 'B') + i += 8; + maxtarget = i + 1; + } + + if (lun == CAM_LUN_WILDCARD) { + minlun = 0; + maxlun = AHD_NUM_LUNS_NONPKT; + } else if (lun >= AHD_NUM_LUNS_NONPKT) { + minlun = maxlun = 0; + } else { + minlun = lun; + maxlun = lun + 1; + } + + if (role != ROLE_TARGET) { + for (;i < maxtarget; i++) { + for (j = minlun;j < maxlun; j++) { + u_int scbid; + u_int tcl; + + tcl = BUILD_TCL_RAW(i, 'A', j); + scbid = ahd_find_busy_tcl(ahd, tcl); + scbp = ahd_lookup_scb(ahd, scbid); + if (scbp == NULL + || ahd_match_scb(ahd, scbp, target, channel, + lun, tag, role) == 0) + continue; + ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j)); + } + } + } + + /* + * Don't abort commands that have already completed, + * but haven't quite made it up to the host yet. + */ + ahd_flush_qoutfifo(ahd); + + /* + * Go through the pending CCB list and look for + * commands for this target that are still active. + * These are other tagged commands that were + * disconnected when the reset occurred. + */ + scbp_next = LIST_FIRST(&ahd->pending_scbs); + while (scbp_next != NULL) { + scbp = scbp_next; + scbp_next = LIST_NEXT(scbp, pending_links); + if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) { + cam_status ostat; + + ostat = ahd_get_transaction_status(scbp); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scbp, status); + if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP) + ahd_freeze_scb(scbp); + if ((scbp->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB on pending list\n"); + ahd_done(ahd, scbp); + found++; + } + } + ahd_set_scbptr(ahd, active_scb); + ahd_restore_modes(ahd, saved_modes); + ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status); + ahd->flags |= AHD_UPDATE_PEND_CMDS; + return found; +} + +static void +ahd_reset_current_bus(struct ahd_softc *ahd) +{ + uint8_t scsiseq; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST); + scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO); + ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO); + ahd_delay(AHD_BUSRESET_DELAY); + /* Turn off the bus reset */ + ahd_outb(ahd, SCSISEQ0, scsiseq); + if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) { + /* + * 2A Razor #474 + * Certain chip state is not cleared for + * SCSI bus resets that we initiate, so + * we must reset the chip. + */ + ahd_delay(AHD_BUSRESET_DELAY); + ahd_reset(ahd); + ahd_intr_enable(ahd, /*enable*/TRUE); + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + } + + ahd_clear_intstat(ahd); +} + +int +ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) +{ + struct ahd_devinfo devinfo; + u_int initiator; + u_int target; + u_int max_scsiid; + int found; + u_int fifo; + u_int next_fifo; + + ahd->pending_device = NULL; + + ahd_compile_devinfo(&devinfo, + CAM_TARGET_WILDCARD, + CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD, + channel, ROLE_UNKNOWN); + ahd_pause(ahd); + + /* Make sure the sequencer is in a safe location. */ + ahd_clear_critical_section(ahd); + +#if AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0) { + ahd_run_tqinfifo(ahd, /*paused*/TRUE); + } +#endif + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + /* + * Disable selections so no automatic hardware + * functions will modify chip state. + */ + ahd_outb(ahd, SCSISEQ0, 0); + ahd_outb(ahd, SCSISEQ1, 0); + + /* + * Safely shut down our DMA engines. Always start with + * the FIFO that is not currently active (if any are + * actively connected). + */ + next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO; + if (next_fifo > CURRFIFO_1) + /* If disconneced, arbitrarily start with FIFO1. */ + next_fifo = fifo = 0; + do { + next_fifo ^= CURRFIFO_1; + ahd_set_modes(ahd, next_fifo, next_fifo); + ahd_outb(ahd, DFCNTRL, + ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN)); + while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) + ahd_delay(10); + /* + * Set CURRFIFO to the now inactive channel. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, DFFSTAT, next_fifo); + } while (next_fifo != fifo); + /* + * Reset the bus if we are initiating this reset + */ + ahd_clear_msg_state(ahd); + ahd_outb(ahd, SIMODE1, + ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE)); + if (initiate_reset) + ahd_reset_current_bus(ahd); + ahd_clear_intstat(ahd); + + /* + * Clean up all the state information for the + * pending transactions on this bus. + */ + found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_UNKNOWN, CAM_SCSI_BUS_RESET); + + /* + * Cleanup anything left in the FIFOs. + */ + ahd_clear_fifo(ahd, 0); + ahd_clear_fifo(ahd, 1); + + /* + * Revert to async/narrow transfers until we renegotiate. + */ + max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; + for (target = 0; target <= max_scsiid; target++) { + + if (ahd->enabled_targets[target] == NULL) + continue; + for (initiator = 0; initiator <= max_scsiid; initiator++) { + struct ahd_devinfo devinfo; + + ahd_compile_devinfo(&devinfo, target, initiator, + CAM_LUN_WILDCARD, + 'A', ROLE_UNKNOWN); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_CUR, /*paused*/TRUE); + } + } + +#ifdef AHD_TARGET_MODE + max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; + + /* + * Send an immediate notify ccb to all target more peripheral + * drivers affected by this action. + */ + for (target = 0; target <= max_scsiid; target++) { + struct ahd_tmode_tstate* tstate; + u_int lun; + + tstate = ahd->enabled_targets[target]; + if (tstate == NULL) + continue; + for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + struct ahd_tmode_lstate* lstate; + + lstate = tstate->enabled_luns[lun]; + if (lstate == NULL) + continue; + + ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD, + EVENT_TYPE_BUS_RESET, /*arg*/0); + ahd_send_lstate_events(ahd, lstate); + } + } +#endif + /* Notify the XPT that a bus reset occurred */ + ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); + ahd_restart(ahd); + /* + * Freeze the SIMQ until our poller can determine that + * the bus reset has really gone away. We set the initial + * timer to 0 to have the check performed as soon as possible + * from the timer context. + */ + if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) { + ahd->flags |= AHD_RESET_POLL_ACTIVE; + ahd_freeze_simq(ahd); + ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd); + } + return (found); +} + + +#define AHD_RESET_POLL_US 1000 +static void +ahd_reset_poll(void *arg) +{ + struct ahd_softc *ahd; + u_int scsiseq1; + u_long l; + u_long s; + + ahd_list_lock(&l); + ahd = ahd_find_softc((struct ahd_softc *)arg); + if (ahd == NULL) { + printf("ahd_reset_poll: Instance %p no longer exists\n", arg); + ahd_list_unlock(&l); + return; + } + ahd_lock(ahd, &s); + ahd_pause(ahd); + ahd_update_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) { + ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US, + ahd_reset_poll, ahd); + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + ahd_list_unlock(&l); + return; + } + + /* Reset is now low. Complete chip reinitialization. */ + ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP)); + ahd_unpause(ahd); + ahd->flags &= ~AHD_RESET_POLL_ACTIVE; + ahd_unlock(ahd, &s); + ahd_release_simq(ahd); + ahd_list_unlock(&l); +} + +/**************************** Statistics Processing ***************************/ +static void +ahd_stat_timer(void *arg) +{ + struct ahd_softc *ahd; + u_long l; + u_long s; + int enint_coal; + + ahd_list_lock(&l); + ahd = ahd_find_softc((struct ahd_softc *)arg); + if (ahd == NULL) { + printf("ahd_stat_timer: Instance %p no longer exists\n", arg); + ahd_list_unlock(&l); + return; + } + ahd_lock(ahd, &s); + + enint_coal = ahd->hs_mailbox & ENINT_COALESS; + if (ahd->cmdcmplt_total > ahd->int_coalessing_threshold) + enint_coal |= ENINT_COALESS; + else if (ahd->cmdcmplt_total < ahd->int_coalessing_stop_threshold) + enint_coal &= ~ENINT_COALESS; + + if (enint_coal != (ahd->hs_mailbox & ENINT_COALESS)) { + ahd_enable_coalessing(ahd, enint_coal); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_INT_COALESSING) != 0) + printf("%s: Interrupt coalessing " + "now %sabled. Cmds %d\n", + ahd_name(ahd), + (enint_coal & ENINT_COALESS) ? "en" : "dis", + ahd->cmdcmplt_total); +#endif + } + + ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1); + ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]; + ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0; + ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, + ahd_stat_timer, ahd); + ahd_unlock(ahd, &s); + ahd_list_unlock(&l); +} + +/****************************** Status Processing *****************************/ +void +ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) +{ + if (scb->hscb->shared_data.istatus.scsi_status != 0) { + ahd_handle_scsi_status(ahd, scb); + } else { + ahd_calc_residual(ahd, scb); + ahd_done(ahd, scb); + } +} + +void +ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) +{ + struct hardware_scb *hscb; + u_int qfreeze_cnt; + ahd_mode_state saved_modes; + + /* + * The sequencer freezes its select-out queue + * anytime a SCSI status error occurs. We must + * handle the error and decrement the QFREEZE count + * to allow the sequencer to continue. + */ + hscb = scb->hscb; + + /* Freeze the queue until the client sees the error. */ + ahd_pause(ahd); + saved_modes = ahd_save_modes(ahd); + ahd_clear_critical_section(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_freeze_devq(ahd, scb); + ahd_freeze_scb(scb); + qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); + if (qfreeze_cnt == 0) { + printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd)); + } else { + qfreeze_cnt--; + ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt); + } + if (qfreeze_cnt == 0) + ahd_outb(ahd, SEQ_FLAGS2, + ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); + ahd_unpause(ahd); + /* Don't want to clobber the original sense code */ + if ((scb->flags & SCB_SENSE) != 0) { + /* + * Clear the SCB_SENSE Flag and perform + * a normal command completion. + */ + scb->flags &= ~SCB_SENSE; + ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); + ahd_done(ahd, scb); + return; + } + ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR); + ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status); + switch (hscb->shared_data.istatus.scsi_status) { + case STATUS_PKT_SENSE: + { + struct scsi_status_iu_header *siu; + + ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD); + siu = (struct scsi_status_iu_header *)scb->sense_data; + ahd_set_scsi_status(scb, siu->status); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SENSE) != 0) { + ahd_print_path(ahd, scb); + printf("SCB 0x%x Received PKT Status of 0x%x\n", + SCB_GET_TAG(scb), siu->status); + printf("\tflags = 0x%x, sense len = 0x%x, " + "pktfail = 0x%x\n", + siu->flags, scsi_4btoul(siu->sense_length), + scsi_4btoul(siu->pkt_failures_length)); + } +#endif + if ((siu->flags & SIU_RSPVALID) != 0) { + ahd_print_path(ahd, scb); + if (scsi_4btoul(siu->pkt_failures_length) < 4) { + printf("Unable to parse pkt_failures\n"); + } else { + + switch (SIU_PKTFAIL_CODE(siu)) { + case SIU_PFC_NONE: + printf("No packet failure found\n"); + break; + case SIU_PFC_CIU_FIELDS_INVALID: + printf("Invalid Command IU Field\n"); + break; + case SIU_PFC_TMF_NOT_SUPPORTED: + printf("TMF not supportd\n"); + break; + case SIU_PFC_TMF_FAILED: + printf("TMF failed\n"); + break; + case SIU_PFC_INVALID_TYPE_CODE: + printf("Invalid L_Q Type code\n"); + break; + case SIU_PFC_ILLEGAL_REQUEST: + printf("Illegal request\n"); + default: + break; + } + } + if (siu->status == SCSI_STATUS_OK) + ahd_set_transaction_status(scb, + CAM_REQ_CMP_ERR); + } + if ((siu->flags & SIU_SNSVALID) != 0) { + scb->flags |= SCB_PKT_SENSE; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SENSE) != 0) + printf("Sense data available\n"); +#endif + } + ahd_done(ahd, scb); + break; + } + case SCSI_STATUS_CMD_TERMINATED: + case SCSI_STATUS_CHECK_COND: + { + struct ahd_devinfo devinfo; + struct ahd_dma_seg *sg; + struct scsi_sense *sc; + struct ahd_initiator_tinfo *targ_info; + struct ahd_tmode_tstate *tstate; + struct ahd_transinfo *tinfo; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_SENSE) { + ahd_print_path(ahd, scb); + printf("SCB %d: requests Check Status\n", + SCB_GET_TAG(scb)); + } +#endif + + if (ahd_perform_autosense(scb) == 0) + break; + + ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb), + SCB_GET_TARGET(ahd, scb), + SCB_GET_LUN(scb), + SCB_GET_CHANNEL(ahd, scb), + ROLE_INITIATOR); + targ_info = ahd_fetch_transinfo(ahd, + devinfo.channel, + devinfo.our_scsiid, + devinfo.target, + &tstate); + tinfo = &targ_info->curr; + sg = scb->sg_list; + sc = (struct scsi_sense *)hscb->shared_data.idata.cdb; + /* + * Save off the residual if there is one. + */ + ahd_update_residual(ahd, scb); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_SENSE) { + ahd_print_path(ahd, scb); + printf("Sending Sense\n"); + } +#endif + scb->sg_count = 0; + sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb), + ahd_get_sense_bufsize(ahd, scb), + /*last*/TRUE); + sc->opcode = REQUEST_SENSE; + sc->byte2 = 0; + if (tinfo->protocol_version <= SCSI_REV_2 + && SCB_GET_LUN(scb) < 8) + sc->byte2 = SCB_GET_LUN(scb) << 5; + sc->unused[0] = 0; + sc->unused[1] = 0; + sc->length = ahd_get_sense_bufsize(ahd, scb); + sc->control = 0; + + /* + * We can't allow the target to disconnect. + * This will be an untagged transaction and + * having the target disconnect will make this + * transaction indestinguishable from outstanding + * tagged transactions. + */ + hscb->control = 0; + + /* + * This request sense could be because the + * the device lost power or in some other + * way has lost our transfer negotiations. + * Renegotiate if appropriate. Unit attention + * errors will be reported before any data + * phases occur. + */ + if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) { + ahd_update_neg_request(ahd, &devinfo, + tstate, targ_info, + AHD_NEG_IF_NON_ASYNC); + } + if (tstate->auto_negotiate & devinfo.target_mask) { + hscb->control |= MK_MESSAGE; + scb->flags &= + ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET); + scb->flags |= SCB_AUTO_NEGOTIATE; + } + hscb->cdb_len = sizeof(*sc); + ahd_setup_data_scb(ahd, scb); + scb->flags |= SCB_SENSE; + ahd_queue_scb(ahd, scb); + /* + * Ensure we have enough time to actually + * retrieve the sense. + */ + ahd_scb_timer_reset(scb, 5 * 1000000); + break; + } + case SCSI_STATUS_OK: + printf("%s: Interrupted for staus of 0???\n", + ahd_name(ahd)); + /* FALLTHROUGH */ + default: + ahd_done(ahd, scb); + break; + } +} + +/* + * Calculate the residual for a just completed SCB. + */ +void +ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) +{ + struct hardware_scb *hscb; + struct initiator_status *spkt; + uint32_t sgptr; + uint32_t resid_sgptr; + uint32_t resid; + + /* + * 5 cases. + * 1) No residual. + * SG_STATUS_VALID clear in sgptr. + * 2) Transferless command + * 3) Never performed any transfers. + * sgptr has SG_FULL_RESID set. + * 4) No residual but target did not + * save data pointers after the + * last transfer, so sgptr was + * never updated. + * 5) We have a partial residual. + * Use residual_sgptr to determine + * where we are. + */ + + hscb = scb->hscb; + sgptr = ahd_le32toh(hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) == 0) + /* Case 1 */ + return; + sgptr &= ~SG_STATUS_VALID; + + if ((sgptr & SG_LIST_NULL) != 0) + /* Case 2 */ + return; + + /* + * Residual fields are the same in both + * target and initiator status packets, + * so we can always use the initiator fields + * regardless of the role for this SCB. + */ + spkt = &hscb->shared_data.istatus; + resid_sgptr = ahd_le32toh(spkt->residual_sgptr); + if ((sgptr & SG_FULL_RESID) != 0) { + /* Case 3 */ + resid = ahd_get_transfer_length(scb); + } else if ((resid_sgptr & SG_LIST_NULL) != 0) { + /* Case 4 */ + return; + } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) { + ahd_print_path(ahd, scb); + printf("data overrun detected Tag == 0x%x.\n", + SCB_GET_TAG(scb)); + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); + ahd_freeze_scb(scb); + return; + } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) { + panic("Bogus resid sgptr value 0x%x\n", resid_sgptr); + /* NOTREACHED */ + } else { + struct ahd_dma_seg *sg; + + /* + * Remainder of the SG where the transfer + * stopped. + */ + resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK; + sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK); + + /* The residual sg_ptr always points to the next sg */ + sg--; + + /* + * Add up the contents of all residual + * SG segments that are after the SG where + * the transfer stopped. + */ + while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) { + sg++; + resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; + } + } + if ((scb->flags & SCB_SENSE) == 0) + ahd_set_residual(scb, resid); + else + ahd_set_sense_residual(scb, resid); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) { + ahd_print_path(ahd, scb); + printf("Handled %sResidual of %d bytes\n", + (scb->flags & SCB_SENSE) ? "Sense " : "", resid); + } +#endif +} + +/******************************* Target Mode **********************************/ +#ifdef AHD_TARGET_MODE +/* + * Add a target mode event to this lun's queue + */ +static void +ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate, + u_int initiator_id, u_int event_type, u_int event_arg) +{ + struct ahd_tmode_event *event; + int pending; + + xpt_freeze_devq(lstate->path, /*count*/1); + if (lstate->event_w_idx >= lstate->event_r_idx) + pending = lstate->event_w_idx - lstate->event_r_idx; + else + pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1 + - (lstate->event_r_idx - lstate->event_w_idx); + + if (event_type == EVENT_TYPE_BUS_RESET + || event_type == MSG_BUS_DEV_RESET) { + /* + * Any earlier events are irrelevant, so reset our buffer. + * This has the effect of allowing us to deal with reset + * floods (an external device holding down the reset line) + * without losing the event that is really interesting. + */ + lstate->event_r_idx = 0; + lstate->event_w_idx = 0; + xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE); + } + + if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) { + xpt_print_path(lstate->path); + printf("immediate event %x:%x lost\n", + lstate->event_buffer[lstate->event_r_idx].event_type, + lstate->event_buffer[lstate->event_r_idx].event_arg); + lstate->event_r_idx++; + if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE) + lstate->event_r_idx = 0; + xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE); + } + + event = &lstate->event_buffer[lstate->event_w_idx]; + event->initiator_id = initiator_id; + event->event_type = event_type; + event->event_arg = event_arg; + lstate->event_w_idx++; + if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE) + lstate->event_w_idx = 0; +} + +/* + * Send any target mode events queued up waiting + * for immediate notify resources. + */ +void +ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate) +{ + struct ccb_hdr *ccbh; + struct ccb_immed_notify *inot; + + while (lstate->event_r_idx != lstate->event_w_idx + && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) { + struct ahd_tmode_event *event; + + event = &lstate->event_buffer[lstate->event_r_idx]; + SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle); + inot = (struct ccb_immed_notify *)ccbh; + switch (event->event_type) { + case EVENT_TYPE_BUS_RESET: + ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN; + break; + default: + ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN; + inot->message_args[0] = event->event_type; + inot->message_args[1] = event->event_arg; + break; + } + inot->initiator_id = event->initiator_id; + inot->sense_len = 0; + xpt_done((union ccb *)inot); + lstate->event_r_idx++; + if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE) + lstate->event_r_idx = 0; + } +} +#endif + +/******************** Sequencer Program Patching/Download *********************/ + +#ifdef AHD_DUMP_SEQ +void +ahd_dumpseq(struct ahd_softc* ahd) +{ + int i; + int max_prog; + + max_prog = 2048; + + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); + ahd_outb(ahd, PRGMCNT, 0); + ahd_outb(ahd, PRGMCNT+1, 0); + for (i = 0; i < max_prog; i++) { + uint8_t ins_bytes[4]; + + ahd_insb(ahd, SEQRAM, ins_bytes, 4); + printf("0x%08x\n", ins_bytes[0] << 24 + | ins_bytes[1] << 16 + | ins_bytes[2] << 8 + | ins_bytes[3]); + } +} +#endif + +static void +ahd_loadseq(struct ahd_softc *ahd) +{ + struct cs cs_table[num_critical_sections]; + u_int begin_set[num_critical_sections]; + u_int end_set[num_critical_sections]; + struct patch *cur_patch; + u_int cs_count; + u_int cur_cs; + u_int i; + int downloaded; + u_int skip_addr; + u_int sg_prefetch_cnt; + u_int sg_prefetch_cnt_limit; + u_int sg_prefetch_align; + u_int sg_size; + uint8_t download_consts[DOWNLOAD_CONST_COUNT]; + + if (bootverbose) + printf("%s: Downloading Sequencer Program...", + ahd_name(ahd)); + +#if DOWNLOAD_CONST_COUNT != 7 +#error "Download Const Mismatch" +#endif + /* + * Start out with 0 critical sections + * that apply to this firmware load. + */ + cs_count = 0; + cur_cs = 0; + memset(begin_set, 0, sizeof(begin_set)); + memset(end_set, 0, sizeof(end_set)); + + /* + * Setup downloadable constant table. + * + * The computation for the S/G prefetch variables is + * a bit complicated. We would like to always fetch + * in terms of cachelined sized increments. However, + * if the cacheline is not an even multiple of the + * SG element size or is larger than our SG RAM, using + * just the cache size might leave us with only a portion + * of an SG element at the tail of a prefetch. If the + * cacheline is larger than our S/G prefetch buffer less + * the size of an SG element, we may round down to a cacheline + * that doesn't contain any or all of the S/G of interest + * within the bounds of our S/G ram. Provide variables to + * the sequencer that will allow it to handle these edge + * cases. + */ + /* Start by aligning to the nearest cacheline. */ + sg_prefetch_align = ahd->pci_cachesize; + if (sg_prefetch_align == 0) + sg_prefetch_cnt = 8; + /* Round down to the nearest power of 2. */ + while (powerof2(sg_prefetch_align) == 0) + sg_prefetch_align--; + /* + * If the cacheline boundary is greater than half our prefetch RAM + * we risk not being able to fetch even a single complete S/G + * segment if we align to that boundary. + */ + if (sg_prefetch_align > CCSGADDR_MAX/2) + sg_prefetch_align = CCSGADDR_MAX/2; + /* Start by fetching a single cacheline. */ + sg_prefetch_cnt = sg_prefetch_align; + /* + * Increment the prefetch count by cachelines until + * at least one S/G element will fit. + */ + sg_size = sizeof(struct ahd_dma_seg); + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + sg_size = sizeof(struct ahd_dma64_seg); + while (sg_prefetch_cnt < sg_size) + sg_prefetch_cnt += sg_prefetch_align; + /* + * If the cacheline is not an even multiple of + * the S/G size, we may only get a partial S/G when + * we align. Add a cacheline if this is the case. + */ + if ((sg_prefetch_align % sg_size) != 0 + && (sg_prefetch_cnt < CCSGADDR_MAX)) + sg_prefetch_cnt += sg_prefetch_align; + /* + * Lastly, compute a value that the sequencer can use + * to determine if the remainder of the CCSGRAM buffer + * has a full S/G element in it. + */ + sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1); + download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt; + download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit; + download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1); + download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1); + download_consts[SG_SIZEOF] = sg_size; + download_consts[PKT_OVERRUN_BUFOFFSET] = + (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256; + download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN; + if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) + download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_FULL_LUN; + cur_patch = patches; + downloaded = 0; + skip_addr = 0; + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); + ahd_outb(ahd, PRGMCNT, 0); + ahd_outb(ahd, PRGMCNT+1, 0); + + for (i = 0; i < sizeof(seqprog)/4; i++) { + if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) { + /* + * Don't download this instruction as it + * is in a patch that was removed. + */ + continue; + } + /* + * Move through the CS table until we find a CS + * that might apply to this instruction. + */ + for (; cur_cs < num_critical_sections; cur_cs++) { + if (critical_sections[cur_cs].end <= i) { + if (begin_set[cs_count] == TRUE + && end_set[cs_count] == FALSE) { + cs_table[cs_count].end = downloaded; + end_set[cs_count] = TRUE; + cs_count++; + } + continue; + } + if (critical_sections[cur_cs].begin <= i + && begin_set[cs_count] == FALSE) { + cs_table[cs_count].begin = downloaded; + begin_set[cs_count] = TRUE; + } + break; + } + ahd_download_instr(ahd, i, download_consts); + downloaded++; + } + + ahd->num_critical_sections = cs_count; + if (cs_count != 0) { + + cs_count *= sizeof(struct cs); + ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT); + if (ahd->critical_sections == NULL) + panic("ahd_loadseq: Could not malloc"); + memcpy(ahd->critical_sections, cs_table, cs_count); + } + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE); + + if (bootverbose) { + printf(" %d instructions downloaded\n", downloaded); + printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", + ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags); + } +} + +static int +ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch, + u_int start_instr, u_int *skip_addr) +{ + struct patch *cur_patch; + struct patch *last_patch; + u_int num_patches; + + num_patches = sizeof(patches)/sizeof(struct patch); + last_patch = &patches[num_patches]; + cur_patch = *start_patch; + + while (cur_patch < last_patch && start_instr == cur_patch->begin) { + + if (cur_patch->patch_func(ahd) == 0) { + + /* Start rejecting code */ + *skip_addr = start_instr + cur_patch->skip_instr; + cur_patch += cur_patch->skip_patch; + } else { + /* Accepted this patch. Advance to the next + * one and wait for our intruction pointer to + * hit this point. + */ + cur_patch++; + } + } + + *start_patch = cur_patch; + if (start_instr < *skip_addr) + /* Still skipping */ + return (0); + + return (1); +} + +static u_int +ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address) +{ + struct patch *cur_patch; + int address_offset; + u_int skip_addr; + u_int i; + + address_offset = 0; + cur_patch = patches; + skip_addr = 0; + + for (i = 0; i < address;) { + + ahd_check_patch(ahd, &cur_patch, i, &skip_addr); + + if (skip_addr > i) { + int end_addr; + + end_addr = MIN(address, skip_addr); + address_offset += end_addr - i; + i = skip_addr; + } else { + i++; + } + } + return (address - address_offset); +} + +static void +ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts) +{ + union ins_formats instr; + struct ins_format1 *fmt1_ins; + struct ins_format3 *fmt3_ins; + u_int opcode; + + /* + * The firmware is always compiled into a little endian format. + */ + instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]); + + fmt1_ins = &instr.format1; + fmt3_ins = NULL; + + /* Pull the opcode */ + opcode = instr.format1.opcode; + switch (opcode) { + case AIC_OP_JMP: + case AIC_OP_JC: + case AIC_OP_JNC: + case AIC_OP_CALL: + case AIC_OP_JNE: + case AIC_OP_JNZ: + case AIC_OP_JE: + case AIC_OP_JZ: + { + fmt3_ins = &instr.format3; + fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address); + /* FALLTHROUGH */ + } + case AIC_OP_OR: + case AIC_OP_AND: + case AIC_OP_XOR: + case AIC_OP_ADD: + case AIC_OP_ADC: + case AIC_OP_BMOV: + if (fmt1_ins->parity != 0) { + fmt1_ins->immediate = dconsts[fmt1_ins->immediate]; + } + fmt1_ins->parity = 0; + /* FALLTHROUGH */ + case AIC_OP_ROL: + { + int i, count; + + /* Calculate odd parity for the instruction */ + for (i = 0, count = 0; i < 31; i++) { + uint32_t mask; + + mask = 0x01 << i; + if ((instr.integer & mask) != 0) + count++; + } + if ((count & 0x01) == 0) + instr.format1.parity = 1; + + /* The sequencer is a little endian cpu */ + instr.integer = ahd_htole32(instr.integer); + ahd_outsb(ahd, SEQRAM, instr.bytes, 4); + break; + } + default: + panic("Unknown opcode encountered in seq program"); + break; + } +} + +static int +ahd_probe_stack_size(struct ahd_softc *ahd) +{ + int last_probe; + + last_probe = 0; + while (1) { + int i; + + /* + * We avoid using 0 as a pattern to avoid + * confusion if the stack implementation + * "back-fills" with zeros when "poping' + * entries. + */ + for (i = 1; i <= last_probe+1; i++) { + ahd_outb(ahd, STACK, i & 0xFF); + ahd_outb(ahd, STACK, (i >> 8) & 0xFF); + } + + /* Verify */ + for (i = last_probe+1; i > 0; i--) { + u_int stack_entry; + + stack_entry = ahd_inb(ahd, STACK) + |(ahd_inb(ahd, STACK) << 8); + if (stack_entry != i) + goto sized; + } + last_probe++; + } +sized: + return (last_probe); +} + +void +ahd_dump_all_cards_state() +{ + struct ahd_softc *list_ahd; + + TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { + ahd_dump_card_state(list_ahd); + } +} + +int +ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, + const char *name, u_int address, u_int value, + u_int *cur_column, u_int wrap_point) +{ + int printed; + u_int printed_mask; + + if (cur_column != NULL && *cur_column >= wrap_point) { + printf("\n"); + *cur_column = 0; + } + printed = printf("%s[0x%x]", name, value); + if (table == NULL) { + printed += printf(" "); + *cur_column += printed; + return (printed); + } + printed_mask = 0; + while (printed_mask != 0xFF) { + int entry; + + for (entry = 0; entry < num_entries; entry++) { + if (((value & table[entry].mask) + != table[entry].value) + || ((printed_mask & table[entry].mask) + == table[entry].mask)) + continue; + + printed += printf("%s%s", + printed_mask == 0 ? ":(" : "|", + table[entry].name); + printed_mask |= table[entry].mask; + + break; + } + if (entry >= num_entries) + break; + } + if (printed_mask != 0) + printed += printf(") "); + else + printed += printf(" "); + if (cur_column != NULL) + *cur_column += printed; + return (printed); +} + +void +ahd_dump_card_state(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int dffstat; + int paused; + u_int scb_index; + u_int saved_scb_index; + u_int cur_col; + int i; + + if (ahd_is_paused(ahd)) { + paused = 1; + } else { + paused = 0; + ahd_pause(ahd); + } + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" + "%s: Dumping Card State at program address 0x%x Mode 0x%x\n", + ahd_name(ahd), + ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8), + ahd_build_mode_state(ahd, ahd->saved_src_mode, + ahd->saved_dst_mode)); + if (paused) + printf("Card was paused\n"); + /* + * Mode independent registers. + */ + cur_col = 0; + ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50); + ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50); + ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50); + ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50); + ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50); + ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50); + ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50); + ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50); + ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50); + ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50); + ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50); + ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50); + ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50); + ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50); + ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50); + ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50); + ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50); + ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50); + ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50); + ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50); + ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50); + ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50); + ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50); + ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50); + ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50); + ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50); + ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50); + printf("\n"); + printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x " + "CURRSCB 0x%x NEXTSCB 0x%x\n", + ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING), + ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB), + ahd_inw(ahd, NEXTSCB)); + cur_col = 0; + /* QINFIFO */ + ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT); + saved_scb_index = ahd_get_scbptr(ahd); + printf("Pending list:"); + i = 0; + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + if (i++ > AHD_SCB_MAX) + break; + cur_col = printf("\n%3d ", SCB_GET_TAG(scb)); + ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); + ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60); + ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60); + ahd_scb_tag_print(ahd_inb(ahd, SCB_TAG), &cur_col, 60); + } + printf("\nTotal %d\n", i); + + printf("Kernel Free SCB list: "); + i = 0; + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { + struct scb *list_scb; + + list_scb = scb; + do { + printf("%d ", SCB_GET_TAG(list_scb)); + list_scb = LIST_NEXT(list_scb, collision_links); + } while (list_scb && i++ < AHD_SCB_MAX); + } + + LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { + if (i++ > AHD_SCB_MAX) + break; + printf("%d ", SCB_GET_TAG(scb)); + } + printf("\n"); + + printf("Sequencer Complete DMA-inprog list: "); + scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD); + i = 0; + while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { + ahd_set_scbptr(ahd, scb_index); + printf("%d ", scb_index); + scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); + } + printf("\n"); + + printf("Sequencer Complete list: "); + scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD); + i = 0; + while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { + ahd_set_scbptr(ahd, scb_index); + printf("%d ", scb_index); + scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); + } + printf("\n"); + + + printf("Sequencer DMA-Up and Complete list: "); + scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); + i = 0; + while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { + ahd_set_scbptr(ahd, scb_index); + printf("%d ", scb_index); + scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); + } + printf("\n"); + ahd_set_scbptr(ahd, saved_scb_index); + dffstat = ahd_inb(ahd, DFFSTAT); + for (i = 0; i < 2; i++) { +#ifdef AHD_DEBUG + struct scb *fifo_scb; +#endif + u_int fifo_scbptr; + + ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); + fifo_scbptr = ahd_get_scbptr(ahd); + printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, " + "SCB 0x%x, LJSCB 0x%x\n", + ahd_name(ahd), i, + (dffstat & (FIFO0FREE << i)) ? "Free" : "Active", + ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr, + ahd_inw(ahd, LONGJMP_SCB)); + cur_col = 0; + ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50); + ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50); + ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50); + ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50); + ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW), + &cur_col, 50); + ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50); + ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50); + ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50); + ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50); + if (cur_col > 50) { + printf("\n"); + cur_col = 0; + } + cur_col += printf("SHADDR = 0x%x%x, SHCNT = 0x%x ", + ahd_inl(ahd, SHADDR+4), + ahd_inl(ahd, SHADDR), + (ahd_inb(ahd, SHCNT) + | (ahd_inb(ahd, SHCNT + 1) << 8) + | (ahd_inb(ahd, SHCNT + 2) << 16))); + if (cur_col > 50) { + printf("\n"); + cur_col = 0; + } + cur_col += printf("HADDR = 0x%x%x, HCNT = 0x%x ", + ahd_inl(ahd, HADDR+4), + ahd_inl(ahd, HADDR), + (ahd_inb(ahd, HCNT) + | (ahd_inb(ahd, HCNT + 1) << 8) + | (ahd_inb(ahd, HCNT + 2) << 16))); + ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SG) != 0) { + fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr); + if (fifo_scb != NULL) + ahd_dump_sglist(fifo_scb); + } +#endif + } + printf("\nLQIN: "); + for (i = 0; i < 20; i++) + printf("0x%x ", ahd_inb(ahd, LQIN + i)); + printf("\n"); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE), + ahd_inb(ahd, OPTIONMODE)); + printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT), + ahd_inb(ahd, MAXCMDCNT)); + ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50); + printf("\n"); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + cur_col = 0; + ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50); + printf("\n"); + ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); + printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n", + ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX), + ahd_inw(ahd, DINDEX)); + printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n", + ahd_name(ahd), ahd_get_scbptr(ahd), ahd_inw(ahd, SCB_NEXT), + ahd_inw(ahd, SCB_NEXT2)); + printf("CDB %x %x %x %x %x %x\n", + ahd_inb(ahd, SCB_CDB_STORE), + ahd_inb(ahd, SCB_CDB_STORE+1), + ahd_inb(ahd, SCB_CDB_STORE+2), + ahd_inb(ahd, SCB_CDB_STORE+3), + ahd_inb(ahd, SCB_CDB_STORE+4), + ahd_inb(ahd, SCB_CDB_STORE+5)); + printf("STACK:"); + for (i = 0; i < ahd->stack_size; i++) { + ahd->saved_stack[i] = + ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8); + printf(" 0x%x", ahd->saved_stack[i]); + } + for (i = ahd->stack_size-1; i >= 0; i--) { + ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF); + ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF); + } + printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); + ahd_platform_dump_card_state(ahd); + ahd_restore_modes(ahd, saved_modes); + if (paused == 0) + ahd_unpause(ahd); +} + +void +ahd_dump_scbs(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + u_int saved_scb_index; + int i; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + saved_scb_index = ahd_get_scbptr(ahd); + for (i = 0; i < AHD_SCB_MAX; i++) { + ahd_set_scbptr(ahd, i); + printf("%3d", i); + printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n", + ahd_inb(ahd, SCB_CONTROL), + ahd_inb(ahd, SCB_SCSIID), ahd_inw(ahd, SCB_NEXT), + ahd_inw(ahd, SCB_NEXT2), ahd_inl(ahd, SCB_SGPTR), + ahd_inl(ahd, SCB_RESIDUAL_SGPTR)); + } + printf("\n"); + ahd_set_scbptr(ahd, saved_scb_index); + ahd_restore_modes(ahd, saved_modes); +} + +/**************************** Flexport Logic **********************************/ +/* + * Read count 16bit words from 16bit word address start_addr from the + * SEEPROM attached to the controller, into buf, using the controller's + * SEEPROM reading state machine. + */ +int +ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count) +{ + u_int cur_addr; + u_int end_addr; + int error; + + /* + * If we never make it through the loop even once, + * we were passed invalid arguments. + */ + error = EINVAL; + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + end_addr = start_addr + count; + for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { + ahd_outb(ahd, SEEADR, cur_addr); + ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART); + + error = ahd_wait_seeprom(ahd); + if (error) + break; + *buf++ = ahd_inw(ahd, SEEDAT); + } + return (error); +} + +/* + * Write count 16bit words from buf, into SEEPROM attache to the + * controller starting at 16bit word address start_addr, using the + * controller's SEEPROM writing state machine. + */ +int +ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count) +{ + u_int cur_addr; + u_int end_addr; + int error; + int retval; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + error = ENOENT; + + /* Place the chip into write-enable mode */ + ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR); + ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART); + error = ahd_wait_seeprom(ahd); + if (error) + return (error); + + /* + * Write the data. If we don't get throught the loop at + * least once, the arguments were invalid. + */ + retval = EINVAL; + end_addr = start_addr + count; + for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { + ahd_outw(ahd, SEEDAT, *buf++); + ahd_outb(ahd, SEEADR, cur_addr); + ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART); + + retval = ahd_wait_seeprom(ahd); + if (retval) + break; + } + + /* + * Disable writes. + */ + ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR); + ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART); + error = ahd_wait_seeprom(ahd); + if (error) + return (error); + return (retval); +} + +/* + * Wait ~100us for the serial eeprom to satisfy our request. + */ +int +ahd_wait_seeprom(struct ahd_softc *ahd) +{ + int cnt; + + cnt = 20; + while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt) + ahd_delay(5); + + if (cnt == 0) + return (ETIMEDOUT); + return (0); +} + +int +ahd_verify_cksum(struct seeprom_config *sc) +{ + int i; + int maxaddr; + uint32_t checksum; + uint16_t *scarray; + + maxaddr = (sizeof(*sc)/2) - 1; + checksum = 0; + scarray = (uint16_t *)sc; + + for (i = 0; i < maxaddr; i++) + checksum = checksum + scarray[i]; + if (checksum == 0 + || (checksum & 0xFFFF) != sc->checksum) { + return (0); + } else { + return (1); + } +} + +int +ahd_acquire_seeprom(struct ahd_softc *ahd) +{ + /* + * We should be able to determine the SEEPROM type + * from the flexport logic, but unfortunately not + * all implementations have this logic and there is + * no programatic method for determining if the logic + * is present. + */ + return (1); +#if 0 + uint8_t seetype; + int error; + + error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype); + if (error != 0 + || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE)) + return (0); + return (1); +#endif +} + +void +ahd_release_seeprom(struct ahd_softc *ahd) +{ + /* Currently a no-op */ +} + +int +ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) +{ + int error; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + if (addr > 7) + panic("ahd_write_flexport: address out of range"); + ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3)); + error = ahd_wait_flexport(ahd); + if (error != 0) + return (error); + ahd_outb(ahd, BRDDAT, value); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3)); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3)); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, BRDCTL, 0); + ahd_flush_device_writes(ahd); + return (0); +} + +int +ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value) +{ + int error; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + if (addr > 7) + panic("ahd_read_flexport: address out of range"); + ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3)); + error = ahd_wait_flexport(ahd); + if (error != 0) + return (error); + *value = ahd_inb(ahd, BRDDAT); + ahd_outb(ahd, BRDCTL, 0); + ahd_flush_device_writes(ahd); + return (0); +} + +/* + * Wait at most 2 seconds for flexport arbitration to succeed. + */ +int +ahd_wait_flexport(struct ahd_softc *ahd) +{ + int cnt; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + cnt = 1000000 * 2 / 5; + while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) + ahd_delay(5); + + if (cnt == 0) + return (ETIMEDOUT); + return (0); +} + +/************************* Target Mode ****************************************/ +#ifdef AHD_TARGET_MODE +cam_status +ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb, + struct ahd_tmode_tstate **tstate, + struct ahd_tmode_lstate **lstate, + int notfound_failure) +{ + + if ((ahd->features & AHD_TARGETMODE) == 0) + return (CAM_REQ_INVALID); + + /* + * Handle the 'black hole' device that sucks up + * requests to unattached luns on enabled targets. + */ + if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD + && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) { + *tstate = NULL; + *lstate = ahd->black_hole; + } else { + u_int max_id; + + max_id = (ahd->features & AHD_WIDE) ? 15 : 7; + if (ccb->ccb_h.target_id > max_id) + return (CAM_TID_INVALID); + + if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS) + return (CAM_LUN_INVALID); + + *tstate = ahd->enabled_targets[ccb->ccb_h.target_id]; + *lstate = NULL; + if (*tstate != NULL) + *lstate = + (*tstate)->enabled_luns[ccb->ccb_h.target_lun]; + } + + if (notfound_failure != 0 && *lstate == NULL) + return (CAM_PATH_INVALID); + + return (CAM_REQ_CMP); +} + +void +ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) +{ +#if NOT_YET + struct ahd_tmode_tstate *tstate; + struct ahd_tmode_lstate *lstate; + struct ccb_en_lun *cel; + cam_status status; + u_int target; + u_int lun; + u_int target_mask; + u_long s; + char channel; + + status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate, + /*notfound_failure*/FALSE); + + if (status != CAM_REQ_CMP) { + ccb->ccb_h.status = status; + return; + } + + if ((ahd->features & AHD_MULTIROLE) != 0) { + u_int our_id; + + our_id = ahd->our_id; + if (ccb->ccb_h.target_id != our_id) { + if ((ahd->features & AHD_MULTI_TID) != 0 + && (ahd->flags & AHD_INITIATORROLE) != 0) { + /* + * Only allow additional targets if + * the initiator role is disabled. + * The hardware cannot handle a re-select-in + * on the initiator id during a re-select-out + * on a different target id. + */ + status = CAM_TID_INVALID; + } else if ((ahd->flags & AHD_INITIATORROLE) != 0 + || ahd->enabled_luns > 0) { + /* + * Only allow our target id to change + * if the initiator role is not configured + * and there are no enabled luns which + * are attached to the currently registered + * scsi id. + */ + status = CAM_TID_INVALID; + } + } + } + + if (status != CAM_REQ_CMP) { + ccb->ccb_h.status = status; + return; + } + + /* + * We now have an id that is valid. + * If we aren't in target mode, switch modes. + */ + if ((ahd->flags & AHD_TARGETROLE) == 0 + && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { + u_long s; + + printf("Configuring Target Mode\n"); + ahd_lock(ahd, &s); + if (LIST_FIRST(&ahd->pending_scbs) != NULL) { + ccb->ccb_h.status = CAM_BUSY; + ahd_unlock(ahd, &s); + return; + } + ahd->flags |= AHD_TARGETROLE; + if ((ahd->features & AHD_MULTIROLE) == 0) + ahd->flags &= ~AHD_INITIATORROLE; + ahd_pause(ahd); + ahd_loadseq(ahd); + ahd_unlock(ahd, &s); + } + cel = &ccb->cel; + target = ccb->ccb_h.target_id; + lun = ccb->ccb_h.target_lun; + channel = SIM_CHANNEL(ahd, sim); + target_mask = 0x01 << target; + if (channel == 'B') + target_mask <<= 8; + + if (cel->enable != 0) { + u_int scsiseq1; + + /* Are we already enabled?? */ + if (lstate != NULL) { + xpt_print_path(ccb->ccb_h.path); + printf("Lun already enabled\n"); + ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; + return; + } + + if (cel->grp6_len != 0 + || cel->grp7_len != 0) { + /* + * Don't (yet?) support vendor + * specific commands. + */ + ccb->ccb_h.status = CAM_REQ_INVALID; + printf("Non-zero Group Codes\n"); + return; + } + + /* + * Seems to be okay. + * Setup our data structures. + */ + if (target != CAM_TARGET_WILDCARD && tstate == NULL) { + tstate = ahd_alloc_tstate(ahd, target, channel); + if (tstate == NULL) { + xpt_print_path(ccb->ccb_h.path); + printf("Couldn't allocate tstate\n"); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + return; + } + } + lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT); + if (lstate == NULL) { + xpt_print_path(ccb->ccb_h.path); + printf("Couldn't allocate lstate\n"); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + return; + } + memset(lstate, 0, sizeof(*lstate)); + status = xpt_create_path(&lstate->path, /*periph*/NULL, + xpt_path_path_id(ccb->ccb_h.path), + xpt_path_target_id(ccb->ccb_h.path), + xpt_path_lun_id(ccb->ccb_h.path)); + if (status != CAM_REQ_CMP) { + free(lstate, M_DEVBUF); + xpt_print_path(ccb->ccb_h.path); + printf("Couldn't allocate path\n"); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + return; + } + SLIST_INIT(&lstate->accept_tios); + SLIST_INIT(&lstate->immed_notifies); + ahd_lock(ahd, &s); + ahd_pause(ahd); + if (target != CAM_TARGET_WILDCARD) { + tstate->enabled_luns[lun] = lstate; + ahd->enabled_luns++; + + if ((ahd->features & AHD_MULTI_TID) != 0) { + u_int targid_mask; + + targid_mask = ahd_inb(ahd, TARGID) + | (ahd_inb(ahd, TARGID + 1) << 8); + + targid_mask |= target_mask; + ahd_outb(ahd, TARGID, targid_mask); + ahd_outb(ahd, TARGID+1, (targid_mask >> 8)); + + ahd_update_scsiid(ahd, targid_mask); + } else { + u_int our_id; + char channel; + + channel = SIM_CHANNEL(ahd, sim); + our_id = SIM_SCSI_ID(ahd, sim); + + /* + * This can only happen if selections + * are not enabled + */ + if (target != our_id) { + u_int sblkctl; + char cur_channel; + int swap; + + sblkctl = ahd_inb(ahd, SBLKCTL); + cur_channel = (sblkctl & SELBUSB) + ? 'B' : 'A'; + if ((ahd->features & AHD_TWIN) == 0) + cur_channel = 'A'; + swap = cur_channel != channel; + ahd->our_id = target; + + if (swap) + ahd_outb(ahd, SBLKCTL, + sblkctl ^ SELBUSB); + + ahd_outb(ahd, SCSIID, target); + + if (swap) + ahd_outb(ahd, SBLKCTL, sblkctl); + } + } + } else + ahd->black_hole = lstate; + /* Allow select-in operations */ + if (ahd->black_hole != NULL && ahd->enabled_luns > 0) { + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + scsiseq1 |= ENSELI; + ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1); + scsiseq1 = ahd_inb(ahd, SCSISEQ1); + scsiseq1 |= ENSELI; + ahd_outb(ahd, SCSISEQ1, scsiseq1); + } + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_print_path(ccb->ccb_h.path); + printf("Lun now enabled for target mode\n"); + } else { + struct scb *scb; + int i, empty; + + if (lstate == NULL) { + ccb->ccb_h.status = CAM_LUN_INVALID; + return; + } + + ahd_lock(ahd, &s); + + ccb->ccb_h.status = CAM_REQ_CMP; + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + struct ccb_hdr *ccbh; + + ccbh = &scb->io_ctx->ccb_h; + if (ccbh->func_code == XPT_CONT_TARGET_IO + && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){ + printf("CTIO pending\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + ahd_unlock(ahd, &s); + return; + } + } + + if (SLIST_FIRST(&lstate->accept_tios) != NULL) { + printf("ATIOs pending\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + } + + if (SLIST_FIRST(&lstate->immed_notifies) != NULL) { + printf("INOTs pending\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + } + + if (ccb->ccb_h.status != CAM_REQ_CMP) { + ahd_unlock(ahd, &s); + return; + } + + xpt_print_path(ccb->ccb_h.path); + printf("Target mode disabled\n"); + xpt_free_path(lstate->path); + free(lstate, M_DEVBUF); + + ahd_pause(ahd); + /* Can we clean up the target too? */ + if (target != CAM_TARGET_WILDCARD) { + tstate->enabled_luns[lun] = NULL; + ahd->enabled_luns--; + for (empty = 1, i = 0; i < 8; i++) + if (tstate->enabled_luns[i] != NULL) { + empty = 0; + break; + } + + if (empty) { + ahd_free_tstate(ahd, target, channel, + /*force*/FALSE); + if (ahd->features & AHD_MULTI_TID) { + u_int targid_mask; + + targid_mask = ahd_inb(ahd, TARGID) + | (ahd_inb(ahd, TARGID + 1) + << 8); + + targid_mask &= ~target_mask; + ahd_outb(ahd, TARGID, targid_mask); + ahd_outb(ahd, TARGID+1, + (targid_mask >> 8)); + ahd_update_scsiid(ahd, targid_mask); + } + } + } else { + + ahd->black_hole = NULL; + + /* + * We can't allow selections without + * our black hole device. + */ + empty = TRUE; + } + if (ahd->enabled_luns == 0) { + /* Disallow select-in */ + u_int scsiseq1; + + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + scsiseq1 &= ~ENSELI; + ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1); + scsiseq1 = ahd_inb(ahd, SCSISEQ1); + scsiseq1 &= ~ENSELI; + ahd_outb(ahd, SCSISEQ1, scsiseq1); + + if ((ahd->features & AHD_MULTIROLE) == 0) { + printf("Configuring Initiator Mode\n"); + ahd->flags &= ~AHD_TARGETROLE; + ahd->flags |= AHD_INITIATORROLE; + ahd_pause(ahd); + ahd_loadseq(ahd); + } + } + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + } +#endif +} + +static void +ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask) +{ +#if NOT_YET + u_int scsiid_mask; + u_int scsiid; + + if ((ahd->features & AHD_MULTI_TID) == 0) + panic("ahd_update_scsiid called on non-multitid unit\n"); + + /* + * Since we will rely on the TARGID mask + * for selection enables, ensure that OID + * in SCSIID is not set to some other ID + * that we don't want to allow selections on. + */ + if ((ahd->features & AHD_ULTRA2) != 0) + scsiid = ahd_inb(ahd, SCSIID_ULTRA2); + else + scsiid = ahd_inb(ahd, SCSIID); + scsiid_mask = 0x1 << (scsiid & OID); + if ((targid_mask & scsiid_mask) == 0) { + u_int our_id; + + /* ffs counts from 1 */ + our_id = ffs(targid_mask); + if (our_id == 0) + our_id = ahd->our_id; + else + our_id--; + scsiid &= TID; + scsiid |= our_id; + } + if ((ahd->features & AHD_ULTRA2) != 0) + ahd_outb(ahd, SCSIID_ULTRA2, scsiid); + else + ahd_outb(ahd, SCSIID, scsiid); +#endif +} + +void +ahd_run_tqinfifo(struct ahd_softc *ahd, int paused) +{ + struct target_cmd *cmd; + + ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD); + while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) { + + /* + * Only advance through the queue if we + * have the resources to process the command. + */ + if (ahd_handle_target_cmd(ahd, cmd) != 0) + break; + + cmd->cmd_valid = 0; + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap, + ahd_targetcmd_offset(ahd, ahd->tqinfifonext), + sizeof(struct target_cmd), + BUS_DMASYNC_PREREAD); + ahd->tqinfifonext++; + + /* + * Lazily update our position in the target mode incoming + * command queue as seen by the sequencer. + */ + if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) { + u_int hs_mailbox; + + hs_mailbox = ahd_inb(ahd, HS_MAILBOX); + hs_mailbox &= ~HOST_TQINPOS; + hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS; + ahd_outb(ahd, HS_MAILBOX, hs_mailbox); + } + } +} + +static int +ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd) +{ + struct ahd_tmode_tstate *tstate; + struct ahd_tmode_lstate *lstate; + struct ccb_accept_tio *atio; + uint8_t *byte; + int initiator; + int target; + int lun; + + initiator = SCSIID_TARGET(ahd, cmd->scsiid); + target = SCSIID_OUR_ID(cmd->scsiid); + lun = (cmd->identify & MSG_IDENTIFY_LUNMASK); + + byte = cmd->bytes; + tstate = ahd->enabled_targets[target]; + lstate = NULL; + if (tstate != NULL) + lstate = tstate->enabled_luns[lun]; + + /* + * Commands for disabled luns go to the black hole driver. + */ + if (lstate == NULL) + lstate = ahd->black_hole; + + atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios); + if (atio == NULL) { + ahd->flags |= AHD_TQINFIFO_BLOCKED; + /* + * Wait for more ATIOs from the peripheral driver for this lun. + */ + return (1); + } else + ahd->flags &= ~AHD_TQINFIFO_BLOCKED; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_TQIN) != 0) + printf("Incoming command from %d for %d:%d%s\n", + initiator, target, lun, + lstate == ahd->black_hole ? "(Black Holed)" : ""); +#endif + SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle); + + if (lstate == ahd->black_hole) { + /* Fill in the wildcards */ + atio->ccb_h.target_id = target; + atio->ccb_h.target_lun = lun; + } + + /* + * Package it up and send it off to + * whomever has this lun enabled. + */ + atio->sense_len = 0; + atio->init_id = initiator; + if (byte[0] != 0xFF) { + /* Tag was included */ + atio->tag_action = *byte++; + atio->tag_id = *byte++; + atio->ccb_h.flags = CAM_TAG_ACTION_VALID; + } else { + atio->ccb_h.flags = 0; + } + byte++; + + /* Okay. Now determine the cdb size based on the command code */ + switch (*byte >> CMD_GROUP_CODE_SHIFT) { + case 0: + atio->cdb_len = 6; + break; + case 1: + case 2: + atio->cdb_len = 10; + break; + case 4: + atio->cdb_len = 16; + break; + case 5: + atio->cdb_len = 12; + break; + case 3: + default: + /* Only copy the opcode. */ + atio->cdb_len = 1; + printf("Reserved or VU command code type encountered\n"); + break; + } + + memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len); + + atio->ccb_h.status |= CAM_CDB_RECVD; + + if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) { + /* + * We weren't allowed to disconnect. + * We're hanging on the bus until a + * continue target I/O comes in response + * to this accept tio. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_TQIN) != 0) + printf("Received Immediate Command %d:%d:%d - %p\n", + initiator, target, lun, ahd->pending_device); +#endif + ahd->pending_device = lstate; + ahd_freeze_ccb((union ccb *)atio); + atio->ccb_h.flags |= CAM_DIS_DISCONNECT; + } + xpt_done((union ccb*)atio); + return (0); +} + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx.h --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx.h 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,1480 @@ +/* + * Core definitions and data structures shareable across OS platforms. + * + * Copyright (c) 1994-2002 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#78 $ + * + * $FreeBSD$ + */ + +#ifndef _AIC79XX_H_ +#define _AIC79XX_H_ + +/* Register Definitions */ +#include "aic79xx_reg.h" + +/************************* Forward Declarations *******************************/ +struct ahd_platform_data; +struct scb_platform_data; + +/****************************** Useful Macros *********************************/ +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) + +#define ALL_CHANNELS '\0' +#define ALL_TARGETS_MASK 0xFFFF +#define INITIATOR_WILDCARD (~0) +#define SCB_LIST_NULL 0xFF00 +#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL)) +#define QOUTFIFO_ENTRY_VALID 0x8000 +#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000)) +#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL) + +#define SCSIID_TARGET(ahd, scsiid) \ + (((scsiid) & TID) >> TID_SHIFT) +#define SCSIID_OUR_ID(scsiid) \ + ((scsiid) & OID) +#define SCSIID_CHANNEL(ahd, scsiid) ('A') +#define SCB_IS_SCSIBUS_B(ahd, scb) (0) +#define SCB_GET_OUR_ID(scb) \ + SCSIID_OUR_ID((scb)->hscb->scsiid) +#define SCB_GET_TARGET(ahd, scb) \ + SCSIID_TARGET((ahd), (scb)->hscb->scsiid) +#define SCB_GET_CHANNEL(ahd, scb) \ + SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid) +#define SCB_GET_LUN(scb) \ + ((scb)->hscb->lun) +#define SCB_GET_TARGET_OFFSET(ahd, scb) \ + SCB_GET_TARGET(ahd, scb) +#define SCB_GET_TARGET_MASK(ahd, scb) \ + (0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb))) +#ifdef AHD_DEBUG +#define SCB_IS_SILENT(scb) \ + ((ahd_debug & AHD_SHOW_MASKED_ERRORS) == 0 \ + && (((scb)->flags & SCB_SILENT) != 0)) +#else +#define SCB_IS_SILENT(scb) \ + (((scb)->flags & SCB_SILENT) != 0) +#endif +/* + * TCLs have the following format: TTTTLLLLLLLL + */ +#define TCL_TARGET_OFFSET(tcl) \ + ((((tcl) >> 4) & TID) >> 4) +#define TCL_LUN(tcl) \ + (tcl & (AHD_NUM_LUNS - 1)) +#define BUILD_TCL(scsiid, lun) \ + ((lun) | (((scsiid) & TID) << 4)) +#define BUILD_TCL_RAW(target, channel, lun) \ + ((lun) | ((target) << 8)) + +#define SCB_GET_TAG(scb) \ + ahd_le16toh(scb->hscb->tag) + +#ifndef AHD_TARGET_MODE +#undef AHD_TMODE_ENABLE +#define AHD_TMODE_ENABLE 0 +#endif + +#define AHD_BUILD_COL_IDX(target, lun) \ + (((lun) << 4) | target) + +#define AHD_GET_SCB_COL_IDX(ahd, scb) \ + ((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb)) + +#define AHD_SET_SCB_COL_IDX(scb, col_idx) \ +do { \ + (scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID; \ + (scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1); \ +} while (0) + +#define AHD_COPY_SCB_COL_IDX(dst, src) \ +do { \ + dst->hscb->scsiid = src->hscb->scsiid; \ + dst->hscb->lun = src->hscb->lun; \ +} while (0) + +#define AHD_NEVER_COL_IDX 0xFFFF + +/**************************** Driver Constants ********************************/ +/* + * The maximum number of supported targets. + */ +#define AHD_NUM_TARGETS 16 + +/* + * The maximum number of supported luns. + * The identify message only supports 64 luns in non-packetized transfers. + * You can have 2^64 luns when information unit transfers are enabled, + * but until we see a need to support that many, we support 256. + */ +#define AHD_NUM_LUNS_NONPKT 64 +#define AHD_NUM_LUNS 256 + +/* + * The maximum transfer per S/G segment. + */ +#define AHD_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */ + +/* + * The maximum amount of SCB storage in hardware on a controller. + * This value represents an upper bound. Due to software design, + * we may not be able to use this number. + */ +#define AHD_SCB_MAX 512 + +/* + * The maximum number of concurrent transactions supported per driver instance. + * Sequencer Control Blocks (SCBs) store per-transaction information. + */ +#define AHD_MAX_QUEUE AHD_SCB_MAX + +/* + * Define the size of our QIN and QOUT FIFOs. They must be a power of 2 + * in size and accomodate as many transactions as can be queued concurrently. + */ +#define AHD_QIN_SIZE AHD_MAX_QUEUE +#define AHD_QOUT_SIZE AHD_MAX_QUEUE + +#define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1)) +/* + * The maximum amount of SCB storage we allocate in host memory. + */ +#define AHD_SCB_MAX_ALLOC AHD_MAX_QUEUE + +/* + * Ring Buffer of incoming target commands. + * We allocate 256 to simplify the logic in the sequencer + * by using the natural wrap point of an 8bit counter. + */ +#define AHD_TMODE_CMDS 256 + +/* Reset line assertion time in us */ +#define AHD_BUSRESET_DELAY 25 + +/******************* Chip Characteristics/Operating Settings *****************/ +/* + * Chip Type + * The chip order is from least sophisticated to most sophisticated. + */ +typedef enum { + AHD_NONE = 0x0000, + AHD_CHIPID_MASK = 0x00FF, + AHD_AIC7901 = 0x0001, + AHD_AIC7902 = 0x0002, + AHD_AIC7901A = 0x0003, + AHD_PCI = 0x0100, /* Bus type PCI */ + AHD_PCIX = 0x0200, /* Bus type PCIX */ + AHD_BUS_MASK = 0x0F00 +} ahd_chip; + +/* + * Features available in each chip type. + */ +typedef enum { + AHD_FENONE = 0x00000, + AHD_WIDE = 0x00001,/* Wide Channel */ + AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */ + AHD_TARGETMODE = 0x01000,/* Has tested target mode support */ + AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */ + AHD_RTI = 0x04000,/* Retained Training Support */ + AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */ + AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */ + AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/ + AHD_AIC7901_FE = AHD_FENONE, + AHD_AIC7902_FE = AHD_MULTI_FUNC +} ahd_feature; + +/* + * Bugs in the silicon that we work around in software. + */ +typedef enum { + AHD_BUGNONE = 0x0000, + /* + * Rev A hardware fails to update LAST/CURR/NEXTSCB + * correctly in certain packetized selection cases. + */ + AHD_SENT_SCB_UPDATE_BUG = 0x0001, + /* The wrong SCB is accessed to check the abort pending bit. */ + AHD_ABORT_LQI_BUG = 0x0002, + /* Packetized bitbucket crosses packet boundaries. */ + AHD_PKT_BITBUCKET_BUG = 0x0004, + /* The selection timer runs twice as long as its setting. */ + AHD_LONG_SETIMO_BUG = 0x0008, + /* The Non-LQ CRC error status is delayed until phase change. */ + AHD_NLQICRC_DELAYED_BUG = 0x0010, + /* The chip must be reset for all outgoing bus resets. */ + AHD_SCSIRST_BUG = 0x0020, + /* Some PCIX fields must be saved and restored across chip reset. */ + AHD_PCIX_CHIPRST_BUG = 0x0040, + /* MMAPIO is not functional in PCI-X mode. */ + AHD_PCIX_MMAPIO_BUG = 0x0080, + /* Bug workarounds that can be disabled on non-PCIX busses. */ + AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG + | AHD_PCIX_MMAPIO_BUG, + /* + * LQOSTOP0 status set even for forced selections with ATN + * to perform non-packetized message delivery. + */ + AHD_LQO_ATNO_BUG = 0x0100, + /* FIFO auto-flush does not always trigger. */ + AHD_AUTOFLUSH_BUG = 0x0200, + /* The CLRLQO registers are not self-clearing. */ + AHD_CLRLQO_AUTOCLR_BUG = 0x0400, + /* The PACKETIZED status bit refers to the previous connection. */ + AHD_PKTIZED_STATUS_BUG = 0x0800, + /* "Short Luns" are not placed into outgoing LQ packets correctly. */ + AHD_PKT_LUN_BUG = 0x1000, + /* + * Only the FIFO allocated to the non-packetized connection may + * be in use during a non-packetzied connection. + */ + AHD_NONPACKFIFO_BUG = 0x2000, + /* + * Writing to a DFF SCBPTR register may fail if concurent with + * a hardware write to the other DFF SCBPTR register. This is + * not currently a concern in our sequencer since all chips with + * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern + * occur in non-packetized connections. + */ + AHD_MDFF_WSCBPTR_BUG = 0x4000, + /* SGHADDR updates are slow. */ + AHD_REG_SLOW_SETTLE_BUG = 0x8000, + /* + * Changing the MODE_PTR coincident with an interrupt that + * switches to a different mode will cause the interrupt to + * be in the mode written outside of interrupt context. + */ + AHD_SET_MODE_BUG = 0x10000, + /* Non-packetized busfree revision does not work. */ + AHD_BUSFREEREV_BUG = 0x20000, + /* + * Paced transfers are indicated with a non-standard PPR + * option bit in the neg table, 160MHz is indicated by + * sync factor 0x7, and the offset if off by a factor of 2. + */ + AHD_PACED_NEGTABLE_BUG = 0x40000, + /* LQOOVERRUN false positives. */ + AHD_LQOOVERRUN_BUG = 0x80000, + /* + * Controller write to INTSTAT will lose to a host + * write to CLRINT. + */ + AHD_INTCOLLISION_BUG = 0x100000 +} ahd_bug; + +/* + * Configuration specific settings. + * The driver determines these settings by probing the + * chip/controller's configuration. + */ +typedef enum { + AHD_FNONE = 0x00000, + AHD_PRIMARY_CHANNEL = 0x00003,/* + * The channel that should + * be probed first. + */ + AHD_USEDEFAULTS = 0x00004,/* + * For cards without an seeprom + * or a BIOS to initialize the chip's + * SRAM, we use the default target + * settings. + */ + AHD_SEQUENCER_DEBUG = 0x00008, + AHD_RESET_BUS_A = 0x00010, + AHD_EXTENDED_TRANS_A = 0x00020, + AHD_TERM_ENB_A = 0x00040, + AHD_SPCHK_ENB_A = 0x00080, + AHD_STPWLEVEL_A = 0x00100, + AHD_INITIATORROLE = 0x00200,/* + * Allow initiator operations on + * this controller. + */ + AHD_TARGETROLE = 0x00400,/* + * Allow target operations on this + * controller. + */ + AHD_RESOURCE_SHORTAGE = 0x00800, + AHD_TQINFIFO_BLOCKED = 0x01000,/* Blocked waiting for ATIOs */ + AHD_INT50_SPEEDFLEX = 0x02000,/* + * Internal 50pin connector + * sits behind an aic3860 + */ + AHD_BIOS_ENABLED = 0x04000, + AHD_ALL_INTERRUPTS = 0x08000, + AHD_39BIT_ADDRESSING = 0x10000,/* Use 39 bit addressing scheme. */ + AHD_64BIT_ADDRESSING = 0x20000,/* Use 64 bit addressing scheme. */ + AHD_CURRENT_SENSING = 0x40000, + AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */ + AHD_HP_BOARD = 0x100000, + AHD_RESET_POLL_ACTIVE = 0x200000, + AHD_UPDATE_PEND_CMDS = 0x400000, + AHD_RUNNING_QOUTFIFO = 0x800000 +} ahd_flag; + +/************************* Hardware SCB Definition ***************************/ + +/* + * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB + * consists of a "hardware SCB" mirroring the fields availible on the card + * and additional information the kernel stores for each transaction. + * + * To minimize space utilization, a portion of the hardware scb stores + * different data during different portions of a SCSI transaction. + * As initialized by the host driver for the initiator role, this area + * contains the SCSI cdb (or a pointer to the cdb) to be executed. After + * the cdb has been presented to the target, this area serves to store + * residual transfer information and the SCSI status byte. + * For the target role, the contents of this area do not change, but + * still serve a different purpose than for the initiator role. See + * struct target_data for details. + */ + +/* + * Status information embedded in the shared poriton of + * an SCB after passing the cdb to the target. The kernel + * driver will only read this data for transactions that + * complete abnormally. + */ +struct initiator_status { + uint32_t residual_datacnt; /* Residual in the current S/G seg */ + uint32_t residual_sgptr; /* The next S/G for this transfer */ + uint8_t scsi_status; /* Standard SCSI status byte */ +}; + +struct target_status { + uint32_t residual_datacnt; /* Residual in the current S/G seg */ + uint32_t residual_sgptr; /* The next S/G for this transfer */ + uint8_t scsi_status; /* SCSI status to give to initiator */ + uint8_t target_phases; /* Bitmap of phases to execute */ + uint8_t data_phase; /* Data-In or Data-Out */ + uint8_t initiator_tag; /* Initiator's transaction tag */ +}; + +/* + * Initiator mode SCB shared data area. + * If the embedded CDB is 12 bytes or less, we embed + * the sense buffer address in the SCB. This allows + * us to retrieve sense information without interupting + * the host in packetized mode. + */ +typedef uint32_t sense_addr_t; +#define MAX_CDB_LEN 16 +#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t)) +union initiator_data { + uint64_t cdbptr; + uint8_t cdb[MAX_CDB_LEN]; + struct { + uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR]; + sense_addr_t sense_addr; + } cdb_plus_saddr; +}; + +/* + * Target mode version of the shared data SCB segment. + */ +struct target_data { + uint32_t spare[2]; + uint8_t scsi_status; /* SCSI status to give to initiator */ + uint8_t target_phases; /* Bitmap of phases to execute */ + uint8_t data_phase; /* Data-In or Data-Out */ + uint8_t initiator_tag; /* Initiator's transaction tag */ +}; + +struct hardware_scb { +/*0*/ union { + union initiator_data idata; + struct target_data tdata; + struct initiator_status istatus; + struct target_status tstatus; + } shared_data; +/* + * A word about residuals. + * The scb is presented to the sequencer with the dataptr and datacnt + * fields initialized to the contents of the first S/G element to + * transfer. The sgptr field is initialized to the bus address for + * the S/G element that follows the first in the in core S/G array + * or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid + * S/G entry for this transfer (single S/G element transfer with the + * first elements address and length preloaded in the dataptr/datacnt + * fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL. + * The SG_FULL_RESID flag ensures that the residual will be correctly + * noted even if no data transfers occur. Once the data phase is entered, + * the residual sgptr and datacnt are loaded from the sgptr and the + * datacnt fields. After each S/G element's dataptr and length are + * loaded into the hardware, the residual sgptr is advanced. After + * each S/G element is expired, its datacnt field is checked to see + * if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the + * residual sg ptr and the transfer is considered complete. If the + * sequencer determines that there is a residual in the tranfer, or + * there is non-zero status, it will set the SG_STATUS_VALID flag in + * sgptr and dma the scb back into host memory. To sumarize: + * + * Sequencer: + * o A residual has occurred if SG_FULL_RESID is set in sgptr, + * or residual_sgptr does not have SG_LIST_NULL set. + * + * o We are transfering the last segment if residual_datacnt has + * the SG_LAST_SEG flag set. + * + * Host: + * o A residual can only have occurred if a completed scb has the + * SG_STATUS_VALID flag set. Inspection of the SCSI status field, + * the residual_datacnt, and the residual_sgptr field will tell + * for sure. + * + * o residual_sgptr and sgptr refer to the "next" sg entry + * and so may point beyond the last valid sg entry for the + * transfer. + */ +#define SG_PTR_MASK 0xFFFFFFF8 +/*16*/ uint16_t tag; +/*18*/ uint8_t cdb_len; +/*19*/ uint8_t task_management; +/*20*/ uint32_t next_hscb_busaddr; +/*24*/ uint64_t dataptr; +/*32*/ uint32_t datacnt; /* Byte 3 is spare. */ +/*36*/ uint32_t sgptr; +/*40*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */ +/*41*/ uint8_t scsiid; /* + * Selection out Id + * Our Id (bits 0-3) Their ID (bits 4-7) + */ +/*42*/ uint8_t lun; +/*43*/ uint8_t task_attribute; +/*44*/ uint32_t hscb_busaddr; +/******* Long lun field only downloaded for full 8 byte lun support *******/ +/*48*/ uint8_t pkt_long_lun[8]; +/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/ +/*56*/ uint8_t spare[8]; +}; + +/************************ Kernel SCB Definitions ******************************/ +/* + * Some fields of the SCB are OS dependent. Here we collect the + * definitions for elements that all OS platforms need to include + * in there SCB definition. + */ + +/* + * Definition of a scatter/gather element as transfered to the controller. + * The aic7xxx chips only support a 24bit length. We use the top byte of + * the length to store additional address bits and a flag to indicate + * that a given segment terminates the transfer. This gives us an + * addressable range of 512GB on machines with 64bit PCI or with chips + * that can support dual address cycles on 32bit PCI busses. + */ +struct ahd_dma_seg { + uint32_t addr; + uint32_t len; +#define AHD_DMA_LAST_SEG 0x80000000 +#define AHD_SG_HIGH_ADDR_MASK 0x7F000000 +#define AHD_SG_LEN_MASK 0x00FFFFFF +}; + +struct ahd_dma64_seg { + uint64_t addr; + uint32_t len; + uint32_t pad; +}; + +struct map_node { + bus_dmamap_t dmamap; + bus_addr_t physaddr; + uint8_t *vaddr; + SLIST_ENTRY(map_node) links; +}; + +/* + * The current state of this SCB. + */ +typedef enum { + SCB_FLAG_NONE = 0x00000, + SCB_TRANSMISSION_ERROR = 0x00001,/* + * We detected a parity or CRC + * error that has effected the + * payload of the command. This + * flag is checked when normal + * status is returned to catch + * the case of a target not + * responding to our attempt + * to report the error. + */ + SCB_OTHERTCL_TIMEOUT = 0x00002,/* + * Another device was active + * during the first timeout for + * this SCB so we gave ourselves + * an additional timeout period + * in case it was hogging the + * bus. + */ + SCB_DEVICE_RESET = 0x00004, + SCB_SENSE = 0x00008, + SCB_CDB32_PTR = 0x00010, + SCB_RECOVERY_SCB = 0x00020, + SCB_AUTO_NEGOTIATE = 0x00040,/* Negotiate to achieve goal. */ + SCB_NEGOTIATE = 0x00080,/* Negotiation forced for command. */ + SCB_ABORT = 0x00100, + SCB_ACTIVE = 0x00200, + SCB_TARGET_IMMEDIATE = 0x00400, + SCB_PACKETIZED = 0x00800, + SCB_EXPECT_PPR_BUSFREE = 0x01000, + SCB_PKT_SENSE = 0x02000, + SCB_CMDPHASE_ABORT = 0x04000, + SCB_ON_COL_LIST = 0x08000, + SCB_SILENT = 0x10000 /* + * Be quiet about transmission type + * errors. They are expected and we + * don't want to upset the user. This + * flag is typically used during DV. + */ +} scb_flag; + +struct scb { + struct hardware_scb *hscb; + union { + SLIST_ENTRY(scb) sle; + LIST_ENTRY(scb) le; + TAILQ_ENTRY(scb) tqe; + } links; + union { + SLIST_ENTRY(scb) sle; + LIST_ENTRY(scb) le; + TAILQ_ENTRY(scb) tqe; + } links2; +#define pending_links links2.le +#define collision_links links2.le + struct scb *col_scb; + ahd_io_ctx_t io_ctx; + struct ahd_softc *ahd_softc; + scb_flag flags; +#ifndef __linux__ + bus_dmamap_t dmamap; +#endif + struct scb_platform_data *platform_data; + struct map_node *hscb_map; + struct map_node *sg_map; + struct map_node *sense_map; + void *sg_list; + uint8_t *sense_data; + bus_addr_t sg_list_busaddr; + bus_addr_t sense_busaddr; + u_int sg_count;/* How full ahd_dma_seg is */ +#define AHD_MAX_LQ_CRC_ERRORS 5 + u_int crc_retry_count; +}; + +TAILQ_HEAD(scb_tailq, scb); +LIST_HEAD(scb_list, scb); + +struct scb_data { + /* + * TAILQ of lists of free SCBs grouped by device + * collision domains. + */ + struct scb_tailq free_scbs; + + /* + * Per-device lists of SCBs whose tag ID would collide + * with an already active tag on the device. + */ + struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT]; + + /* + * SCBs that will not collide with any active device. + */ + struct scb_list any_dev_free_scb_list; + + /* + * Mapping from tag to SCB. + */ + struct scb *scbindex[AHD_SCB_MAX]; + + /* + * "Bus" addresses of our data structures. + */ + bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */ + bus_dma_tag_t sg_dmat; /* dmat for our sg segments */ + bus_dma_tag_t sense_dmat; /* dmat for our sense buffers */ + SLIST_HEAD(, map_node) hscb_maps; + SLIST_HEAD(, map_node) sg_maps; + SLIST_HEAD(, map_node) sense_maps; + int scbs_left; /* unallocated scbs in head map_node */ + int sgs_left; /* unallocated sgs in head map_node */ + int sense_left; /* unallocated sense in head map_node */ + uint16_t numscbs; + uint16_t maxhscbs; /* Number of SCBs on the card */ + uint8_t init_level; /* + * How far we've initialized + * this structure. + */ +}; + +/************************ Target Mode Definitions *****************************/ + +/* + * Connection desciptor for select-in requests in target mode. + */ +struct target_cmd { + uint8_t scsiid; /* Our ID and the initiator's ID */ + uint8_t identify; /* Identify message */ + uint8_t bytes[22]; /* + * Bytes contains any additional message + * bytes terminated by 0xFF. The remainder + * is the cdb to execute. + */ + uint8_t cmd_valid; /* + * When a command is complete, the firmware + * will set cmd_valid to all bits set. + * After the host has seen the command, + * the bits are cleared. This allows us + * to just peek at host memory to determine + * if more work is complete. cmd_valid is on + * an 8 byte boundary to simplify setting + * it on aic7880 hardware which only has + * limited direct access to the DMA FIFO. + */ + uint8_t pad[7]; +}; + +/* + * Number of events we can buffer up if we run out + * of immediate notify ccbs. + */ +#define AHD_TMODE_EVENT_BUFFER_SIZE 8 +struct ahd_tmode_event { + uint8_t initiator_id; + uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */ +#define EVENT_TYPE_BUS_RESET 0xFF + uint8_t event_arg; +}; + +/* + * Per enabled lun target mode state. + * As this state is directly influenced by the host OS'es target mode + * environment, we let the OS module define it. Forward declare the + * structure here so we can store arrays of them, etc. in OS neutral + * data structures. + */ +#ifdef AHD_TARGET_MODE +struct ahd_tmode_lstate { + struct cam_path *path; + struct ccb_hdr_slist accept_tios; + struct ccb_hdr_slist immed_notifies; + struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE]; + uint8_t event_r_idx; + uint8_t event_w_idx; +}; +#else +struct ahd_tmode_lstate; +#endif + +/******************** Transfer Negotiation Datastructures *********************/ +#define AHD_TRANS_CUR 0x01 /* Modify current neogtiation status */ +#define AHD_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */ +#define AHD_TRANS_GOAL 0x04 /* Modify negotiation goal */ +#define AHD_TRANS_USER 0x08 /* Modify user negotiation settings */ +#define AHD_PERIOD_10MHz 0x19 + +#define AHD_WIDTH_UNKNOWN 0xFF +#define AHD_PERIOD_UNKNOWN 0xFF +#define AHD_OFFSET_UNKNOWN 0x0 +#define AHD_PPR_OPTS_UNKNOWN 0xFF + +/* + * Transfer Negotiation Information. + */ +struct ahd_transinfo { + uint8_t protocol_version; /* SCSI Revision level */ + uint8_t transport_version; /* SPI Revision level */ + uint8_t width; /* Bus width */ + uint8_t period; /* Sync rate factor */ + uint8_t offset; /* Sync offset */ + uint8_t ppr_options; /* Parallel Protocol Request options */ +}; + +/* + * Per-initiator current, goal and user transfer negotiation information. */ +struct ahd_initiator_tinfo { + struct ahd_transinfo curr; + struct ahd_transinfo goal; + struct ahd_transinfo user; +}; + +/* + * Per enabled target ID state. + * Pointers to lun target state as well as sync/wide negotiation information + * for each initiator<->target mapping. For the initiator role we pretend + * that we are the target and the targets are the initiators since the + * negotiation is the same regardless of role. + */ +struct ahd_tmode_tstate { + struct ahd_tmode_lstate* enabled_luns[AHD_NUM_LUNS]; + struct ahd_initiator_tinfo transinfo[AHD_NUM_TARGETS]; + + /* + * Per initiator state bitmasks. + */ + uint16_t auto_negotiate;/* Auto Negotiation Required */ + uint16_t discenable; /* Disconnection allowed */ + uint16_t tagenable; /* Tagged Queuing allowed */ +}; + +/* + * Points of interest along the negotiated transfer scale. + */ +#define AHD_SYNCRATE_160 0x8 +#define AHD_SYNCRATE_PACED 0x8 +#define AHD_SYNCRATE_DT 0x9 +#define AHD_SYNCRATE_ULTRA2 0xa +#define AHD_SYNCRATE_ULTRA 0xc +#define AHD_SYNCRATE_FAST 0x19 +#define AHD_SYNCRATE_MIN_DT AHD_SYNCRATE_FAST +#define AHD_SYNCRATE_SYNC 0x32 +#define AHD_SYNCRATE_MIN 0x60 +#define AHD_SYNCRATE_ASYNC 0xFF +#define AHD_SYNCRATE_MAX AHD_SYNCRATE_160 + +/* Safe and valid period for async negotiations. */ +#define AHD_ASYNC_XFER_PERIOD 0x44 + +/* + * In RevA, the synctable uses a 120MHz rate for the period + * factor 8 and 160MHz for the period factor 7. The 120MHz + * rate never made it into the official SCSI spec, so we must + * compensate when setting the negotiation table for Rev A + * parts. + */ +#define AHD_SYNCRATE_REVA_120 0x8 +#define AHD_SYNCRATE_REVA_160 0x7 + +/***************************** Lookup Tables **********************************/ +/* + * Phase -> name and message out response + * to parity errors in each phase table. + */ +struct ahd_phase_table_entry { + uint8_t phase; + uint8_t mesg_out; /* Message response to parity errors */ + char *phasemsg; +}; + +/************************** Serial EEPROM Format ******************************/ + +struct seeprom_config { +/* + * Per SCSI ID Configuration Flags + */ + uint16_t device_flags[16]; /* words 0-15 */ +#define CFXFER 0x003F /* synchronous transfer rate */ +#define CFXFER_ASYNC 0x3F +#define CFQAS 0x0040 /* Negotiate QAS */ +#define CFPACKETIZED 0x0080 /* Negotiate Packetized Transfers */ +#define CFSTART 0x0100 /* send start unit SCSI command */ +#define CFINCBIOS 0x0200 /* include in BIOS scan */ +#define CFDISC 0x0400 /* enable disconnection */ +#define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */ +#define CFWIDEB 0x1000 /* wide bus device */ +#define CFHOSTMANAGED 0x8000 /* Managed by a RAID controller */ + +/* + * BIOS Control Bits + */ + uint16_t bios_control; /* word 16 */ +#define CFSUPREM 0x0001 /* support all removeable drives */ +#define CFSUPREMB 0x0002 /* support removeable boot drives */ +#define CFBIOSSTATE 0x000C /* BIOS Action State */ +#define CFBS_DISABLED 0x00 +#define CFBS_ENABLED 0x04 +#define CFBS_DISABLED_SCAN 0x08 +#define CFENABLEDV 0x0010 /* Perform Domain Validation */ +#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */ +#define CFSPARITY 0x0040 /* SCSI parity */ +#define CFEXTEND 0x0080 /* extended translation enabled */ +#define CFBOOTCD 0x0100 /* Support Bootable CD-ROM */ +#define CFMSG_LEVEL 0x0600 /* BIOS Message Level */ +#define CFMSG_VERBOSE 0x0000 +#define CFMSG_SILENT 0x0200 +#define CFMSG_DIAG 0x0400 +#define CFRESETB 0x0800 /* reset SCSI bus at boot */ +/* UNUSED 0xf000 */ + +/* + * Host Adapter Control Bits + */ + uint16_t adapter_control; /* word 17 */ +#define CFAUTOTERM 0x0001 /* Perform Auto termination */ +#define CFSTERM 0x0002 /* SCSI low byte termination */ +#define CFWSTERM 0x0004 /* SCSI high byte termination */ +#define CFSEAUTOTERM 0x0008 /* Ultra2 Perform secondary Auto Term*/ +#define CFSELOWTERM 0x0010 /* Ultra2 secondary low term */ +#define CFSEHIGHTERM 0x0020 /* Ultra2 secondary high term */ +#define CFSTPWLEVEL 0x0040 /* Termination level control */ +#define CFBIOSAUTOTERM 0x0080 /* Perform Auto termination */ +#define CFTERM_MENU 0x0100 /* BIOS displays termination menu */ +#define CFCLUSTERENB 0x8000 /* Cluster Enable */ + +/* + * Bus Release Time, Host Adapter ID + */ + uint16_t brtime_id; /* word 18 */ +#define CFSCSIID 0x000f /* host adapter SCSI ID */ +/* UNUSED 0x00f0 */ +#define CFBRTIME 0xff00 /* bus release time/PCI Latency Time */ + +/* + * Maximum targets + */ + uint16_t max_targets; /* word 19 */ +#define CFMAXTARG 0x00ff /* maximum targets */ +#define CFBOOTLUN 0x0f00 /* Lun to boot from */ +#define CFBOOTID 0xf000 /* Target to boot from */ + uint16_t res_1[10]; /* words 20-29 */ + uint16_t signature; /* BIOS Signature */ +#define CFSIGNATURE 0x400 + uint16_t checksum; /* word 31 */ +}; + +/****************************** Flexport Logic ********************************/ +#define FLXADDR_TERMCTL 0x0 +#define FLX_TERMCTL_ENSECHIGH 0x8 +#define FLX_TERMCTL_ENSECLOW 0x4 +#define FLX_TERMCTL_ENPRIHIGH 0x2 +#define FLX_TERMCTL_ENPRILOW 0x1 +#define FLXADDR_ROMSTAT_CURSENSECTL 0x1 +#define FLX_ROMSTAT_SEECFG 0xF0 +#define FLX_ROMSTAT_EECFG 0x0F +#define FLX_ROMSTAT_SEE_93C66 0x00 +#define FLX_ROMSTAT_SEE_NONE 0xF0 +#define FLX_ROMSTAT_EE_512x8 0x0 +#define FLX_ROMSTAT_EE_1MBx8 0x1 +#define FLX_ROMSTAT_EE_2MBx8 0x2 +#define FLX_ROMSTAT_EE_4MBx8 0x3 +#define FLX_ROMSTAT_EE_16MBx8 0x4 +#define CURSENSE_ENB 0x1 +#define FLXADDR_FLEXSTAT 0x2 +#define FLX_FSTAT_BUSY 0x1 +#define FLXADDR_CURRENT_STAT 0x4 +#define FLX_CSTAT_SEC_HIGH 0xC0 +#define FLX_CSTAT_SEC_LOW 0x30 +#define FLX_CSTAT_PRI_HIGH 0x0C +#define FLX_CSTAT_PRI_LOW 0x03 +#define FLX_CSTAT_MASK 0x03 +#define FLX_CSTAT_SHIFT 2 +#define FLX_CSTAT_OKAY 0x0 +#define FLX_CSTAT_OVER 0x1 +#define FLX_CSTAT_UNDER 0x2 +#define FLX_CSTAT_INVALID 0x3 + +int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count); + +int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count); +int ahd_wait_seeprom(struct ahd_softc *ahd); +int ahd_verify_cksum(struct seeprom_config *sc); +int ahd_acquire_seeprom(struct ahd_softc *ahd); +void ahd_release_seeprom(struct ahd_softc *ahd); + +/**************************** Message Buffer *********************************/ +typedef enum { + MSG_FLAG_NONE = 0x00, + MSG_FLAG_EXPECT_PPR_BUSFREE = 0x01, + MSG_FLAG_IU_REQ_CHANGED = 0x02, + MSG_FLAG_EXPECT_IDE_BUSFREE = 0x04, + MSG_FLAG_EXPECT_QASREJ_BUSFREE = 0x08, + MSG_FLAG_PACKETIZED = 0x10 +} ahd_msg_flags; + +typedef enum { + MSG_TYPE_NONE = 0x00, + MSG_TYPE_INITIATOR_MSGOUT = 0x01, + MSG_TYPE_INITIATOR_MSGIN = 0x02, + MSG_TYPE_TARGET_MSGOUT = 0x03, + MSG_TYPE_TARGET_MSGIN = 0x04 +} ahd_msg_type; + +typedef enum { + MSGLOOP_IN_PROG, + MSGLOOP_MSGCOMPLETE, + MSGLOOP_TERMINATED +} msg_loop_stat; + +/*********************** Software Configuration Structure *********************/ +struct ahd_suspend_channel_state { + uint8_t scsiseq; + uint8_t sxfrctl0; + uint8_t sxfrctl1; + uint8_t simode0; + uint8_t simode1; + uint8_t seltimer; + uint8_t seqctl; +}; + +struct ahd_suspend_state { + struct ahd_suspend_channel_state channel[2]; + uint8_t optionmode; + uint8_t dscommand0; + uint8_t dspcistatus; + /* hsmailbox */ + uint8_t crccontrol1; + uint8_t scbbaddr; + /* Host and sequencer SCB counts */ + uint8_t dff_thrsh; + uint8_t *scratch_ram; + uint8_t *btt; +}; + +typedef void (*ahd_bus_intr_t)(struct ahd_softc *); + +typedef enum { + AHD_MODE_DFF0, + AHD_MODE_DFF1, + AHD_MODE_CCHAN, + AHD_MODE_SCSI, + AHD_MODE_CFG, + AHD_MODE_UNKNOWN +} ahd_mode; + +#define AHD_MK_MSK(x) (0x01 << (x)) +#define AHD_MODE_DFF0_MSK AHD_MK_MSK(AHD_MODE_DFF0) +#define AHD_MODE_DFF1_MSK AHD_MK_MSK(AHD_MODE_DFF1) +#define AHD_MODE_CCHAN_MSK AHD_MK_MSK(AHD_MODE_CCHAN) +#define AHD_MODE_SCSI_MSK AHD_MK_MSK(AHD_MODE_SCSI) +#define AHD_MODE_CFG_MSK AHD_MK_MSK(AHD_MODE_CFG) +#define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN) +#define AHD_MODE_ANY_MSK (~0) + +typedef uint8_t ahd_mode_state; + +typedef void ahd_callback_t (void *); + +struct ahd_softc { + bus_space_tag_t tags[2]; + bus_space_handle_t bshs[2]; +#ifndef __linux__ + bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ +#endif + struct scb_data scb_data; + + struct hardware_scb *next_queued_hscb; + + /* + * SCBs that have been sent to the controller + */ + LIST_HEAD(, scb) pending_scbs; + + /* + * Current register window mode information. + */ + ahd_mode dst_mode; + ahd_mode src_mode; + + /* + * Saved register window mode information + * used for restore on next unpause. + */ + ahd_mode saved_dst_mode; + ahd_mode saved_src_mode; + + /* + * Platform specific data. + */ + struct ahd_platform_data *platform_data; + + /* + * Platform specific device information. + */ + ahd_dev_softc_t dev_softc; + + /* + * Bus specific device information. + */ + ahd_bus_intr_t bus_intr; + + /* + * Target mode related state kept on a per enabled lun basis. + * Targets that are not enabled will have null entries. + * As an initiator, we keep one target entry for our initiator + * ID to store our sync/wide transfer settings. + */ + struct ahd_tmode_tstate *enabled_targets[AHD_NUM_TARGETS]; + + /* + * The black hole device responsible for handling requests for + * disabled luns on enabled targets. + */ + struct ahd_tmode_lstate *black_hole; + + /* + * Device instance currently on the bus awaiting a continue TIO + * for a command that was not given the disconnect priveledge. + */ + struct ahd_tmode_lstate *pending_device; + + /* + * Timer handles for timer driven callbacks. + */ + ahd_timer_t reset_timer; + ahd_timer_t stat_timer; + + /* + * Statistics. + */ +#define AHD_STAT_UPDATE_US 250000 /* 250ms */ +#define AHD_STAT_BUCKETS 4 + u_int cmdcmplt_bucket; + uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS]; + uint32_t cmdcmplt_total; + + /* + * Card characteristics + */ + ahd_chip chip; + ahd_feature features; + ahd_bug bugs; + ahd_flag flags; + struct seeprom_config *seep_config; + + /* Values to store in the SEQCTL register for pause and unpause */ + uint8_t unpause; + uint8_t pause; + + /* Command Queues */ + uint16_t qoutfifonext; + uint16_t qoutfifonext_valid_tag; + uint16_t qinfifonext; + uint16_t qinfifo[AHD_SCB_MAX]; + uint16_t *qoutfifo; + + /* Critical Section Data */ + struct cs *critical_sections; + u_int num_critical_sections; + + /* Buffer for handling packetized bitbucket. */ + uint8_t *overrun_buf; + + /* Links for chaining softcs */ + TAILQ_ENTRY(ahd_softc) links; + + /* Channel Names ('A', 'B', etc.) */ + char channel; + + /* Initiator Bus ID */ + uint8_t our_id; + + /* + * Target incoming command FIFO. + */ + struct target_cmd *targetcmds; + uint8_t tqinfifonext; + + /* + * Cached verson of the hs_mailbox so we can avoid + * pausing the sequencer during mailbox updates. + */ + uint8_t hs_mailbox; + + /* + * Incoming and outgoing message handling. + */ + uint8_t send_msg_perror; + ahd_msg_flags msg_flags; + ahd_msg_type msg_type; + uint8_t msgout_buf[12];/* Message we are sending */ + uint8_t msgin_buf[12];/* Message we are receiving */ + u_int msgout_len; /* Length of message to send */ + u_int msgout_index; /* Current index in msgout */ + u_int msgin_index; /* Current index in msgin */ + + /* + * Mapping information for data structures shared + * between the sequencer and kernel. + */ + bus_dma_tag_t parent_dmat; + bus_dma_tag_t shared_data_dmat; + bus_dmamap_t shared_data_dmamap; + bus_addr_t shared_data_busaddr; + + /* Information saved through suspend/resume cycles */ + struct ahd_suspend_state suspend_state; + + /* Number of enabled target mode device on this card */ + u_int enabled_luns; + + /* Initialization level of this data structure */ + u_int init_level; + + /* PCI cacheline size. */ + u_int pci_cachesize; + + /* IO Cell Parameters */ + uint8_t iocell_opts[AHD_NUM_PER_DEV_ANNEXCOLS]; + + u_int stack_size; + uint16_t *saved_stack; + + /* Per-Unit descriptive information */ + const char *description; + const char *bus_description; + char *name; + int unit; + + /* Selection Timer settings */ + int seltime; + + /* + * Interrupt coalessing settings. + */ +#define AHD_INT_COALESSING_TIMER_DEFAULT 250 /*us*/ +#define AHD_INT_COALESSING_MAXCMDS_DEFAULT 10 +#define AHD_INT_COALESSING_MAXCMDS_MAX 127 +#define AHD_INT_COALESSING_MINCMDS_DEFAULT 5 +#define AHD_INT_COALESSING_MINCMDS_MAX 127 +#define AHD_INT_COALESSING_THRESHOLD_DEFAULT 2000 +#define AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT 1000 + u_int int_coalessing_timer; + u_int int_coalessing_maxcmds; + u_int int_coalessing_mincmds; + u_int int_coalessing_threshold; + u_int int_coalessing_stop_threshold; + + uint16_t user_discenable;/* Disconnection allowed */ + uint16_t user_tagenable;/* Tagged Queuing allowed */ +}; + +TAILQ_HEAD(ahd_softc_tailq, ahd_softc); +extern struct ahd_softc_tailq ahd_tailq; + +/*************************** IO Cell Configuration ****************************/ +#define AHD_PRECOMP_SLEW_INDEX \ + (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0) + +#define AHD_AMPLITUDE_INDEX \ + (AHD_ANNEXCOL_AMPLITUDE - AHD_ANNEXCOL_PER_DEV0) + +#define AHD_SET_SLEWRATE(ahd, new_slew) \ +do { \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_SLEWRATE_MASK; \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ + (((new_slew) << AHD_SLEWRATE_SHIFT) & AHD_SLEWRATE_MASK); \ +} while (0) + +#define AHD_SET_PRECOMP(ahd, new_pcomp) \ +do { \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ + (((new_pcomp) << AHD_PRECOMP_SHIFT) & AHD_PRECOMP_MASK); \ +} while (0) + +#define AHD_SET_AMPLITUDE(ahd, new_amp) \ +do { \ + (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] &= ~AHD_AMPLITUDE_MASK; \ + (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] |= \ + (((new_amp) << AHD_AMPLITUDE_SHIFT) & AHD_AMPLITUDE_MASK); \ +} while (0) + +/************************ Active Device Information ***************************/ +typedef enum { + ROLE_UNKNOWN, + ROLE_INITIATOR, + ROLE_TARGET +} role_t; + +struct ahd_devinfo { + int our_scsiid; + int target_offset; + uint16_t target_mask; + u_int target; + u_int lun; + char channel; + role_t role; /* + * Only guaranteed to be correct if not + * in the busfree state. + */ +}; + +/****************************** PCI Structures ********************************/ +#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/ +#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */ +#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */ + +typedef int (ahd_device_setup_t)(struct ahd_softc *); + +struct ahd_pci_identity { + uint64_t full_id; + uint64_t id_mask; + char *name; + ahd_device_setup_t *setup; +}; +extern struct ahd_pci_identity ahd_pci_ident_table []; +extern const u_int ahd_num_pci_devs; + +/***************************** VL/EISA Declarations ***************************/ +struct aic7770_identity { + uint32_t full_id; + uint32_t id_mask; + char *name; + ahd_device_setup_t *setup; +}; +extern struct aic7770_identity aic7770_ident_table []; +extern const int ahd_num_aic7770_devs; + +#define AHD_EISA_SLOT_OFFSET 0xc00 +#define AHD_EISA_IOSIZE 0x100 + +/*************************** Function Declarations ****************************/ +/******************************************************************************/ +void ahd_reset_cmds_pending(struct ahd_softc *ahd); +u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); +void ahd_busy_tcl(struct ahd_softc *ahd, + u_int tcl, u_int busyid); +static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); +static __inline void +ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) +{ + ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); +} + +/***************************** PCI Front End *********************************/ +struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); +int ahd_pci_config(struct ahd_softc *, + struct ahd_pci_identity *); +int ahd_pci_test_register_access(struct ahd_softc *); + +/************************** SCB and SCB queue management **********************/ +int ahd_probe_scbs(struct ahd_softc *); +void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, + struct scb *scb); +int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, + int target, char channel, int lun, + u_int tag, role_t role); + +/****************************** Initialization ********************************/ +struct ahd_softc *ahd_alloc(void *platform_arg, char *name); +int ahd_softc_init(struct ahd_softc *); +void ahd_controller_info(struct ahd_softc *ahd, char *buf); +int ahd_init(struct ahd_softc *ahd); +int ahd_default_config(struct ahd_softc *ahd); +int ahd_parse_cfgdata(struct ahd_softc *ahd, + struct seeprom_config *sc); +void ahd_intr_enable(struct ahd_softc *ahd, int enable); +void ahd_update_coalessing_values(struct ahd_softc *ahd, + u_int timer, + u_int maxcmds, + u_int mincmds); +void ahd_enable_coalessing(struct ahd_softc *ahd, + int enable); +void ahd_pause_and_flushwork(struct ahd_softc *ahd); +int ahd_suspend(struct ahd_softc *ahd); +int ahd_resume(struct ahd_softc *ahd); +void ahd_softc_insert(struct ahd_softc *); +struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd); +void ahd_set_unit(struct ahd_softc *, int); +void ahd_set_name(struct ahd_softc *, char *); +struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); +void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); +void ahd_alloc_scbs(struct ahd_softc *ahd); +void ahd_free(struct ahd_softc *ahd); +int ahd_reset(struct ahd_softc *ahd); +void ahd_shutdown(void *arg); +int ahd_write_flexport(struct ahd_softc *ahd, + u_int addr, u_int value); +int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, + uint8_t *value); +int ahd_wait_flexport(struct ahd_softc *ahd); + +/*************************** Interrupt Services *******************************/ +void ahd_pci_intr(struct ahd_softc *ahd); +void ahd_clear_intstat(struct ahd_softc *ahd); +void ahd_flush_qoutfifo(struct ahd_softc *ahd); +void ahd_run_qoutfifo(struct ahd_softc *ahd); +#ifdef AHD_TARGET_MODE +void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); +#endif +void ahd_handle_hwerrint(struct ahd_softc *ahd); +void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); +void ahd_handle_scsiint(struct ahd_softc *ahd, + u_int intstat); +void ahd_clear_critical_section(struct ahd_softc *ahd); + +/***************************** Error Recovery *********************************/ +typedef enum { + SEARCH_COMPLETE, + SEARCH_COUNT, + SEARCH_REMOVE, + SEARCH_PRINT +} ahd_search_action; +int ahd_search_qinfifo(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status, + ahd_search_action action); +int ahd_search_disc_list(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + int stop_on_first, int remove, + int save_state); +void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); +int ahd_reset_channel(struct ahd_softc *ahd, char channel, + int initiate_reset); +int ahd_abort_scbs(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status); +void ahd_restart(struct ahd_softc *ahd); +void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); +void ahd_handle_scb_status(struct ahd_softc *ahd, + struct scb *scb); +void ahd_handle_scsi_status(struct ahd_softc *ahd, + struct scb *scb); +void ahd_calc_residual(struct ahd_softc *ahd, + struct scb *scb); +/*************************** Utility Functions ********************************/ +struct ahd_phase_table_entry* + ahd_lookup_phase_entry(int phase); +void ahd_compile_devinfo(struct ahd_devinfo *devinfo, + u_int our_id, u_int target, + u_int lun, char channel, + role_t role); +/************************** Transfer Negotiation ******************************/ +void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, + u_int *ppr_options, u_int maxsync); +void ahd_validate_offset(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int period, u_int *offset, + int wide, role_t role); +void ahd_validate_width(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int *bus_width, + role_t role); +/* + * Negotiation types. These are used to qualify if we should renegotiate + * even if our goal and current transport parameters are identical. + */ +typedef enum { + AHD_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */ + AHD_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */ + AHD_NEG_ALWAYS /* Renegotiat even if goal is async. */ +} ahd_neg_type; +int ahd_update_neg_request(struct ahd_softc*, + struct ahd_devinfo*, + struct ahd_tmode_tstate*, + struct ahd_initiator_tinfo*, + ahd_neg_type); +void ahd_set_width(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int width, u_int type, int paused); +void ahd_set_syncrate(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int period, u_int offset, + u_int ppr_options, + u_int type, int paused); +typedef enum { + AHD_QUEUE_NONE, + AHD_QUEUE_BASIC, + AHD_QUEUE_TAGGED +} ahd_queue_alg; + +void ahd_set_tags(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + ahd_queue_alg alg); + +/**************************** Target Mode *************************************/ +#ifdef AHD_TARGET_MODE +void ahd_send_lstate_events(struct ahd_softc *, + struct ahd_tmode_lstate *); +void ahd_handle_en_lun(struct ahd_softc *ahd, + struct cam_sim *sim, union ccb *ccb); +cam_status ahd_find_tmode_devs(struct ahd_softc *ahd, + struct cam_sim *sim, union ccb *ccb, + struct ahd_tmode_tstate **tstate, + struct ahd_tmode_lstate **lstate, + int notfound_failure); +#ifndef AHD_TMODE_ENABLE +#define AHD_TMODE_ENABLE 0 +#endif +#endif +/******************************* Debug ***************************************/ +#ifdef AHD_DEBUG +extern uint32_t ahd_debug; +#define AHD_SHOW_MISC 0x00001 +#define AHD_SHOW_SENSE 0x00002 +#define AHD_SHOW_RECOVERY 0x00004 +#define AHD_DUMP_SEEPROM 0x00008 +#define AHD_SHOW_TERMCTL 0x00010 +#define AHD_SHOW_MEMORY 0x00020 +#define AHD_SHOW_MESSAGES 0x00040 +#define AHD_SHOW_MODEPTR 0x00080 +#define AHD_SHOW_SELTO 0x00100 +#define AHD_SHOW_FIFOS 0x00200 +#define AHD_SHOW_QFULL 0x00400 +#define AHD_SHOW_DV 0x00800 +#define AHD_SHOW_MASKED_ERRORS 0x01000 +#define AHD_SHOW_QUEUE 0x02000 +#define AHD_SHOW_TQIN 0x04000 +#define AHD_SHOW_SG 0x08000 +#define AHD_SHOW_INT_COALESSING 0x10000 +#define AHD_DEBUG_SEQUENCER 0x20000 +#endif +void ahd_print_scb(struct scb *scb); +void ahd_print_devinfo(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +void ahd_dump_sglist(struct scb *scb); +void ahd_dump_all_cards_state(void); +void ahd_dump_card_state(struct ahd_softc *ahd); +int ahd_print_register(ahd_reg_parse_entry_t *table, + u_int num_entries, + const char *name, + u_int address, + u_int value, + u_int *cur_column, + u_int wrap_point); +void ahd_dump_scbs(struct ahd_softc *ahd); +#endif /* _AIC79XX_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_inline.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_inline.h --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_inline.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_inline.h 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,950 @@ +/* + * Inline routines shareable across OS platforms. + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 $ + * + * $FreeBSD$ + */ + +#ifndef _AIC79XX_INLINE_H_ +#define _AIC79XX_INLINE_H_ + +/******************************** Debugging ***********************************/ +static __inline char *ahd_name(struct ahd_softc *ahd); + +static __inline char * +ahd_name(struct ahd_softc *ahd) +{ + return (ahd->name); +} + +/************************ Sequencer Execution Control *************************/ +static __inline void ahd_known_modes(struct ahd_softc *ahd, + ahd_mode src, ahd_mode dst); +static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd, + ahd_mode src, + ahd_mode dst); +static __inline void ahd_extract_mode_state(struct ahd_softc *ahd, + ahd_mode_state state, + ahd_mode *src, ahd_mode *dst); +static __inline void ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, + ahd_mode dst); +static __inline void ahd_update_modes(struct ahd_softc *ahd); +static __inline void ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, + ahd_mode dstmode, const char *file, + int line); +static __inline ahd_mode_state ahd_save_modes(struct ahd_softc *ahd); +static __inline void ahd_restore_modes(struct ahd_softc *ahd, + ahd_mode_state state); +static __inline int ahd_is_paused(struct ahd_softc *ahd); +static __inline void ahd_pause(struct ahd_softc *ahd); +static __inline void ahd_unpause(struct ahd_softc *ahd); + +static __inline void +ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) +{ + ahd->src_mode = src; + ahd->dst_mode = dst; + ahd->saved_src_mode = src; + ahd->saved_dst_mode = dst; +} + +static __inline ahd_mode_state +ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) +{ + return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT)); +} + +static __inline void +ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state, + ahd_mode *src, ahd_mode *dst) +{ + *src = (state & SRC_MODE) >> SRC_MODE_SHIFT; + *dst = (state & DST_MODE) >> DST_MODE_SHIFT; +} + +static __inline void +ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) +{ + if (ahd->src_mode == src && ahd->dst_mode == dst) + return; +#ifdef AHD_DEBUG + if (ahd->src_mode == AHD_MODE_UNKNOWN + || ahd->dst_mode == AHD_MODE_UNKNOWN) + panic("Setting mode prior to saving it.\n"); + if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) + printf("%s: Setting mode 0x%x\n", ahd_name(ahd), + ahd_build_mode_state(ahd, src, dst)); +#endif + ahd_outb(ahd, MODE_PTR, ahd_build_mode_state(ahd, src, dst)); + ahd->src_mode = src; + ahd->dst_mode = dst; +} + +static __inline void +ahd_update_modes(struct ahd_softc *ahd) +{ + ahd_mode_state mode_ptr; + ahd_mode src; + ahd_mode dst; + + mode_ptr = ahd_inb(ahd, MODE_PTR); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) + printf("Reading mode 0x%x\n", mode_ptr); +#endif + ahd_extract_mode_state(ahd, mode_ptr, &src, &dst); + ahd_known_modes(ahd, src, dst); +} + +static __inline void +ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, + ahd_mode dstmode, const char *file, int line) +{ +#ifdef AHD_DEBUG + if ((srcmode & AHD_MK_MSK(ahd->src_mode)) == 0 + || (dstmode & AHD_MK_MSK(ahd->dst_mode)) == 0) { + panic("%s:%s:%d: Mode assertion failed.\n", + ahd_name(ahd), file, line); + } +#endif +} + +static __inline ahd_mode_state +ahd_save_modes(struct ahd_softc *ahd) +{ + if (ahd->src_mode == AHD_MODE_UNKNOWN + || ahd->dst_mode == AHD_MODE_UNKNOWN) + ahd_update_modes(ahd); + + return (ahd_build_mode_state(ahd, ahd->src_mode, ahd->dst_mode)); +} + +static __inline void +ahd_restore_modes(struct ahd_softc *ahd, ahd_mode_state state) +{ + ahd_mode src; + ahd_mode dst; + + ahd_extract_mode_state(ahd, state, &src, &dst); + ahd_set_modes(ahd, src, dst); +} + +#define AHD_ASSERT_MODES(ahd, source, dest) \ + ahd_assert_modes(ahd, source, dest, __FILE__, __LINE__); + +/* + * Determine whether the sequencer has halted code execution. + * Returns non-zero status if the sequencer is stopped. + */ +static __inline int +ahd_is_paused(struct ahd_softc *ahd) +{ + return ((ahd_inb(ahd, HCNTRL) & PAUSE) != 0); +} + +/* + * Request that the sequencer stop and wait, indefinitely, for it + * to stop. The sequencer will only acknowledge that it is paused + * once it has reached an instruction boundary and PAUSEDIS is + * cleared in the SEQCTL register. The sequencer may use PAUSEDIS + * for critical sections. + */ +static __inline void +ahd_pause(struct ahd_softc *ahd) +{ + ahd_outb(ahd, HCNTRL, ahd->pause); + + /* + * Since the sequencer can disable pausing in a critical section, we + * must loop until it actually stops. + */ + while (ahd_is_paused(ahd) == 0) + ; +} + +/* + * Allow the sequencer to continue program execution. + * We check here to ensure that no additional interrupt + * sources that would cause the sequencer to halt have been + * asserted. If, for example, a SCSI bus reset is detected + * while we are fielding a different, pausing, interrupt type, + * we don't want to release the sequencer before going back + * into our interrupt handler and dealing with this new + * condition. + */ +static __inline void +ahd_unpause(struct ahd_softc *ahd) +{ + /* + * Automatically restore our modes to those saved + * prior to the first change of the mode. + */ + if (ahd->saved_src_mode != AHD_MODE_UNKNOWN + && ahd->saved_dst_mode != AHD_MODE_UNKNOWN) { + if ((ahd->flags & AHD_UPDATE_PEND_CMDS) != 0) + ahd_reset_cmds_pending(ahd); + ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); + } + + if ((ahd_inb(ahd, INTSTAT) & ~(SWTMINT | CMDCMPLT)) == 0) + ahd_outb(ahd, HCNTRL, ahd->unpause); + + ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN); +} + +/*********************** Scatter Gather List Handling *************************/ +static __inline void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, + void *sgptr, bus_addr_t addr, + bus_size_t len, int last); +static __inline void ahd_setup_scb_common(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_setup_data_scb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_setup_noxfer_scb(struct ahd_softc *ahd, + struct scb *scb); + +static __inline void * +ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, + void *sgptr, bus_addr_t addr, bus_size_t len, int last) +{ + scb->sg_count++; + if (sizeof(bus_addr_t) > 4 + && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = (struct ahd_dma64_seg *)sgptr; + sg->addr = ahd_htole64(addr); + sg->len = ahd_htole32(len | (last ? AHD_DMA_LAST_SEG : 0)); + return (sg + 1); + } else { + struct ahd_dma_seg *sg; + + sg = (struct ahd_dma_seg *)sgptr; + sg->addr = ahd_htole32(addr & 0xFFFFFFFF); + sg->len = ahd_htole32(len | ((addr >> 8) & 0x7F000000) + | (last ? AHD_DMA_LAST_SEG : 0)); + return (sg + 1); + } +} + +static __inline void +ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb) +{ + /* XXX Handle target mode SCBs. */ + scb->crc_retry_count = 0; + if ((scb->flags & SCB_PACKETIZED) != 0) { + /* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */ + scb->hscb->task_attribute= scb->hscb->control & SCB_TAG_TYPE; + /* + * For Rev A short lun workaround. + */ + scb->hscb->pkt_long_lun[6] = scb->hscb->lun; + } + + if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR + || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0) + scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr = + ahd_htole32(scb->sense_busaddr); +} + +static __inline void +ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb) +{ + /* + * Copy the first SG into the "current" data ponter area. + */ + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = (struct ahd_dma64_seg *)scb->sg_list; + scb->hscb->dataptr = sg->addr; + scb->hscb->datacnt = sg->len; + } else { + struct ahd_dma_seg *sg; + + sg = (struct ahd_dma_seg *)scb->sg_list; + scb->hscb->dataptr = sg->addr; + if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { + uint64_t high_addr; + + high_addr = ahd_le32toh(sg->len) & 0x7F000000; + scb->hscb->dataptr |= ahd_htole64(high_addr << 8); + } + scb->hscb->datacnt = sg->len; + } + /* + * Note where to find the SG entries in bus space. + * We also set the full residual flag which the + * sequencer will clear as soon as a data transfer + * occurs. + */ + scb->hscb->sgptr = ahd_htole32(scb->sg_list_busaddr|SG_FULL_RESID); +} + +static __inline void +ahd_setup_noxfer_scb(struct ahd_softc *ahd, struct scb *scb) +{ + scb->hscb->sgptr = ahd_htole32(SG_LIST_NULL); + scb->hscb->dataptr = 0; + scb->hscb->datacnt = 0; +} + +/************************** Memory mapping routines ***************************/ +static __inline size_t ahd_sg_size(struct ahd_softc *ahd); +static __inline void * + ahd_sg_bus_to_virt(struct ahd_softc *ahd, + struct scb *scb, + uint32_t sg_busaddr); +static __inline uint32_t + ahd_sg_virt_to_bus(struct ahd_softc *ahd, + struct scb *scb, + void *sg); +static __inline void ahd_sync_scb(struct ahd_softc *ahd, + struct scb *scb, int op); +static __inline void ahd_sync_sglist(struct ahd_softc *ahd, + struct scb *scb, int op); +static __inline void ahd_sync_sense(struct ahd_softc *ahd, + struct scb *scb, int op); +static __inline uint32_t + ahd_targetcmd_offset(struct ahd_softc *ahd, + u_int index); + +static __inline size_t +ahd_sg_size(struct ahd_softc *ahd) +{ + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + return (sizeof(struct ahd_dma64_seg)); + return (sizeof(struct ahd_dma_seg)); +} + +static __inline void * +ahd_sg_bus_to_virt(struct ahd_softc *ahd, struct scb *scb, uint32_t sg_busaddr) +{ + bus_addr_t sg_offset; + + /* sg_list_phys points to entry 1, not 0 */ + sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd)); + return ((uint8_t *)scb->sg_list + sg_offset); +} + +static __inline uint32_t +ahd_sg_virt_to_bus(struct ahd_softc *ahd, struct scb *scb, void *sg) +{ + bus_addr_t sg_offset; + + /* sg_list_phys points to entry 1, not 0 */ + sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list) + - ahd_sg_size(ahd); + + return (scb->sg_list_busaddr + sg_offset); +} + +static __inline void +ahd_sync_scb(struct ahd_softc *ahd, struct scb *scb, int op) +{ + ahd_dmamap_sync(ahd, ahd->scb_data.hscb_dmat, + scb->hscb_map->dmamap, + /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr, + /*len*/sizeof(*scb->hscb), op); +} + +static __inline void +ahd_sync_sglist(struct ahd_softc *ahd, struct scb *scb, int op) +{ + if (scb->sg_count == 0) + return; + + ahd_dmamap_sync(ahd, ahd->scb_data.sg_dmat, + scb->sg_map->dmamap, + /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd), + /*len*/ahd_sg_size(ahd) * scb->sg_count, op); +} + +static __inline void +ahd_sync_sense(struct ahd_softc *ahd, struct scb *scb, int op) +{ + ahd_dmamap_sync(ahd, ahd->scb_data.sense_dmat, + scb->sense_map->dmamap, + /*offset*/scb->sense_busaddr, + /*len*/AHD_SENSE_BUFSIZE, op); +} + +static __inline uint32_t +ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) +{ + return (((uint8_t *)&ahd->targetcmds[index]) + - (uint8_t *)ahd->qoutfifo); +} + +/*********************** Miscelaneous Support Functions ***********************/ +static __inline void ahd_complete_scb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_update_residual(struct ahd_softc *ahd, + struct scb *scb); +static __inline struct ahd_initiator_tinfo * + ahd_fetch_transinfo(struct ahd_softc *ahd, + char channel, u_int our_id, + u_int remote_id, + struct ahd_tmode_tstate **tstate); +static __inline uint16_t + ahd_inw(struct ahd_softc *ahd, u_int port); +static __inline void ahd_outw(struct ahd_softc *ahd, u_int port, + u_int value); +static __inline uint32_t + ahd_inl(struct ahd_softc *ahd, u_int port); +static __inline void ahd_outl(struct ahd_softc *ahd, u_int port, + uint32_t value); +static __inline uint64_t + ahd_inq(struct ahd_softc *ahd, u_int port); +static __inline void ahd_outq(struct ahd_softc *ahd, u_int port, + uint64_t value); +static __inline u_int ahd_get_scbptr(struct ahd_softc *ahd); +static __inline void ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr); +static __inline u_int ahd_get_hnscb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_hescb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_snscb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_sescb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_sdscb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset); +static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset); +static __inline uint32_t + ahd_inl_scbram(struct ahd_softc *ahd, u_int offset); +static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb); +static __inline uint8_t * + ahd_get_sense_buf(struct ahd_softc *ahd, + struct scb *scb); +static __inline uint32_t + ahd_get_sense_bufaddr(struct ahd_softc *ahd, + struct scb *scb); + +static __inline void +ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_handle_scb_status(ahd, scb); + else + ahd_done(ahd, scb); +} + +/* + * Determine whether the sequencer reported a residual + * for this SCB/transaction. + */ +static __inline void +ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_calc_residual(ahd, scb); +} + +/* + * Return pointers to the transfer negotiation information + * for the specified our_id/remote_id pair. + */ +static __inline struct ahd_initiator_tinfo * +ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id, + u_int remote_id, struct ahd_tmode_tstate **tstate) +{ + /* + * Transfer data structures are stored from the perspective + * of the target role. Since the parameters for a connection + * in the initiator role to a given target are the same as + * when the roles are reversed, we pretend we are the target. + */ + if (channel == 'B') + our_id += 8; + *tstate = ahd->enabled_targets[our_id]; + return (&(*tstate)->transinfo[remote_id]); +} + +#define AHD_COPY_COL_IDX(dst, src) \ +do { \ + dst->hscb->scsiid = src->hscb->scsiid; \ + dst->hscb->lun = src->hscb->lun; \ +} while (0) + +static __inline uint16_t +ahd_inw(struct ahd_softc *ahd, u_int port) +{ + return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); +} + +static __inline void +ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) +{ + ahd_outb(ahd, port, value & 0xFF); + ahd_outb(ahd, port+1, (value >> 8) & 0xFF); +} + +static __inline uint32_t +ahd_inl(struct ahd_softc *ahd, u_int port) +{ + return ((ahd_inb(ahd, port)) + | (ahd_inb(ahd, port+1) << 8) + | (ahd_inb(ahd, port+2) << 16) + | (ahd_inb(ahd, port+3) << 24)); +} + +static __inline void +ahd_outl(struct ahd_softc *ahd, u_int port, uint32_t value) +{ + ahd_outb(ahd, port, (value) & 0xFF); + ahd_outb(ahd, port+1, ((value) >> 8) & 0xFF); + ahd_outb(ahd, port+2, ((value) >> 16) & 0xFF); + ahd_outb(ahd, port+3, ((value) >> 24) & 0xFF); +} + +static __inline uint64_t +ahd_inq(struct ahd_softc *ahd, u_int port) +{ + return ((ahd_inb(ahd, port)) + | (ahd_inb(ahd, port+1) << 8) + | (ahd_inb(ahd, port+2) << 16) + | (ahd_inb(ahd, port+3) << 24) + | (((uint64_t)ahd_inb(ahd, port+4)) << 32) + | (((uint64_t)ahd_inb(ahd, port+5)) << 40) + | (((uint64_t)ahd_inb(ahd, port+6)) << 48) + | (((uint64_t)ahd_inb(ahd, port+7)) << 56)); +} + +static __inline void +ahd_outq(struct ahd_softc *ahd, u_int port, uint64_t value) +{ + ahd_outb(ahd, port, value & 0xFF); + ahd_outb(ahd, port+1, (value >> 8) & 0xFF); + ahd_outb(ahd, port+2, (value >> 16) & 0xFF); + ahd_outb(ahd, port+3, (value >> 24) & 0xFF); + ahd_outb(ahd, port+4, (value >> 32) & 0xFF); + ahd_outb(ahd, port+5, (value >> 40) & 0xFF); + ahd_outb(ahd, port+6, (value >> 48) & 0xFF); + ahd_outb(ahd, port+7, (value >> 56) & 0xFF); +} + +static __inline u_int +ahd_get_scbptr(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + return (ahd_inb(ahd, SCBPTR) | (ahd_inb(ahd, SCBPTR + 1) << 8)); +} + +static __inline void +ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr) +{ + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + ahd_outb(ahd, SCBPTR, scbptr & 0xFF); + ahd_outb(ahd, SCBPTR+1, (scbptr >> 8) & 0xFF); +} + +static __inline u_int +ahd_get_hnscb_qoff(struct ahd_softc *ahd) +{ + return (ahd_inw_atomic(ahd, HNSCB_QOFF)); +} + +static __inline void +ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value) +{ + ahd_outw_atomic(ahd, HNSCB_QOFF, value); +} + +static __inline u_int +ahd_get_hescb_qoff(struct ahd_softc *ahd) +{ + return (ahd_inb(ahd, HESCB_QOFF)); +} + +static __inline void +ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value) +{ + ahd_outb(ahd, HESCB_QOFF, value); +} + +static __inline u_int +ahd_get_snscb_qoff(struct ahd_softc *ahd) +{ + u_int oldvalue; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + oldvalue = ahd_inw(ahd, SNSCB_QOFF); + ahd_outw(ahd, SNSCB_QOFF, oldvalue); + return (oldvalue); +} + +static __inline void +ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + ahd_outw(ahd, SNSCB_QOFF, value); +} + +static __inline u_int +ahd_get_sescb_qoff(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + return (ahd_inb(ahd, SESCB_QOFF)); +} + +static __inline void +ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + ahd_outb(ahd, SESCB_QOFF, value); +} + +static __inline u_int +ahd_get_sdscb_qoff(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + return (ahd_inb(ahd, SDSCB_QOFF) | (ahd_inb(ahd, SDSCB_QOFF + 1) << 8)); +} + +static __inline void +ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + ahd_outb(ahd, SDSCB_QOFF, value & 0xFF); + ahd_outb(ahd, SDSCB_QOFF+1, (value >> 8) & 0xFF); +} + +static __inline u_int +ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) +{ + u_int value; + + /* + * Workaround PCI-X Rev A. hardware bug. + * After a host read of SCB memory, the chip + * may become confused into thinking prefetch + * was required. This starts the discard timer + * running and can cause an unexpected discard + * timer interrupt. The work around is to read + * a normal register prior to the exhaustion of + * the discard timer. The mode pointer register + * has no side effects and so serves well for + * this purpose. + * + * Razor #528 + */ + value = ahd_inb(ahd, offset); + ahd_inb(ahd, MODE_PTR); + return (value); +} + +static __inline u_int +ahd_inw_scbram(struct ahd_softc *ahd, u_int offset) +{ + return (ahd_inb_scbram(ahd, offset) + | (ahd_inb_scbram(ahd, offset+1) << 8)); +} + +static __inline uint32_t +ahd_inl_scbram(struct ahd_softc *ahd, u_int offset) +{ + return (ahd_inb_scbram(ahd, offset) + | (ahd_inb_scbram(ahd, offset+1) << 8) + | (ahd_inb_scbram(ahd, offset+2) << 16) + | (ahd_inb_scbram(ahd, offset+3) << 24)); +} + +static __inline struct scb * +ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) +{ + struct scb* scb; + + if (tag >= AHD_SCB_MAX) + return (NULL); + scb = ahd->scb_data.scbindex[tag]; + if (scb != NULL) + ahd_sync_scb(ahd, scb, + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); + return (scb); +} + +static __inline void +ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) +{ + struct hardware_scb *q_hscb; + uint32_t saved_hscb_busaddr; + + /* + * Our queuing method is a bit tricky. The card + * knows in advance which HSCB (by address) to download, + * and we can't disappoint it. To achieve this, the next + * HSCB to download is saved off in ahd->next_queued_hscb. + * When we are called to queue "an arbitrary scb", + * we copy the contents of the incoming HSCB to the one + * the sequencer knows about, swap HSCB pointers and + * finally assign the SCB to the tag indexed location + * in the scb_array. This makes sure that we can still + * locate the correct SCB by SCB_TAG. + */ + q_hscb = ahd->next_queued_hscb; + saved_hscb_busaddr = q_hscb->hscb_busaddr; + memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); + q_hscb->hscb_busaddr = saved_hscb_busaddr; + q_hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; + + /* Now swap HSCB pointers. */ + ahd->next_queued_hscb = scb->hscb; + scb->hscb = q_hscb; + + /* Now define the mapping from tag to SCB in the scbindex */ + ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; +} + +/* + * Tell the sequencer about a new transaction to execute. + */ +static __inline void +ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb) +{ + ahd_swap_with_next_hscb(ahd, scb); + + if (SCBID_IS_NULL(SCB_GET_TAG(scb))) + panic("Attempt to queue invalid SCB tag %x\n", + SCB_GET_TAG(scb)); + + /* + * Keep a history of SCBs we've downloaded in the qinfifo. + */ + ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); + ahd->qinfifonext++; + + if (scb->sg_count != 0) + ahd_setup_data_scb(ahd, scb); + else + ahd_setup_noxfer_scb(ahd, scb); + ahd_setup_scb_common(ahd, scb); + + /* + * Make sure our data is consistant from the + * perspective of the adapter. + */ + ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_QUEUE) != 0) { + printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n", + ahd_name(ahd), + SCB_GET_TAG(scb), scb->hscb->hscb_busaddr, + (u_int)((scb->hscb->dataptr >> 32) & 0xFFFFFFFF), + (u_int)(scb->hscb->dataptr & 0xFFFFFFFF), + scb->hscb->datacnt); + } +#endif + /* Tell the adapter about the newly queued SCB */ + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); +} + +static __inline uint8_t * +ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb) +{ + return (scb->sense_data); +} + +static __inline uint32_t +ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb) +{ + return (scb->sense_busaddr); +} + +/************************** Interrupt Processing ******************************/ +static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op); +static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op); +static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd); +static __inline void ahd_intr(struct ahd_softc *ahd); + +static __inline void +ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) +{ + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, + /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); +} + +static __inline void +ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) +{ +#ifdef AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0) { + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap, + ahd_targetcmd_offset(ahd, 0), + sizeof(struct target_cmd) * AHD_TMODE_CMDS, + op); + } +#endif +} + +/* + * See if the firmware has posted any completed commands + * into our in-core command complete fifos. + */ +#define AHD_RUN_QOUTFIFO 0x1 +#define AHD_RUN_TQINFIFO 0x2 +static __inline u_int +ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) +{ + u_int retval; + + retval = 0; + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, + /*offset*/ahd->qoutfifonext, /*len*/2, + BUS_DMASYNC_POSTREAD); + if ((ahd->qoutfifo[ahd->qoutfifonext] + & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) + retval |= AHD_RUN_QOUTFIFO; +#ifdef AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0 + && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap, + ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), + /*len*/sizeof(struct target_cmd), + BUS_DMASYNC_POSTREAD); + if (ahd->targetcmds[ahd->tqinfifonext].cmd_valid != 0) + retval |= AHD_RUN_TQINFIFO; + } +#endif + return (retval); +} + +/* + * Catch an interrupt from the adapter + */ +static __inline void +ahd_intr(struct ahd_softc *ahd) +{ + u_int intstat; + + if ((ahd->pause & INTEN) == 0) { + /* + * Our interrupt is not enabled on the chip + * and may be disabled for re-entrancy reasons, + * so just return. This is likely just a shared + * interrupt. + */ + return; + } + + /* + * Instead of directly reading the interrupt status register, + * infer the cause of the interrupt by checking our in-core + * completion queues. This avoids a costly PCI bus read in + * most cases. + */ + if ((ahd->flags & AHD_ALL_INTERRUPTS) == 0 + && (ahd_check_cmdcmpltqueues(ahd) != 0)) + intstat = CMDCMPLT; + else + intstat = ahd_inb(ahd, INTSTAT); + + if (intstat & CMDCMPLT) { + ahd_outb(ahd, CLRINT, CLRCMDINT); + + /* + * Ensure that the chip sees that we've cleared + * this interrupt before we walk the output fifo. + * Otherwise, we may, due to posted bus writes, + * clear the interrupt after we finish the scan, + * and after the sequencer has added new entries + * and asserted the interrupt again. + */ + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + if (ahd_is_paused(ahd)) { + /* + * Potentially lost SEQINT. + * If SEQINTCODE is non-zero, + * simulate the SEQINT. + */ + if (ahd_inb(ahd, SEQINTCODE) != NO_SEQINT) + intstat |= SEQINT; + } + } else { + ahd_flush_device_writes(ahd); + } + ahd_run_qoutfifo(ahd); + ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]++; + ahd->cmdcmplt_total++; +#ifdef AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0) + ahd_run_tqinfifo(ahd, /*paused*/FALSE); +#endif + } + + if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) + /* Hot eject */ + return; + + if ((intstat & INT_PEND) == 0) + return; + + if (intstat & HWERRINT) { + ahd_handle_hwerrint(ahd); + return; + } + + if ((intstat & (PCIINT|SPLTINT)) != 0) { + ahd->bus_intr(ahd); + return; + } + + if ((intstat & SEQINT) != 0) + ahd_handle_seqint(ahd, intstat); + + if ((intstat & SCSIINT) != 0) + ahd_handle_scsiint(ahd, intstat); +} + +#endif /* _AIC79XX_INLINE_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_osm.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_osm.c --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_osm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_osm.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,5322 @@ +/* + * Adaptec AIC79xx device driver for Linux. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 $ + * + * -------------------------------------------------------------------------- + * Copyright (c) 1994-2000 Justin T. Gibbs. + * Copyright (c) 1997-1999 Doug Ledford + * Copyright (c) 2000-2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * This is the only file where module.h should + * embed module global version info. + */ +#define AHD_MODVERSION_FILE + +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" +#include + +/* + * Include aiclib.c as part of our + * "module dependencies are hard" work around. + */ +#include "aiclib.c" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) +#include /* __setup */ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include "sd.h" /* For geometry detection */ +#endif + +#include /* For fetching system memory size */ + +#define __KERNEL_SYSCALLS__ + +#include +static int errno; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +/* + * Lock protecting manipulation of the ahd softc list. + */ +spinlock_t ahd_list_spinlock; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +struct proc_dir_entry proc_scsi_aic79xx = { + PROC_SCSI_AIC79XX, 7, "aic79xx", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif + +/* + * Bucket size for counting good commands in between bad ones. + */ +#define AHD_LINUX_ERR_THRESH 1000 + +/* + * Set this to the delay in seconds after SCSI bus reset. + * Note, we honor this only for the initial bus reset. + * The scsi error recovery code performs its own bus settle + * delay handling for error recovery actions. + */ +#ifdef CONFIG_AIC79XX_RESET_DELAY_MS +#define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS +#else +#define AIC79XX_RESET_DELAY 5000 +#endif + +/* + * To change the default number of tagged transactions allowed per-device, + * add a line to the lilo.conf file like: + * append="aic79xx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}" + * which will result in the first four devices on the first two + * controllers being set to a tagged queue depth of 32. + * + * The tag_commands is an array of 16 to allow for wide and twin adapters. + * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15 + * for channel 1. + */ +typedef struct { + uint16_t tag_commands[16]; /* Allow for wide/twin adapters. */ +} adapter_tag_info_t; + +/* + * Modify this as you see fit for your system. + * + * 0 tagged queuing disabled + * 1 <= n <= 253 n == max tags ever dispatched. + * + * The driver will throttle the number of commands dispatched to a + * device if it returns queue full. For devices with a fixed maximum + * queue depth, the driver will eventually determine this depth and + * lock it in (a console message is printed to indicate that a lock + * has occurred). On some devices, queue full is returned for a temporary + * resource shortage. These devices will return queue full at varying + * depths. The driver will throttle back when the queue fulls occur and + * attempt to slowly increase the depth over time as the device recovers + * from the resource shortage. + * + * In this example, the first line will disable tagged queueing for all + * the devices on the first probed aic79xx adapter. + * + * The second line enables tagged queueing with 4 commands/LUN for IDs + * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the + * driver to attempt to use up to 64 tags for ID 1. + * + * The third line is the same as the first line. + * + * The fourth line disables tagged queueing for devices 0 and 3. It + * enables tagged queueing for the other IDs, with 16 commands/LUN + * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for + * IDs 2, 5-7, and 9-15. + */ + +/* + * NOTE: The below structure is for reference only, the actual structure + * to modify in order to change things is just below this comment block. +adapter_tag_info_t aic79xx_tag_info[] = +{ + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}} +}; +*/ + +#ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE +#define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE +#else +#define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE +#endif + +#define AIC79XX_CONFIGED_TAG_COMMANDS { \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \ +} + +/* + * By default, use the number of commands specified by + * the users kernel configuration. + */ +static adapter_tag_info_t aic79xx_tag_info[] = +{ + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS} +}; + +/* + * By default, read streaming is disabled. In theory, + * read streaming should enhance performance, but early + * U320 drive firmware actually performs slower with + * read streaming enabled. + */ +#ifdef CONFIG_AIC79XX_ENABLE_RD_STRM +#define AIC79XX_CONFIGED_RD_STRM 0xFFFF +#else +#define AIC79XX_CONFIGED_RD_STRM 0 +#endif + +static uint16_t aic79xx_rd_strm_info[] = +{ + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM +}; + +/* + * DV option: + * + * positive value = DV Enabled + * zero = DV Disabled + * negative value = DV Default for adapter type/seeprom + */ +#ifdef CONFIG_AIC79XX_DV_SETTING +#define AIC79XX_CONFIGED_DV CONFIG_AIC79XX_DV_SETTING +#else +#define AIC79XX_CONFIGED_DV -1 +#endif + +static int8_t aic79xx_dv_settings[] = +{ + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV +}; + +/* + * The I/O cell on the chip is very configurable in respect to its analog + * characteristics. Set the defaults here; they can be overriden with + * the proper insmod parameters. + */ +struct ahd_linux_iocell_opts +{ + uint8_t precomp; + uint8_t slewrate; + uint8_t amplitude; +}; +#define AIC79XX_DEFAULT_PRECOMP 0xFF +#define AIC79XX_DEFAULT_SLEWRATE 0xFF +#define AIC79XX_DEFAULT_AMPLITUDE 0xFF +#define AIC79XX_DEFAULT_IOOPTS \ +{ \ + AIC79XX_DEFAULT_PRECOMP, \ + AIC79XX_DEFAULT_SLEWRATE, \ + AIC79XX_DEFAULT_AMPLITUDE \ +} +#define AIC79XX_PRECOMP_INDEX 0 +#define AIC79XX_SLEWRATE_INDEX 1 +#define AIC79XX_AMPLITUDE_INDEX 2 +static struct ahd_linux_iocell_opts aic79xx_iocell_info[] = +{ + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS +}; + +/* + * There should be a specific return value for this in scsi.h, but + * it seems that most drivers ignore it. + */ +#define DID_UNDERFLOW DID_ERROR + +void +ahd_print_path(struct ahd_softc *ahd, struct scb *scb) +{ + printk("(scsi%d:%c:%d:%d): ", + ahd->platform_data->host->host_no, + scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X', + scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1, + scb != NULL ? SCB_GET_LUN(scb) : -1); +} + +/* + * XXX - these options apply unilaterally to _all_ adapters + * cards in the system. This should be fixed. Exceptions to this + * rule are noted in the comments. + */ + +/* + * Skip the scsi bus reset. Non 0 make us skip the reset at startup. This + * has no effect on any later resets that might occur due to things like + * SCSI bus timeouts. + */ +static uint32_t aic79xx_no_reset; + +/* + * Certain PCI motherboards will scan PCI devices from highest to lowest, + * others scan from lowest to highest, and they tend to do all kinds of + * strange things when they come into contact with PCI bridge chips. The + * net result of all this is that the PCI card that is actually used to boot + * the machine is very hard to detect. Most motherboards go from lowest + * PCI slot number to highest, and the first SCSI controller found is the + * one you boot from. The only exceptions to this are when a controller + * has its BIOS disabled. So, we by default sort all of our SCSI controllers + * from lowest PCI slot number to highest PCI slot number. We also force + * all controllers with their BIOS disabled to the end of the list. This + * works on *almost* all computers. Where it doesn't work, we have this + * option. Setting this option to non-0 will reverse the order of the sort + * to highest first, then lowest, but will still leave cards with their BIOS + * disabled at the very end. That should fix everyone up unless there are + * really strange cirumstances. + */ +static int aic79xx_reverse_scan = 0; + +/* + * Should we force EXTENDED translation on a controller. + * 0 == Use whatever is in the SEEPROM or default to off + * 1 == Use whatever is in the SEEPROM or default to on + */ +static uint32_t aic79xx_extended = 0; + +/* + * PCI bus parity checking of the Adaptec controllers. This is somewhat + * dubious at best. To my knowledge, this option has never actually + * solved a PCI parity problem, but on certain machines with broken PCI + * chipset configurations, it can generate tons of false error messages. + * It's included in the driver for completeness. + * 0 = Shut off PCI parity check + * -1 = Normal polarity pci parity checking + * 1 = reverse polarity pci parity checking + * + * NOTE: you can't actually pass -1 on the lilo prompt. So, to set this + * variable to -1 you would actually want to simply pass the variable + * name without a number. That will invert the 0 which will result in + * -1. + */ +static int aic79xx_pci_parity = 0; + +/* + * There are lots of broken chipsets in the world. Some of them will + * violate the PCI spec when we issue byte sized memory writes to our + * controller. I/O mapped register access, if allowed by the given + * platform, will work in almost all cases. + */ +int aic79xx_allow_memio = 1; + +/* + * aic79xx_detect() has been run, so register all device arrivals + * immediately with the system rather than deferring to the sorted + * attachment performed by aic79xx_detect(). + */ +int aic79xx_detect_complete; + +/* + * So that we can set how long each device is given as a selection timeout. + * The table of values goes like this: + * 0 - 256ms + * 1 - 128ms + * 2 - 64ms + * 3 - 32ms + * We default to 256ms because some older devices need a longer time + * to respond to initial selection. + */ +static int aic79xx_seltime = 0x00; + +/* + * Certain devices do not perform any aging on commands. Should the + * device be saturated by commands in one portion of the disk, it is + * possible for transactions on far away sectors to never be serviced. + * To handle these devices, we can periodically send an ordered tag to + * force all outstanding transactions to be serviced prior to a new + * transaction. + */ +int aic79xx_periodic_otag; + +/* + * Module information and settable options. + */ +#ifdef MODULE +static char *aic79xx = NULL; +/* + * Just in case someone uses commas to separate items on the insmod + * command line, we define a dummy buffer here to avoid having insmod + * write wild stuff into our code segment + */ +static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n"; + +MODULE_AUTHOR("Maintainer: Justin T. Gibbs "); +MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual BSD/GPL"); +#endif +MODULE_PARM(aic79xx, "s"); +MODULE_PARM_DESC(aic79xx, +"period delimited, options string.\n" +" verbose Enable verbose/diagnostic logging\n" +" allow_memio Allow device registers to be memory mapped\n" +" debug Bitmask of debug values to enable\n" +" no_reset Supress initial bus resets\n" +" extended Enable extended geometry on all controllers\n" +" periodic_otag Send an ordered tagged transaction\n" +" periodically to prevent tag starvation.\n" +" This may be required by some older disk\n" +" or drives/RAID arrays.\n" +" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" +" tag_info: Set per-target tag depth\n" +" global_tag_depth: Global tag depth for all targets on all buses\n" +" rd_strm: Set per-target read streaming setting.\n" +" dv: Set per-controller Domain Validation Setting.\n" +" slewrate:Set the signal slew rate (0-15).\n" +" precomp: Set the signal precompensation (0-7).\n" +" amplitude: Set the signal amplitude (0-7).\n" +" seltime: Selection Timeout:\n" +" (0/256ms,1/128ms,2/64ms,3/32ms)\n" +"\n" +" Sample /etc/modules.conf line:\n" +" Enable verbose logging\n" +" Set tag depth on Controller 2/Target 2 to 10 tags\n" +" Shorten the selection timeout to 128ms\n" +"\n" +" options aic79xx='\"verbose.tag_info:{{}.{}.{..10}}.seltime:1\"'\n" +"\n" +" Sample /etc/modules.conf line:\n" +" Change Read Streaming for Controller's 2 and 3\n" +"\n" +" options aic79xx='\"rd_strm:{..0xFFF0.0xC0F0}\"'"); +#endif + +static void ahd_linux_handle_scsi_status(struct ahd_softc *, + struct ahd_linux_device *, + struct scb *); +static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, + Scsi_Cmnd *cmd); +static void ahd_linux_filter_inquiry(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dev_timed_unfreeze(u_long arg); +static void ahd_linux_sem_timeout(u_long arg); +static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); +static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); +static void ahd_linux_start_dv(struct ahd_softc *ahd); +static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd); +static int ahd_linux_dv_thread(void *data); +static void ahd_linux_dv_target(struct ahd_softc *ahd, u_int target); +static void ahd_linux_dv_transition(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dv_inq(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ, + u_int request_length); +static void ahd_linux_dv_tur(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dv_rebd(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_web(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_reb(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_su(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static __inline int + ahd_linux_dv_fallback(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static int ahd_linux_fallback(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static __inline int ahd_linux_dv_fallback(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dv_complete(Scsi_Cmnd *cmd); +static void ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ); +static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static u_int ahd_linux_user_dv_setting(struct ahd_softc *ahd); +static void ahd_linux_device_queue_depth(struct ahd_softc *ahd, + struct ahd_linux_device *dev); +static struct ahd_linux_target* ahd_linux_alloc_target(struct ahd_softc*, + u_int, u_int); +static void ahd_linux_free_target(struct ahd_softc*, + struct ahd_linux_target*); +static struct ahd_linux_device* ahd_linux_alloc_device(struct ahd_softc*, + struct ahd_linux_target*, + u_int); +static void ahd_linux_free_device(struct ahd_softc*, + struct ahd_linux_device*); +static void ahd_linux_run_device_queue(struct ahd_softc*, + struct ahd_linux_device*); +static void ahd_linux_setup_tag_info(char *p, char *end, char *s); +static void ahd_linux_setup_tag_info_global(char *p); +static void ahd_linux_setup_rd_strm_info(char *p, char *end, char *s); +static void ahd_linux_setup_dv(char *p, char *end, char *s); +static void ahd_linux_setup_iocell_info(char *p, char *end, char *s, int index); +static int ahd_linux_next_unit(void); +static void ahd_runq_tasklet(unsigned long data); +static int ahd_linux_halt(struct notifier_block *nb, u_long event, void *buf); +static int aic79xx_setup(char *c); + +/****************************** Inlines ***************************************/ +static __inline void ahd_schedule_completeq(struct ahd_softc *ahd, + struct ahd_cmd *acmd); +static __inline void ahd_schedule_runq(struct ahd_softc *ahd); +static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd); +static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd); +static __inline struct ahd_linux_device* + ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, + u_int target, u_int lun, int alloc); +static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd, + struct ahd_cmd *acmd); +static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd, + struct ahd_linux_device *dev); +static __inline struct ahd_linux_device * + ahd_linux_next_device_to_run(struct ahd_softc *ahd); +static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd); +static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); + +static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, + struct ahd_dma_seg *sg, + bus_addr_t addr, bus_size_t len); + +static __inline void +ahd_schedule_completeq(struct ahd_softc *ahd, struct ahd_cmd *acmd) +{ + while (acmd != NULL) { + struct ahd_completeq *completeq; + struct ahd_cmd *list_cmd; + struct ahd_cmd *next_cmd; + + next_cmd = TAILQ_NEXT(acmd, acmd_links.tqe); + completeq = &ahd->platform_data->completeq; + list_cmd = TAILQ_FIRST(completeq); + while (list_cmd != NULL + && acmd_scsi_cmd(list_cmd).serial_number + < acmd_scsi_cmd(acmd).serial_number) + list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); + if (list_cmd != NULL) + TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); + else + TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); + acmd = next_cmd; + } + if ((ahd->platform_data->flags & AHD_RUN_CMPLT_Q_TIMER) == 0) { + ahd->platform_data->flags |= AHD_RUN_CMPLT_Q_TIMER; + ahd->platform_data->completeq_timer.expires = jiffies; + add_timer(&ahd->platform_data->completeq_timer); + } +} + +static __inline void +ahd_schedule_runq(struct ahd_softc *ahd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_schedule(&ahd->platform_data->runq_tasklet); +#else + /* + * Tasklets are not available, so run inline. + */ + ahd_runq_tasklet((unsigned long)ahd); +#endif +} + +static __inline +void ahd_setup_runq_tasklet(struct ahd_softc *ahd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet, + (unsigned long)ahd); +#endif +} + +static __inline void +ahd_teardown_runq_tasklet(struct ahd_softc *ahd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_kill(&ahd->platform_data->runq_tasklet); +#endif +} + +static __inline struct ahd_linux_device* +ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target, + u_int lun, int alloc) +{ + struct ahd_linux_target *targ; + struct ahd_linux_device *dev; + u_int target_offset; + + target_offset = target; + if (channel != 0) + target_offset += 8; + targ = ahd->platform_data->targets[target_offset]; + if (targ == NULL) { + if (alloc != 0) { + targ = ahd_linux_alloc_target(ahd, channel, target); + if (targ == NULL) + return (NULL); + } else + return (NULL); + } + dev = targ->devices[lun]; + if (dev == NULL && alloc != 0) + dev = ahd_linux_alloc_device(ahd, targ, lun); + return (dev); +} + +#define AHD_LINUX_MAX_RETURNED_ERRORS 4 +static struct ahd_cmd * +ahd_linux_run_complete_queue(struct ahd_softc *ahd, struct ahd_cmd *acmd) +{ + u_long done_flags; + int with_errors; + + ahd_done_lock(ahd, &done_flags); + with_errors = 0; + while (acmd != NULL) { + Scsi_Cmnd *cmd; + + cmd = &acmd_scsi_cmd(acmd); + acmd = TAILQ_NEXT(acmd, acmd_links.tqe); + cmd->host_scribble = NULL; + if (ahd_cmd_get_transaction_status(cmd) != DID_OK + || (cmd->result & 0xFF) != SCSI_STATUS_OK) + with_errors++; + + cmd->scsi_done(cmd); + + if (with_errors > AHD_LINUX_MAX_RETURNED_ERRORS) { + /* + * Linux uses stack recursion to requeue + * commands that need to be retried. Avoid + * blowing out the stack by "spoon feeding" + * commands that completed with error back + * the operating system in case they are going + * to be retried. "ick" + */ + break; + } + } + ahd_done_unlock(ahd, &done_flags); + return (acmd); +} + +static __inline void +ahd_linux_check_device_queue(struct ahd_softc *ahd, + struct ahd_linux_device *dev) +{ + if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) != 0 + && dev->active == 0) { + dev->flags &= ~AHD_DEV_FREEZE_TIL_EMPTY; + dev->qfrozen--; + } + + if (TAILQ_FIRST(&dev->busyq) == NULL + || dev->openings == 0 || dev->qfrozen != 0) + return; + + ahd_linux_run_device_queue(ahd, dev); +} + +static __inline struct ahd_linux_device * +ahd_linux_next_device_to_run(struct ahd_softc *ahd) +{ + + if ((ahd->flags & AHD_RESOURCE_SHORTAGE) != 0 + || (ahd->platform_data->qfrozen != 0 + && AHD_DV_SIMQ_FROZEN(ahd) == 0)) + return (NULL); + return (TAILQ_FIRST(&ahd->platform_data->device_runq)); +} + +static __inline void +ahd_linux_run_device_queues(struct ahd_softc *ahd) +{ + struct ahd_linux_device *dev; + + while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { + TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); + dev->flags &= ~AHD_DEV_ON_RUN_LIST; + ahd_linux_check_device_queue(ahd, dev); + } +} + +static __inline void +ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) +{ + Scsi_Cmnd *cmd; + int direction; + + cmd = scb->io_ctx; + direction = scsi_to_pci_dma_dir(cmd->sc_data_direction); + ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE); + if (cmd->use_sg != 0) { + struct scatterlist *sg; + + sg = (struct scatterlist *)cmd->request_buffer; + pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction); + } else if (cmd->request_bufflen != 0) { + pci_unmap_single(ahd->dev_softc, + scb->platform_data->buf_busaddr, + cmd->request_bufflen, direction); + } +} + +static __inline int +ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, + struct ahd_dma_seg *sg, bus_addr_t addr, bus_size_t len) +{ + int consumed; + + if ((scb->sg_count + 1) > AHD_NSEG) + panic("Too few segs for dma mapping. " + "Increase AHD_NSEG\n"); + + consumed = 1; + sg->addr = ahd_htole32(addr & 0xFFFFFFFF); + scb->platform_data->xfer_len += len; + if (sizeof(bus_addr_t) > 4 + && (ahd->flags & AHD_39BIT_ADDRESSING) != 0) { + /* + * Due to DAC restrictions, we can't + * cross a 4GB boundary. + */ + if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) { + struct ahd_dma_seg *next_sg; + uint32_t next_len; + + printf("Crossed Seg\n"); + if ((scb->sg_count + 2) > AHD_NSEG) + panic("Too few segs for dma mapping. " + "Increase AHD_NSEG\n"); + + consumed++; + next_sg = sg + 1; + next_sg->addr = 0; + next_len = 0x100000000 - (addr & 0xFFFFFFFF); + len -= next_len; + next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000; + next_sg->len = ahd_htole32(next_len); + } + len |= (addr >> 8) & 0x7F000000; + } + sg->len = ahd_htole32(len); + return (consumed); +} + +/******************************** Macros **************************************/ +#define BUILD_SCSIID(ahd, cmd) \ + ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) + +/************************ Host template entry points *************************/ +static int ahd_linux_detect(Scsi_Host_Template *); +static int ahd_linux_release(struct Scsi_Host *); +static const char *ahd_linux_info(struct Scsi_Host *); +static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int ahd_linux_slave_alloc(Scsi_Device *); +static int ahd_linux_slave_configure(Scsi_Device *); +static void ahd_linux_slave_destroy(Scsi_Device *); +static int ahd_linux_biosparam(struct scsi_device*, + struct block_device*, sector_t, int[]); +#else +static void ahd_linux_select_queue_depth(struct Scsi_Host *host, + Scsi_Device *scsi_devs); +static int ahd_linux_biosparam(Disk *, kdev_t, int[]); +#endif +static int ahd_linux_bus_reset(Scsi_Cmnd *); +static int ahd_linux_dev_reset(Scsi_Cmnd *); +static int ahd_linux_abort(Scsi_Cmnd *); + +/* + * Try to detect an Adaptec 79XX controller. + */ +static int +ahd_linux_detect(Scsi_Host_Template *template) +{ + struct ahd_softc *ahd; + int found; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * It is a bug that the upper layer takes + * this lock just prior to calling us. + */ + spin_unlock_irq(&io_request_lock); +#endif + + /* + * Sanity checking of Linux SCSI data structures so + * that some of our hacks^H^H^H^H^Hassumptions aren't + * violated. + */ + if (offsetof(struct ahd_cmd_internal, end) + > offsetof(struct scsi_cmnd, host_scribble)) { + printf("ahd_linux_detect: SCSI data structures changed.\n"); + printf("ahd_linux_detect: Unable to attach\n"); + return (0); + } +#ifdef MODULE + /* + * If we've been passed any parameters, process them now. + */ + if (aic79xx) + aic79xx_setup(aic79xx); + if (dummy_buffer[0] != 'P') + printk(KERN_WARNING +"aic79xx: Please read the file /usr/src/linux/drivers/scsi/README.aic79xx\n" +"aic79xx: to see the proper way to specify options to the aic79xx module\n" +"aic79xx: Specifically, don't use any commas when passing arguments to\n" +"aic79xx: insmod or else it might trash certain memory areas.\n"); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) + template->proc_name = "aic79xx"; +#else + template->proc_dir = &proc_scsi_aic79xx; +#endif + + /* + * Initialize our softc list lock prior to + * probing for any adapters. + */ + ahd_list_lockinit(); + +#ifdef CONFIG_PCI + ahd_linux_pci_probe(template); +#endif + + /* + * Register with the SCSI layer all + * controllers we've found. + */ + found = 0; + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + + if (ahd_linux_register_host(ahd, template) == 0) + found++; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + aic79xx_detect_complete++; + return (found); +} + +/* + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + */ +static int +ahd_linux_release(struct Scsi_Host * host) +{ + struct ahd_softc *ahd; + u_long l; + + ahd_list_lock(&l); + if (host != NULL) { + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata); + if (ahd != NULL) { + u_long s; + + ahd_lock(ahd, &s); + ahd_intr_enable(ahd, FALSE); + ahd_unlock(ahd, &s); + ahd_free(ahd); + } + } + ahd_list_unlock(&l); + return (0); +} + +/* + * Return a string describing the driver. + */ +static const char * +ahd_linux_info(struct Scsi_Host *host) +{ + static char buffer[512]; + char ahd_info[256]; + char *bp; + struct ahd_softc *ahd; + + bp = &buffer[0]; + ahd = *(struct ahd_softc **)host->hostdata; + memset(bp, 0, sizeof(buffer)); + strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev "); + strcat(bp, AIC79XX_DRIVER_VERSION); + strcat(bp, "\n"); + strcat(bp, " <"); + strcat(bp, ahd->description); + strcat(bp, ">\n"); + strcat(bp, " "); + ahd_controller_info(ahd, ahd_info); + strcat(bp, ahd_info); + strcat(bp, "\n"); + + return (bp); +} + +/* + * Queue an SCB to the controller. + */ +static int +ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + + /* + * Save the callback on completion function. + */ + cmd->scsi_done = scsi_done; + + ahd_midlayer_entrypoint_lock(ahd, &flags); + + /* + * Close the race of a command that was in the process of + * being queued to us just as our simq was frozen. Let + * DV commands through so long as we are only frozen to + * perform DV. + */ + if (ahd->platform_data->qfrozen != 0 + && AHD_DV_CMD(cmd) == 0) { + + ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); + ahd_linux_queue_cmd_complete(ahd, cmd); + ahd_schedule_completeq(ahd, NULL); + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); + } + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, cmd->device->lun, + /*alloc*/TRUE); + if (dev == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &flags); + printf("aic79xx_linux_queue: Unable to allocate device!\n"); + return (-ENOMEM); + } + if (cmd->cmd_len > MAX_CDB_LEN) + return (-EINVAL); + cmd->result = CAM_REQ_INPROG << 16; + TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe); + if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + ahd_linux_run_device_queues(ahd); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +ahd_linux_slave_alloc(Scsi_Device *device) +{ + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Alloc %d\n", ahd_name(ahd), device->id); + return (0); +} + +static int +ahd_linux_slave_configure(Scsi_Device *device) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *((struct ahd_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Configure %d\n", ahd_name(ahd), device->id); + ahd_midlayer_entrypoint_lock(ahd, &flags); + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHD_DEV_UNCONFIGURED; + dev->flags |= AHD_DEV_SLAVE_CONFIGURED; + dev->scsi_device = device; + ahd_linux_device_queue_depth(ahd, dev); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); +} + +static void +ahd_linux_slave_destroy(Scsi_Device *device) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *((struct ahd_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Destroy %d\n", ahd_name(ahd), device->id); + ahd_midlayer_entrypoint_lock(ahd, &flags); + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/FALSE); + + /* + * Filter out "silly" deletions of real devices by only + * deleting devices that have had slave_configure() + * called on them. All other devices that have not + * been configured will automatically be deleted by + * the refcounting process. + */ + if (dev != NULL + && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) { + dev->flags |= AHD_DEV_UNCONFIGURED; + if (TAILQ_EMPTY(&dev->busyq) + && dev->active == 0) + ahd_linux_free_device(ahd, dev); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); +} +#else +/* + * Sets the queue depth for each SCSI device hanging + * off the input host adapter. + */ +static void +ahd_linux_select_queue_depth(struct Scsi_Host * host, + Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + struct ahd_softc *ahd; + u_long flags; + int scbnum; + + ahd = *((struct ahd_softc **)host->hostdata); + ahd_midlayer_entrypoint_lock(ahd, &flags); + scbnum = 0; + for (device = scsi_devs; device != NULL; device = device->next) { + + if (device->host == host) { + struct ahd_linux_device *dev; + + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHD_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahd_linux_device_queue_depth(ahd, dev); + device->queue_depth = dev->openings + + dev->active; + if ((dev->flags & (AHD_DEV_Q_BASIC + | AHD_DEV_Q_TAGGED)) == 0) { + /* + * We allow the OS to queue 2 untagged + * transactions to us at any time even + * though we can only execute them + * serially on the controller/device. + * This should remove some latency. + */ + device->queue_depth = 2; + } + } + } + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); +} +#endif + +/* + * Return the disk geometry for the given SCSI device. + */ +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) +{ + uint8_t *bh; +#else +ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + struct scsi_device *sdev = disk->device; + u_long capacity = disk->capacity; + struct buffer_head *bh; +#endif + int heads; + int sectors; + int cylinders; + int ret; + int extended; + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)sdev->host->hostdata); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + bh = scsi_bios_ptable(bdev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); +#else + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); +#endif + + if (bh) { + ret = scsi_partsize(bh, capacity, + &geom[2], &geom[0], &geom[1]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + kfree(bh); +#else + brelse(bh); +#endif + if (ret != -1) + return (ret); + } + heads = 64; + sectors = 32; + cylinders = aic_sector_div(capacity, heads, sectors); + + if (aic79xx_extended != 0) + extended = 1; + else + extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0; + if (extended && cylinders >= 1024) { + heads = 255; + sectors = 63; + cylinders = aic_sector_div(capacity, heads, sectors); + } + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + return (0); +} + +/* + * Abort the current SCSI command(s). + */ +static int +ahd_linux_abort(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + struct ahd_cmd *acmd; + struct ahd_cmd *list_acmd; + struct ahd_linux_device *dev; + struct scb *pending_scb; + u_long s; + u_int saved_scbptr; + u_int active_scbptr; + u_int last_phase; + int retval; + int paused; + int wait; + int disconnected; + ahd_mode_state saved_modes; + + pending_scb = NULL; + paused = FALSE; + wait = FALSE; + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + acmd = (struct ahd_cmd *)cmd; + + printf("%s:%d:%d:%d: Attempting to abort cmd %p\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun, cmd); + + /* + * In all versions of Linux, we have to work around + * a major flaw in how the mid-layer is locked down + * if we are to sleep successfully in our error handler + * while allowing our interrupt handler to run. Since + * the midlayer acquires either the io_request_lock or + * our lock prior to calling us, we must use the + * spin_unlock_irq() method for unlocking our lock. + * This will force interrupts to be enabled on the + * current CPU. Since the EH thread should not have + * been running with CPU interrupts disabled other than + * by acquiring either the io_request_lock or our own + * lock, this *should* be safe. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahd_midlayer_entrypoint_lock(ahd, &s); + + /* + * First determine if we currently own this command. + * Start by searching the device queue. If not found + * there, check the pending_scb list. If not found + * at all, and the system wanted us to just abort the + * command return success. + */ + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, cmd->device->lun, + /*alloc*/FALSE); + + if (dev == NULL) { + /* + * No target device for this command exists, + * so we must not still own the command. + */ + printf("%s:%d:%d:%d: Is not an active device\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + retval = SUCCESS; + goto no_cmd; + } + + TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { + if (list_acmd == acmd) + break; + } + + if (list_acmd != NULL) { + printf("%s:%d:%d:%d: Command found on device queue\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); + cmd->result = DID_ABORT << 16; + ahd_linux_queue_cmd_complete(ahd, cmd); + retval = SUCCESS; + goto done; + } + + /* + * See if we can find a matching cmd in the pending list. + */ + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + if (pending_scb->io_ctx == cmd) + break; + } + + if (pending_scb == NULL) { + printf("%s:%d:%d:%d: Command not found\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + goto no_cmd; + } + + if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) { + /* + * We can't queue two recovery actions using the same SCB + */ + retval = FAILED; + goto done; + } + + /* + * Ensure that the card doesn't do anything + * behind our back. Also make sure that we + * didn't "just" miss an interrupt that would + * affect this cmd. + */ + ahd_pause_and_flushwork(ahd); + paused = TRUE; + + if ((pending_scb->flags & SCB_ACTIVE) == 0) { + printf("%s:%d:%d:%d: Command already completed\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + goto no_cmd; + } + + ahd_dump_card_state(ahd); + + disconnected = TRUE; + if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, + ROLE_INITIATOR, CAM_REQ_ABORTED, + SEARCH_COMPLETE) > 0) { + printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + retval = SUCCESS; + goto done; + } + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + last_phase = ahd_inb(ahd, LASTPHASE); + saved_scbptr = ahd_get_scbptr(ahd); + active_scbptr = saved_scbptr; + if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { + struct scb *bus_scb; + + bus_scb = ahd_lookup_scb(ahd, active_scbptr); + if (bus_scb == pending_scb) + disconnected = FALSE; + } + + /* + * At this point, pending_scb is the scb associated with the + * passed in command. That command is currently active on the + * bus or is in the disconnected state. + */ + if (last_phase != P_BUSFREE + && pending_scb->hscb->tag == active_scbptr) { + + /* + * We're active on the bus, so assert ATN + * and hope that the target responds. + */ + pending_scb = ahd_lookup_scb(ahd, active_scbptr); + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SCSISIGO, last_phase|ATNO); + printf("%s:%d:%d:%d: Device is active, asserting ATN\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + wait = TRUE; + } else if (disconnected) { + + /* + * Actually re-queue this SCB in an attempt + * to select the device before it reconnects. + */ + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + ahd_set_scbptr(ahd, pending_scb->hscb->tag); + pending_scb->hscb->cdb_len = 0; + pending_scb->hscb->task_attribute = 0; + pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK; + + if ((pending_scb->flags & SCB_PACKETIZED) != 0) { + /* + * Mark the SCB has having an outstanding + * task management function. Should the command + * complete normally before the task management + * function can be sent, the host will be notified + * to abort our requeued SCB. + */ + ahd_outb(ahd, SCB_TASK_MANAGEMENT, + pending_scb->hscb->task_management); + } else { + /* + * If non-packetized, set the MK_MESSAGE control + * bit indicating that we desire to send a message. + * We also set the disconnected flag since there is + * no guarantee that our SCB control byte matches + * the version on the card. We don't want the + * sequencer to abort the command thinking an + * unsolicited reselection occurred. + */ + pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED; + + /* + * The sequencer will never re-reference the + * in-core SCB. To make sure we are notified + * during reslection, set the MK_MESSAGE flag in + * the card's copy of the SCB. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE); + } + + /* + * Clear out any entries in the QINFIFO first + * so we are the next SCB for this target + * to run. + */ + ahd_search_qinfifo(ahd, cmd->device->id, + cmd->device->channel + 'A', cmd->device->lun, + SCB_LIST_NULL, ROLE_INITIATOR, + CAM_REQUEUE_REQ, SEARCH_COMPLETE); + ahd_qinfifo_requeue_tail(ahd, pending_scb); + ahd_set_scbptr(ahd, saved_scbptr); + ahd_print_path(ahd, pending_scb); + printf("Device is disconnected, re-queuing SCB\n"); + wait = TRUE; + } else { + printf("%s:%d:%d:%d: Unable to deliver message\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + retval = FAILED; + goto done; + } + +no_cmd: + /* + * Our assumption is that if we don't have the command, no + * recovery action was required, so we return success. Again, + * the semantics of the mid-layer recovery engine are not + * well defined, so this may change in time. + */ + retval = SUCCESS; +done: + if (paused) + ahd_unpause(ahd); + if (wait) { + struct timer_list timer; + int ret; + + ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &s); +#else + spin_unlock_irq(ahd->platform_data->host->host_lock); +#endif + init_timer(&timer); + timer.data = (u_long)ahd; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); + printf("Recovery code sleeping\n"); + down(&ahd->platform_data->eh_sem); + printf("Recovery code awake\n"); + ret = del_timer(&timer); + if (ret == 0) { + printf("Timer Expired\n"); + retval = FAILED; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &s); +#else + spin_lock_irq(ahd->platform_data->host->host_lock); +#endif + } + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + ahd_midlayer_entrypoint_unlock(ahd, &s); + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { + ahd_midlayer_entrypoint_lock(ahd, &s); + ahd_schedule_completeq(ahd, acmd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + } + } + ahd_schedule_runq(ahd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + return (retval); +} + + +static void +ahd_linux_dev_reset_complete(Scsi_Cmnd *cmd) +{ + free(cmd, M_DEVBUF); +} + +/* + * Attempt to send a target reset message to the device that timed out. + */ +static int +ahd_linux_dev_reset(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + struct scsi_cmnd *recovery_cmd; + struct ahd_linux_device *dev; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + struct scb *scb; + struct hardware_scb *hscb; + struct ahd_cmd *acmd; + u_long s; + struct timer_list timer; + int retval; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + memset(recovery_cmd, 0, sizeof(struct scsi_cmnd)); + recovery_cmd->device = cmd->device; + recovery_cmd->scsi_done = ahd_linux_dev_reset_complete; +#if AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s:%d:%d:%d: Device reset called for cmd %p\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun, cmd); +#endif + ahd_midlayer_entrypoint_lock(ahd, &s); + + dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); + if (dev == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); + } + if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); + } + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + cmd->device->id, &tstate); + recovery_cmd->result = CAM_REQ_INPROG << 16; + recovery_cmd->host_scribble = (char *)scb; + scb->io_ctx = recovery_cmd; + scb->platform_data->dev = dev; + scb->sg_count = 0; + ahd_set_residual(scb, 0); + ahd_set_sense_residual(scb, 0); + hscb = scb->hscb; + hscb->control = 0; + hscb->scsiid = BUILD_SCSIID(ahd, cmd); + hscb->lun = cmd->lun; + hscb->cdb_len = 0; + hscb->task_management = SIU_TASKMGMT_LUN_RESET; + scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE; + if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + scb->flags |= SCB_PACKETIZED; + } else { + hscb->control |= MK_MESSAGE; + } + dev->openings--; + dev->active++; + dev->commands_issued++; + LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); + ahd_queue_scb(ahd, scb); + + ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &s); +#else + spin_unlock_irq(ahd->platform_data->host->host_lock); +#endif + init_timer(&timer); + timer.data = (u_long)ahd; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); + printf("Recovery code sleeping\n"); + down(&ahd->platform_data->eh_sem); + printf("Recovery code awake\n"); + retval = SUCCESS; + if (del_timer(&timer) == 0) { + printf("Timer Expired\n"); + retval = FAILED; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &s); +#else + spin_lock_irq(ahd->platform_data->host->host_lock); +#endif + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + ahd_midlayer_entrypoint_unlock(ahd, &s); + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { + ahd_midlayer_entrypoint_lock(ahd, &s); + ahd_schedule_completeq(ahd, acmd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + } + } + ahd_schedule_runq(ahd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); + return (retval); +} + +/* + * Reset the SCSI bus. + */ +static int +ahd_linux_bus_reset(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + struct ahd_cmd *acmd; + u_long s; + int found; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Bus reset called for cmd %p\n", + ahd_name(ahd), cmd); +#endif + ahd_midlayer_entrypoint_lock(ahd, &s); + found = ahd_reset_channel(ahd, cmd->channel + 'A', + /*initiate reset*/TRUE); + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + ahd_midlayer_entrypoint_unlock(ahd, &s); + if (bootverbose) + printf("%s: SCSI bus reset delivered. " + "%d SCBs aborted.\n", ahd_name(ahd), found); + + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { + ahd_midlayer_entrypoint_lock(ahd, &s); + ahd_schedule_completeq(ahd, acmd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + } + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + return (SUCCESS); +} + +Scsi_Host_Template aic79xx_driver_template = { + .proc_info = ahd_linux_proc_info, + .detect = ahd_linux_detect, + .release = ahd_linux_release, + .info = ahd_linux_info, + .queuecommand = ahd_linux_queue, + .eh_abort_handler = ahd_linux_abort, + .eh_device_reset_handler = ahd_linux_dev_reset, + .eh_bus_reset_handler = ahd_linux_bus_reset, +#if defined(__i386__) + .bios_param = ahd_linux_biosparam, +#endif + .can_queue = AHD_MAX_QUEUE, + .this_id = -1, + .sg_tablesize = AHD_NSEG, + .cmd_per_lun = 2, + .use_clustering = ENABLE_CLUSTERING, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) + /* + * We can only map 16MB per-SG + * so create a sector limit of + * "16MB" in 2K sectors. + */ + .max_sectors = 8192, +#endif +#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) +/* Assume RedHat Distribution with its different HIGHIO conventions. */ + .can_dma_32 = 1, + .single_sg_okay = 1, +#else + .highmem_io = 1, +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + .name = "aic79xx", + .slave_alloc = ahd_linux_slave_alloc, + .slave_configure = ahd_linux_slave_configure, + .slave_destroy = ahd_linux_slave_destroy, +#else + .select_queue_depths = ahd_linux_select_queue_depth, + .use_new_eh_code = 1, +#endif +}; + +#define driver_template aic79xx_driver_template +#include "scsi_module.c" +/**************************** Tasklet Handler *********************************/ + +static void +ahd_runq_tasklet(unsigned long data) +{ + struct ahd_softc* ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = (struct ahd_softc *)data; + ahd_lock(ahd, &flags); + while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { + + TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); + dev->flags &= ~AHD_DEV_ON_RUN_LIST; + ahd_linux_check_device_queue(ahd, dev); + /* Yeild to our interrupt handler */ + ahd_unlock(ahd, &flags); + ahd_lock(ahd, &flags); + } + ahd_unlock(ahd, &flags); +} + +/************************ Shutdown/halt/reboot hook ***************************/ +#include +#include + +static struct notifier_block ahd_linux_notifier = { + ahd_linux_halt, NULL, 0 +}; + +static int ahd_linux_halt(struct notifier_block *nb, u_long event, void *buf) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + struct ahd_softc *ahd; + + /* + * In 2.5.X, this is called prior to the filesystems + * being synced and the SCSI layer being properly + * shutdown. A different API is required there, + * but the device hooks for this don't quite look + * right. + */ + if (event == SYS_DOWN || event == SYS_HALT) { + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + ahd_shutdown(ahd); + } + } +#endif + return (NOTIFY_OK); +} + +/******************************** Bus DMA *************************************/ +int +ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, + bus_size_t alignment, bus_size_t boundary, + bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, + bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) +{ + bus_dma_tag_t dmat; + + dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); + if (dmat == NULL) + return (ENOMEM); + + /* + * Linux is very simplistic about DMA memory. For now don't + * maintain all specification information. Once Linux supplies + * better facilities for doing these operations, or the + * needs of this particular driver change, we might need to do + * more here. + */ + dmat->alignment = alignment; + dmat->boundary = boundary; + dmat->maxsize = maxsize; + *ret_tag = dmat; + return (0); +} + +void +ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat) +{ + free(dmat, M_DEVBUF); +} + +int +ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr, + int flags, bus_dmamap_t *mapp) +{ + bus_dmamap_t map; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); + if (map == NULL) + return (ENOMEM); + /* + * Although we can dma data above 4GB, our + * "consistent" memory is below 4GB for + * space efficiency reasons (only need a 4byte + * address). For this reason, we have to reset + * our dma mask when doing allocations. + */ + if (ahd->dev_softc != NULL) + ahd_pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF); + *vaddr = pci_alloc_consistent(ahd->dev_softc, + dmat->maxsize, &map->bus_addr); + if (ahd->dev_softc != NULL) + ahd_pci_set_dma_mask(ahd->dev_softc, + ahd->platform_data->hw_dma_mask); +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + /* + * At least in 2.2.14, malloc is a slab allocator so all + * allocations are aligned. We assume for these kernel versions + * that all allocations will be bellow 4Gig, physically contiguous, + * and accessable via DMA by the controller. + */ + map = NULL; /* No additional information to store */ + *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); +#endif + if (*vaddr == NULL) + return (ENOMEM); + *mapp = map; + return(0); +} + +void +ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat, + void* vaddr, bus_dmamap_t map) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + pci_free_consistent(ahd->dev_softc, dmat->maxsize, + vaddr, map->bus_addr); +#else + free(vaddr, M_DEVBUF); +#endif +} + +int +ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map, + void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, + void *cb_arg, int flags) +{ + /* + * Assume for now that this will only be used during + * initialization and not for per-transaction buffer mapping. + */ + bus_dma_segment_t stack_sg; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + stack_sg.ds_addr = map->bus_addr; +#else +#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) + stack_sg.ds_addr = VIRT_TO_BUS(buf); +#endif + stack_sg.ds_len = dmat->maxsize; + cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); + return (0); +} + +void +ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* + * The map may is NULL in our < 2.3.X implementation. + */ + if (map != NULL) + free(map, M_DEVBUF); +} + +int +ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* Nothing to do */ + return (0); +} + +/********************* Platform Dependent Functions ***************************/ +int +ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd) +{ + int value; + char primary_channel; + + /* + * Under Linux, cards are ordered as follows: + * 1) PCI devices with BIOS enabled sorted by bus/slot/func. + * 2) All remaining PCI devices sorted by bus/slot/func. + */ + value = (lahd->flags & AHD_BIOS_ENABLED) + - (rahd->flags & AHD_BIOS_ENABLED); + if (value != 0) + /* Controllers with BIOS enabled have a *higher* priority */ + return (-value); + + /* Still equal. Sort by bus/slot/func. */ + if (aic79xx_reverse_scan != 0) + value = ahd_get_pci_bus(rahd->dev_softc) + - ahd_get_pci_bus(lahd->dev_softc); + else + value = ahd_get_pci_bus(lahd->dev_softc) + - ahd_get_pci_bus(rahd->dev_softc); + if (value != 0) + return (value); + if (aic79xx_reverse_scan != 0) + value = ahd_get_pci_slot(rahd->dev_softc) + - ahd_get_pci_slot(lahd->dev_softc); + else + value = ahd_get_pci_slot(lahd->dev_softc) + - ahd_get_pci_slot(rahd->dev_softc); + if (value != 0) + return (value); + + /* + * On multi-function devices, the user can choose + * to have function 1 probed before function 0. + * Give whichever channel is the primary channel + * the lowest priority. + */ + primary_channel = (lahd->flags & AHD_PRIMARY_CHANNEL) + 'A'; + value = 1; + if (lahd->channel == primary_channel) + value = -1; + return (value); +} + +static void +ahd_linux_setup_tag_info(char *p, char *end, char *s) +{ + char *base; + char *tok; + char *tok_end; + char *tok_end2; + int i; + int instance; + int targ; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + if (*p != ':') + return; + + instance = -1; + targ = -1; + done = FALSE; + base = p; + /* Forward us just past the ':' */ + tok = base + 1; + tok_end = strchr(tok, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*tok) { + case '{': + if (instance == -1) + instance = 0; + else if (targ == -1) + targ = 0; + tok++; + break; + case '}': + if (targ != -1) + targ = -1; + else if (instance != -1) + instance = -1; + tok++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (targ >= 0) + targ++; + else if (instance >= 0) + instance++; + if ((targ >= AHD_NUM_TARGETS) || + (instance >= NUM_ELEMENTS(aic79xx_tag_info))) + done = TRUE; + tok++; + if (!done) { + base = tok; + } + break; + case '\0': + done = TRUE; + break; + default: + done = TRUE; + tok_end = strchr(tok, '\0'); + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(tok, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) { + tok_end = tok_end2; + done = FALSE; + } + } + if ((instance >= 0) && (targ >= 0) + && (instance < NUM_ELEMENTS(aic79xx_tag_info)) + && (targ < AHD_NUM_TARGETS)) { + aic79xx_tag_info[instance].tag_commands[targ] = + simple_strtoul(tok, NULL, 0) & 0xff; + } + tok = tok_end; + break; + } + } + while ((p != base) && (p != NULL)) + p = strsep(&s, ",."); +} + +static void +ahd_linux_setup_rd_strm_info(char *p, char *end, char *s) +{ + char *base; + char *tok; + char *tok_end; + char *tok_end2; + int i; + int instance; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + if (*p != ':') + return; + + instance = -1; + done = FALSE; + base = p; + /* Forward us just past the ':' */ + tok = base + 1; + tok_end = strchr(tok, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*tok) { + case '{': + if (instance == -1) + instance = 0; + tok++; + break; + case '}': + if (instance != -1) + instance = -1; + tok++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (instance >= 0) + instance++; + if (instance >= NUM_ELEMENTS(aic79xx_rd_strm_info)) + done = TRUE; + tok++; + if (!done) { + base = tok; + } + break; + case '\0': + done = TRUE; + break; + default: + done = TRUE; + tok_end = strchr(tok, '\0'); + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(tok, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) { + tok_end = tok_end2; + done = FALSE; + } + } + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic79xx_rd_strm_info))) { + aic79xx_rd_strm_info[instance] = + simple_strtoul(tok, NULL, 0) & 0xffff; + } + tok = tok_end; + break; + } + } + while ((p != base) && (p != NULL)) + p = strsep(&s, ",."); +} + +static void +ahd_linux_setup_dv(char *p, char *end, char *s) +{ + char *base; + char *tok; + char *tok_end; + char *tok_end2; + int i; + int instance; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + if (*p != ':') + return; + + instance = -1; + done = FALSE; + base = p; + /* Forward us just past the ':' */ + tok = base + 1; + tok_end = strchr(tok, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*tok) { + case '{': + if (instance == -1) + instance = 0; + tok++; + break; + case '}': + if (instance != -1) + instance = -1; + tok++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (instance >= 0) + instance++; + if (instance >= NUM_ELEMENTS(aic79xx_dv_settings)) + done = TRUE; + tok++; + if (!done) { + base = tok; + } + break; + case '\0': + done = TRUE; + break; + default: + done = TRUE; + tok_end = strchr(tok, '\0'); + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(tok, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) { + tok_end = tok_end2; + done = FALSE; + } + } + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic79xx_dv_settings))) { + aic79xx_dv_settings[instance] = + simple_strtol(tok, NULL, 0); + } + tok = tok_end; + break; + } + } + while ((p != base) && (p != NULL)) + p = strsep(&s, ",."); +} + +static void +ahd_linux_setup_iocell_info(char *p, char *end, char *s, int index) +{ + char *base; + char *tok; + char *tok_end; + char *tok_end2; + uint8_t *iocell_info; + int i; + int instance; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + if (*p != ':') + return; + + instance = -1; + done = FALSE; + base = p; + /* Forward us just past the ':' */ + tok = base + 1; + tok_end = strchr(tok, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*tok) { + case '{': + if (instance == -1) + instance = 0; + tok++; + break; + case '}': + if (instance != -1) + instance = -1; + tok++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (instance >= 0) + instance++; + if (instance >= NUM_ELEMENTS(aic79xx_iocell_info)) + done = TRUE; + tok++; + if (!done) { + base = tok; + } + break; + case '\0': + done = TRUE; + break; + default: + done = TRUE; + tok_end = strchr(tok, '\0'); + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(tok, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) { + tok_end = tok_end2; + done = FALSE; + } + } + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic79xx_iocell_info))) { + iocell_info = + (uint8_t*)&aic79xx_iocell_info[instance]; + iocell_info[index] = + simple_strtoul(tok, NULL, 0) & 0xffff; + } + tok = tok_end; + break; + } + } + while ((p != base) && (p != NULL)) + p = strsep(&s, ",."); +} + +static void +ahd_linux_setup_tag_info_global(char *p) +{ + int tags, i, j; + + tags = simple_strtoul(p + 1, NULL, 0) & 0xff; + printf("Setting Global Tags= %d\n", tags); + + for (i = 0; i < NUM_ELEMENTS(aic79xx_tag_info); i++) { + for (j = 0; j < AHD_NUM_TARGETS; j++) { + aic79xx_tag_info[i].tag_commands[j] = tags; + } + } +} + +/* + * Handle Linux boot parameters. This routine allows for assigning a value + * to a parameter with a ':' between the parameter and the value. + * ie. aic79xx=stpwlev:1,extended + */ +static int +aic79xx_setup(char *s) +{ + int i, n; + char *p; + char *end; + + static struct { + const char *name; + uint32_t *flag; + } options[] = { + { "extended", &aic79xx_extended }, + { "no_reset", &aic79xx_no_reset }, + { "verbose", &aic79xx_verbose }, + { "allow_memio", &aic79xx_allow_memio}, +#ifdef AHD_DEBUG + { "debug", &ahd_debug }, +#endif + { "reverse_scan", &aic79xx_reverse_scan }, + { "periodic_otag", &aic79xx_periodic_otag }, + { "pci_parity", &aic79xx_pci_parity }, + { "seltime", &aic79xx_seltime }, + { "tag_info", NULL }, + { "global_tag_depth", NULL}, + { "rd_strm", NULL }, + { "dv", NULL }, + { "slewrate", NULL }, + { "precomp", NULL }, + { "amplitude", NULL }, + }; + + end = strchr(s, '\0'); + + while ((p = strsep(&s, ",.")) != NULL) { + if (*p == '\0') + continue; + for (i = 0; i < NUM_ELEMENTS(options); i++) { + n = strlen(options[i].name); + + if (strncmp(options[i].name, p, n) != 0) + continue; + + if (!strncmp(p, "global_tag_depth", n)) { + ahd_linux_setup_tag_info_global(p + n); + } else if (!strncmp(p, "tag_info", n)) { + ahd_linux_setup_tag_info(p + n, end, s); + } else if (strncmp(p, "rd_strm", n) == 0) { + ahd_linux_setup_rd_strm_info(p + n, end, s); + } else if (strncmp(p, "dv", n) == 0) { + ahd_linux_setup_dv(p + n, end, s); + } else if (strncmp(p, "slewrate", n) == 0) { + ahd_linux_setup_iocell_info(p + n, end, s, + AIC79XX_SLEWRATE_INDEX); + } else if (strncmp(p, "precomp", n) == 0) { + ahd_linux_setup_iocell_info(p + n, end, s, + AIC79XX_PRECOMP_INDEX); + } else if (strncmp(p, "amplitude", n) == 0) { + ahd_linux_setup_iocell_info(p + n, end, s, + AIC79XX_AMPLITUDE_INDEX); + } else if (p[n] == ':') { + *(options[i].flag) = + simple_strtoul(p + n + 1, NULL, 0); + } else if (!strncmp(p, "verbose", n)) { + *(options[i].flag) = 1; + } else { + *(options[i].flag) = ~(*(options[i].flag)); + } + break; + } + } + return 1; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) +__setup("aic79xx=", aic79xx_setup); +#endif + +int aic79xx_verbose; + +int +ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) +{ + char buf[80]; + struct Scsi_Host *host; + char *new_name; + u_long s; + u_long target; + + template->name = ahd->description; + host = scsi_register(template, sizeof(struct ahd_softc *)); + if (host == NULL) + return (ENOMEM); + + *((struct ahd_softc **)host->hostdata) = ahd; + ahd_lock(ahd, &s); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_assign_lock(host, &ahd->platform_data->spin_lock); +#endif + ahd->platform_data->host = host; + host->can_queue = AHD_MAX_QUEUE; + host->cmd_per_lun = 2; + host->sg_tablesize = AHD_NSEG; + host->this_id = ahd->our_id; + host->irq = ahd->platform_data->irq; + host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8; + host->max_lun = AHD_NUM_LUNS; + host->max_channel = 0; + ahd_set_unit(ahd, ahd_linux_next_unit()); + sprintf(buf, "scsi%d", host->host_no); + new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (new_name != NULL) { + strcpy(new_name, buf); + ahd_set_name(ahd, new_name); + } + host->unique_id = ahd->unit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) + scsi_set_pci_device(host, ahd->dev_softc); +#endif + ahd_linux_initialize_scsi_bus(ahd); + ahd_unlock(ahd, &s); + ahd->platform_data->dv_pid = kernel_thread(ahd_linux_dv_thread, ahd, 0); + ahd_lock(ahd, &s); + if (ahd->platform_data->dv_pid < 0) { + printf("%s: Failed to create DV thread, error= %d\n", + ahd_name(ahd), ahd->platform_data->dv_pid); + return (-ahd->platform_data->dv_pid); + } + /* + * Initially allocate *all* of our linux target objects + * so that the DV thread will scan them all in parallel + * just after driver initialization. Any device that + * does not exist will have its target object destroyed + * by the selection timeout handler. In the case of a + * device that appears after the initial DV scan, async + * negotiation will occur for the first command, and DV + * will comence should that first command be successful. + */ + for (target = 0; target < host->max_id; target++) + ahd_linux_alloc_target(ahd, 0, target); + ahd_intr_enable(ahd, TRUE); + ahd_linux_start_dv(ahd); + ahd_unlock(ahd, &s); + return (0); +} + +uint64_t +ahd_linux_get_memsize() +{ + struct sysinfo si; + + si_meminfo(&si); + return ((uint64_t)si.totalram << PAGE_SHIFT); +} + +/* + * Find the smallest available unit number to use + * for a new device. We don't just use a static + * count to handle the "repeated hot-(un)plug" + * scenario. + */ +static int +ahd_linux_next_unit() +{ + struct ahd_softc *ahd; + int unit; + + unit = 0; +retry: + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + if (ahd->unit == unit) { + unit++; + goto retry; + } + } + return (unit); +} + +/* + * Place the SCSI bus into a known state by either resetting it, + * or forcing transfer negotiations on the next command to any + * target. + */ +static void +ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) +{ + u_int target_id; + u_int numtarg; + + target_id = 0; + numtarg = 0; + + if (aic79xx_no_reset != 0) + ahd->flags &= ~AHD_RESET_BUS_A; + + if ((ahd->flags & AHD_RESET_BUS_A) != 0) + ahd_reset_channel(ahd, 'A', /*initiate_reset*/TRUE); + else + numtarg = (ahd->features & AHD_WIDE) ? 16 : 8; + + /* + * Force negotiation to async for all targets that + * will not see an initial bus reset. + */ + for (; target_id < numtarg; target_id++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + target_id, &tstate); + ahd_compile_devinfo(&devinfo, ahd->our_id, target_id, + CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR); + ahd_update_neg_request(ahd, &devinfo, tstate, + tinfo, AHD_NEG_ALWAYS); + } + /* Give the bus some time to recover */ + if ((ahd->flags & AHD_RESET_BUS_A) != 0) { + ahd_freeze_simq(ahd); + init_timer(&ahd->platform_data->reset_timer); + ahd->platform_data->reset_timer.data = (u_long)ahd; + ahd->platform_data->reset_timer.expires = + jiffies + (AIC79XX_RESET_DELAY * HZ)/1000; + ahd->platform_data->reset_timer.function = + (ahd_linux_callback_t *)ahd_release_simq; + add_timer(&ahd->platform_data->reset_timer); + } +} + +int +ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) +{ + ahd->platform_data = + malloc(sizeof(struct ahd_platform_data), M_DEVBUF, M_NOWAIT); + if (ahd->platform_data == NULL) + return (ENOMEM); + memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); + TAILQ_INIT(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->device_runq); + ahd->platform_data->irq = AHD_LINUX_NOIRQ; + ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; + ahd_lockinit(ahd); + ahd_done_lockinit(ahd); + init_timer(&ahd->platform_data->completeq_timer); + ahd->platform_data->completeq_timer.data = (u_long)ahd; + ahd->platform_data->completeq_timer.function = + (ahd_linux_callback_t *)ahd_linux_thread_run_complete_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); + init_MUTEX_LOCKED(&ahd->platform_data->dv_sem); + init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem); +#else + ahd->platform_data->eh_sem = MUTEX_LOCKED; + ahd->platform_data->dv_sem = MUTEX_LOCKED; + ahd->platform_data->dv_cmd_sem = MUTEX_LOCKED; +#endif + ahd_setup_runq_tasklet(ahd); + ahd->seltime = (aic79xx_seltime & 0x3) << 4; + if (TAILQ_EMPTY(&ahd_tailq)) + register_reboot_notifier(&ahd_linux_notifier); + return (0); +} + +void +ahd_platform_free(struct ahd_softc *ahd) +{ + struct ahd_linux_target *targ; + struct ahd_linux_device *dev; + u_long s; + int i, j; + + if (ahd->platform_data != NULL) { + /* Kill the DV kthread */ + if (ahd->platform_data->dv_pid != 0) { + ahd_lock(ahd, &s); + ahd->platform_data->flags |= AHD_DV_SHUTDOWN; + ahd_unlock(ahd, &s); + up(&ahd->platform_data->dv_sem); + do { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + printf("%s: Waiting for DV thread to " + "exit\n", ahd_name(ahd)); + } +#endif + } while (waitpid(ahd->platform_data->dv_pid, NULL, + __WCLONE) == -ERESTARTSYS); + } + ahd_teardown_runq_tasklet(ahd); + if (ahd->platform_data->host != NULL) + scsi_unregister(ahd->platform_data->host); + + /* destroy all of the device and target objects */ + for (i = 0; i < AHD_NUM_TARGETS; i++) { + targ = ahd->platform_data->targets[i]; + if (targ != NULL) { + for (j = 0; j < AHD_NUM_LUNS; j++) { + if (targ->devices[j] != NULL) { + dev = targ->devices[j]; + ahd_linux_free_device(ahd, dev); + } + if (ahd->platform_data->targets[i] == + NULL) + break; + } + } + } + + if (ahd->platform_data->irq != AHD_LINUX_NOIRQ) + free_irq(ahd->platform_data->irq, ahd); + if (ahd->tags[0] == BUS_SPACE_PIO + && ahd->bshs[0].ioport != 0) + release_region(ahd->bshs[0].ioport, 256); + if (ahd->tags[1] == BUS_SPACE_PIO + && ahd->bshs[1].ioport != 0) + release_region(ahd->bshs[1].ioport, 256); + if (ahd->tags[0] == BUS_SPACE_MEMIO + && ahd->bshs[0].maddr != NULL) { + u_long base_addr; + + base_addr = (u_long)ahd->bshs[0].maddr; + base_addr &= PAGE_MASK; + iounmap((void *)base_addr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(ahd->platform_data->mem_busaddr, + 0x1000); +#endif + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + /* XXX Need an instance detach in the PCI code */ + if (ahd->dev_softc != NULL) + ahd->dev_softc->driver = NULL; +#endif + free(ahd->platform_data, M_DEVBUF); + } + if (TAILQ_EMPTY(&ahd_tailq)) { + unregister_reboot_notifier(&ahd_linux_notifier); +#ifdef CONFIG_PCI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pci_unregister_driver(&aic79xx_pci_driver); +#endif +#endif + } +} + +void +ahd_platform_init(struct ahd_softc *ahd) +{ + /* + * Lookup and commit any modified IO Cell options. + */ + if (ahd->unit < NUM_ELEMENTS(aic79xx_iocell_info)) { + struct ahd_linux_iocell_opts *iocell_opts; + + iocell_opts = &aic79xx_iocell_info[ahd->unit]; + if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP) + AHD_SET_PRECOMP(ahd, iocell_opts->precomp); + if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE) + AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate); + if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE) + AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude); + } + +} + +void +ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb) +{ + ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_LIST_NULL, + ROLE_UNKNOWN, CAM_REQUEUE_REQ); +} + +void +ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + ahd_queue_alg alg) +{ + struct ahd_linux_device *dev; + int was_queuing; + int now_queuing; + + dev = ahd_linux_get_device(ahd, devinfo->channel - 'A', + devinfo->target, + devinfo->lun, /*alloc*/FALSE); + if (dev == NULL) + return; + was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED); + now_queuing = alg != AHD_QUEUE_NONE; + if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0 + && (was_queuing != now_queuing) + && (dev->active != 0)) { + dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY; + dev->qfrozen++; + } + + dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG); + if (now_queuing) { + u_int usertags; + + usertags = ahd_linux_user_tagdepth(ahd, devinfo); + if (!was_queuing) { + /* + * Start out agressively and allow our + * dynamic queue depth algorithm to take + * care of the rest. + */ + dev->maxtags = usertags; + dev->openings = dev->maxtags - dev->active; + } + if (dev->maxtags == 0) { + /* + * Queueing is disabled by the user. + */ + dev->openings = 1; + } else if (alg == AHD_QUEUE_TAGGED) { + dev->flags |= AHD_DEV_Q_TAGGED; + if (aic79xx_periodic_otag != 0) + dev->flags |= AHD_DEV_PERIODIC_OTAG; + } else + dev->flags |= AHD_DEV_Q_BASIC; + } else { + /* We can only have one opening. */ + dev->maxtags = 0; + dev->openings = 1 - dev->active; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (dev->scsi_device != NULL) { + switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { + case AHD_DEV_Q_BASIC: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_SIMPLE_TASK, + dev->openings + dev->active); + break; + case AHD_DEV_Q_TAGGED: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_ORDERED_TASK, + dev->openings + dev->active); + break; + default: + /* + * We allow the OS to queue 2 untagged transactions to + * us at any time even though we can only execute them + * serially on the controller/device. This should + * remove some latency. + */ + scsi_adjust_queue_depth(dev->scsi_device, + /*NON-TAGGED*/0, + /*queue depth*/2); + break; + } + } +#endif +} + +int +ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status) +{ + int targ; + int maxtarg; + int maxlun; + int clun; + int count; + + if (tag != SCB_LIST_NULL) + return (0); + + targ = 0; + if (target != CAM_TARGET_WILDCARD) { + targ = target; + maxtarg = targ + 1; + } else { + maxtarg = (ahd->features & AHD_WIDE) ? 16 : 8; + } + clun = 0; + if (lun != CAM_LUN_WILDCARD) { + clun = lun; + maxlun = clun + 1; + } else { + maxlun = AHD_NUM_LUNS; + } + + count = 0; + for (; targ < maxtarg; targ++) { + + for (; clun < maxlun; clun++) { + struct ahd_linux_device *dev; + struct ahd_busyq *busyq; + struct ahd_cmd *acmd; + + dev = ahd_linux_get_device(ahd, /*chan*/0, targ, + clun, /*alloc*/FALSE); + if (dev == NULL) + continue; + + busyq = &dev->busyq; + while ((acmd = TAILQ_FIRST(busyq)) != NULL) { + Scsi_Cmnd *cmd; + + cmd = &acmd_scsi_cmd(acmd); + TAILQ_REMOVE(busyq, acmd, + acmd_links.tqe); + count++; + cmd->result = status << 16; + ahd_linux_queue_cmd_complete(ahd, cmd); + } + } + } + + return (count); +} + +static void +ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd) +{ + struct ahd_cmd *acmd; + u_long flags; + + ahd_lock(ahd, &flags); + del_timer(&ahd->platform_data->completeq_timer); + ahd->platform_data->flags &= ~AHD_RUN_CMPLT_Q_TIMER; + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &flags); +#endif + ahd_schedule_completeq(ahd, acmd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif + } + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif +} + +static void +ahd_linux_start_dv(struct ahd_softc *ahd) +{ + + /* + * Freeze the simq and signal ahd_linux_queue to not let any + * more commands through + */ + if ((ahd->platform_data->flags & AHD_DV_ACTIVE) == 0) { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s: Starting DV\n", ahd_name(ahd)); +#endif + + ahd->platform_data->flags |= AHD_DV_ACTIVE; + ahd_freeze_simq(ahd); + + /* Wake up the DV kthread */ + up(&ahd->platform_data->dv_sem); + } +} + +static int +ahd_linux_dv_thread(void *data) +{ + struct ahd_softc *ahd; + int target; + u_long s; + + ahd = (struct ahd_softc *)data; + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("In DV Thread\n"); +#endif + + /* + * Don't care about any signals. + */ + siginitsetinv(¤t->blocked, 0); + + /* + * Complete thread creation. + */ + lock_kernel(); + daemonize(); + sprintf(current->comm, "ahd_dv_%d", ahd->unit); + unlock_kernel(); + + while (1) { + /* + * Use down_interruptible() rather than down() to + * avoid inclusion in the load average. + */ + down_interruptible(&ahd->platform_data->dv_sem); + + /* Check to see if we've been signaled to exit */ + ahd_lock(ahd, &s); + if ((ahd->platform_data->flags & AHD_DV_SHUTDOWN) != 0) { + ahd_unlock(ahd, &s); + return (0); + } + ahd_unlock(ahd, &s); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s: Beginning Domain Validation\n", + ahd_name(ahd)); +#endif + + /* + * Wait for any pending commands to drain before proceeding. + */ + ahd_lock(ahd, &s); + while (LIST_FIRST(&ahd->pending_scbs) != NULL) { + ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_EMPTY; + ahd_unlock(ahd, &s); + down_interruptible(&ahd->platform_data->dv_sem); + ahd_lock(ahd, &s); + } + + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + while (AHD_DV_SIMQ_FROZEN(ahd) == 0) { + ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE; + ahd_unlock(ahd, &s); + down_interruptible(&ahd->platform_data->dv_sem); + ahd_lock(ahd, &s); + } + ahd_unlock(ahd, &s); + + for (target = 0; target < AHD_NUM_TARGETS; target++) + ahd_linux_dv_target(ahd, target); + + ahd_lock(ahd, &s); + ahd->platform_data->flags &= ~AHD_DV_ACTIVE; + ahd_unlock(ahd, &s); + + /* + * Release the SIMQ so that normal commands are + * allowed to continue on the bus. + */ + ahd_release_simq(ahd); + } + + return (0); +} + +#define AHD_LINUX_DV_INQ_SHORT_LEN 36 +#define AHD_LINUX_DV_INQ_LEN 256 +#define AHD_LINUX_DV_TIMEOUT (HZ / 4) + +#define AHD_SET_DV_STATE(ahd, targ, newstate) \ + ahd_set_dv_state(ahd, targ, newstate, __LINE__) + +static __inline void +ahd_set_dv_state(struct ahd_softc *ahd, struct ahd_linux_target *targ, + ahd_dv_state newstate, u_int line) +{ + ahd_dv_state oldstate; + + oldstate = targ->dv_state; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s:%d: Going from state %d to state %d\n", + ahd_name(ahd), line, oldstate, newstate); +#endif + + if (oldstate == newstate) + targ->dv_state_retry++; + else + targ->dv_state_retry = 0; + targ->dv_state = newstate; +} + +static void +ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset) +{ + struct ahd_devinfo devinfo; + struct ahd_linux_target *targ; + struct scsi_cmnd *cmd; + struct scsi_device *scsi_dev; + struct scsi_sense_data *sense; + uint8_t *buffer; + u_long s; + u_int timeout; + int echo_size; + + sense = NULL; + buffer = NULL; + echo_size = 0; + ahd_lock(ahd, &s); + targ = ahd->platform_data->targets[target_offset]; + if (targ == NULL || (targ->flags & AHD_DV_REQUIRED) == 0) { + ahd_unlock(ahd, &s); + return; + } + ahd_compile_devinfo(&devinfo, ahd->our_id, targ->target, /*lun*/0, + targ->channel + 'A', ROLE_INITIATOR); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, &devinfo); + printf("Performing DV\n"); + } +#endif + + ahd_unlock(ahd, &s); + + cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); + scsi_dev->host = ahd->platform_data->host; + scsi_dev->id = devinfo.target; + scsi_dev->lun = devinfo.lun; + scsi_dev->channel = devinfo.channel - 'A'; + ahd->platform_data->dv_scsi_dev = scsi_dev; + + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC); + + while (targ->dv_state != AHD_DV_STATE_EXIT) { + timeout = AHD_LINUX_DV_TIMEOUT; + switch (targ->dv_state) { + case AHD_DV_STATE_INQ_SHORT_ASYNC: + case AHD_DV_STATE_INQ_ASYNC: + case AHD_DV_STATE_INQ_ASYNC_VERIFY: + /* + * Set things to async narrow to reduce the + * chance that the INQ will fail. + */ + ahd_lock(ahd, &s); + ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_unlock(ahd, &s); + timeout = 10 * HZ; + targ->flags &= ~AHD_INQ_VALID; + /* FALLTHROUGH */ + case AHD_DV_STATE_INQ_VERIFY: + { + u_int inq_len; + + if (targ->dv_state == AHD_DV_STATE_INQ_SHORT_ASYNC) + inq_len = AHD_LINUX_DV_INQ_SHORT_LEN; + else + inq_len = targ->inq_data->additional_length + 5; + ahd_linux_dv_inq(ahd, cmd, &devinfo, targ, inq_len); + break; + } + case AHD_DV_STATE_TUR: + case AHD_DV_STATE_BUSY: + ahd_linux_dv_tur(ahd, cmd, &devinfo); + break; + case AHD_DV_STATE_REBD: + ahd_linux_dv_rebd(ahd, cmd, &devinfo, targ); + break; + case AHD_DV_STATE_WEB: + ahd_linux_dv_web(ahd, cmd, &devinfo, targ); + break; + + case AHD_DV_STATE_REB: + ahd_linux_dv_reb(ahd, cmd, &devinfo, targ); + break; + + case AHD_DV_STATE_SU: + ahd_linux_dv_su(ahd, cmd, &devinfo, targ); + timeout = 50 * HZ; + break; + + default: + ahd_print_devinfo(ahd, &devinfo); + printf("Unknown DV state %d\n", targ->dv_state); + goto out; + } + + /* Queue the command and wait for it to complete */ + /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */ + init_timer(&cmd->eh_timeout); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + /* + * All of the printfs during negotiation + * really slow down the negotiation. + * Add a bit of time just to be safe. + */ + timeout += HZ; +#endif + scsi_add_timer(cmd, timeout, ahd_linux_dv_timeout); + /* + * In 2.5.X, it is assumed that all calls from the + * "midlayer" (which we are emulating) will have the + * ahd host lock held. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &s); +#endif + ahd_linux_queue(cmd, ahd_linux_dv_complete); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &s); +#endif + down_interruptible(&ahd->platform_data->dv_cmd_sem); + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + ahd_lock(ahd, &s); + while (AHD_DV_SIMQ_FROZEN(ahd) == 0) { + ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE; + ahd_unlock(ahd, &s); + down_interruptible(&ahd->platform_data->dv_sem); + ahd_lock(ahd, &s); + } + ahd_unlock(ahd, &s); + + ahd_linux_dv_transition(ahd, cmd, &devinfo, targ); + } + +out: + if ((targ->flags & AHD_INQ_VALID) != 0 + && ahd_linux_get_device(ahd, devinfo.channel - 'A', + devinfo.target, devinfo.lun, + /*alloc*/FALSE) == NULL) { + /* + * The DV state machine failed to configure this device. + * This is normal if DV is disabled. Since we have inquiry + * data, filter it and use the "optimistic" negotiation + * parameters found in the inquiry string. + */ + ahd_linux_filter_inquiry(ahd, &devinfo); + if ((targ->flags & (AHD_BASIC_DV|AHD_ENHANCED_DV)) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("DV failed to configure device. " + "Please file a bug report against " + "this driver.\n"); + } + } + + if (cmd != NULL) + free(cmd, M_DEVBUF); + + if (ahd->platform_data->dv_scsi_dev != NULL) { + free(ahd->platform_data->dv_scsi_dev, M_DEVBUF); + ahd->platform_data->dv_scsi_dev = NULL; + } + + ahd_lock(ahd, &s); + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + targ->flags &= ~AHD_DV_REQUIRED; + if (targ->refcount == 0) + ahd_linux_free_target(ahd, targ); + ahd_unlock(ahd, &s); +} + +static void +ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ) +{ + cam_status cam_status; + u_int32_t status; + u_int scsi_status; + + scsi_status = ahd_cmd_get_scsi_status(cmd); + cam_status = ahd_cmd_get_transaction_status(cmd); + status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status); + + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Entering ahd_linux_dv_transition, state= %d, " + "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state, + status, cmd->result); + } +#endif + + switch (targ->dv_state) { + case AHD_DV_STATE_INQ_SHORT_ASYNC: + case AHD_DV_STATE_INQ_ASYNC: + switch (status & SS_MASK) { + case SS_NOP: + { + AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1); + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if ((status & SS_ERRMASK) == EBUSY) + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHD_DV_STATE_INQ_ASYNC_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + u_int xportflags; + u_int spi3data; + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHD_LINUX_DV_INQ_LEN) != 0) { + /* + * Inquiry data must have changed. + * Try from the top again. + */ + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + } + + AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1); + targ->flags |= AHD_INQ_VALID; + if (ahd_linux_user_dv_setting(ahd) == 0) + break; + + xportflags = targ->inq_data->flags; + if ((xportflags & (SID_Sync|SID_WBus16)) == 0) + break; + + spi3data = targ->inq_data->spi3data; + switch (spi3data & SID_SPI_CLOCK_DT_ST) { + default: + case SID_SPI_CLOCK_ST: + /* Assume only basic DV is supported. */ + targ->flags |= AHD_BASIC_DV; + break; + case SID_SPI_CLOCK_DT: + case SID_SPI_CLOCK_DT_ST: + targ->flags |= AHD_ENHANCED_DV; + break; + } + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + + if ((status & SS_ERRMASK) == EBUSY) + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHD_DV_STATE_INQ_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHD_LINUX_DV_INQ_LEN) == 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + int i; + + ahd_print_devinfo(ahd, devinfo); + printf("Inquiry buffer mismatch:"); + for (i = 0; i < AHD_LINUX_DV_INQ_LEN; i++) { + if ((i & 0xF) == 0) + printf("\n "); + printf("0x%x:0x0%x ", + ((uint8_t *)targ->inq_data)[i], + targ->dv_buffer[i]); + } + printf("\n"); + } +#endif + + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } else if ((status & SS_ERRMASK) == EBUSY) + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + + case AHD_DV_STATE_TUR: + switch (status & SS_MASK) { + case SS_NOP: + if ((targ->flags & AHD_BASIC_DV) != 0) { + ahd_linux_filter_inquiry(ahd, devinfo); + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_VERIFY); + } else if ((targ->flags & AHD_ENHANCED_DV) != 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REBD); + } else { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + } + break; + case SS_RETRY: + case SS_TUR: + if ((status & SS_ERRMASK) == EBUSY) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + break; + } + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry >= 10) { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV TUR reties exhausted\n"); + } +#endif + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + if (status & SSQ_DELAY) + scsi_sleep(1 * HZ); + + break; + case SS_START: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_SU); + break; + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_REBD: + switch (status & SS_MASK) { + case SS_NOP: + { + uint32_t echo_size; + + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB); + echo_size = scsi_3btoul(&targ->dv_buffer[1]); + echo_size &= 0x1FFF; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Echo buffer size= %d\n", echo_size); + } +#endif + if (echo_size == 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + + /* Generate the buffer pattern */ + targ->dv_echo_size = echo_size; + ahd_linux_generate_dv_pattern(targ); + /* + * Setup initial negotiation values. + */ + ahd_linux_filter_inquiry(ahd, devinfo); + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if (targ->dv_state_retry <= 10) + break; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV REBD reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + case SS_FATAL: + default: + /* + * Setup initial negotiation values + * and try level 1 DV. + */ + ahd_linux_filter_inquiry(ahd, devinfo); + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_VERIFY); + targ->dv_echo_size = 0; + break; + } + break; + + case AHD_DV_STATE_WEB: + switch (status & SS_MASK) { + case SS_NOP: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REB); + break; + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry <= 10) + break; + /* FALLTHROUGH */ +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV WEB reties exhausted\n"); + } +#endif + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_REB: + switch (status & SS_MASK) { + case SS_NOP: + if (memcmp(targ->dv_buffer, targ->dv_buffer1, + targ->dv_echo_size) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + else + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_WEB); + break; + } + + if (targ->dv_buffer != NULL) { + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = NULL; + } + if (targ->dv_buffer1 != NULL) { + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = NULL; + } + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB); + } + if (targ->dv_state_retry <= 10) { + if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0) + scsi_sleep(ahd->our_id*HZ/10); + break; + } +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV REB reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_SU: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_BUSY: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if (targ->dv_state_retry < 60) { + if ((status & SSQ_DELAY) != 0) + scsi_sleep(1 * HZ); + } else { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV BUSY reties exhausted\n"); + } +#endif + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + } + break; + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + default: + printf("%s: Invalid DV completion state %d\n", ahd_name(ahd), + targ->dv_state); + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } +} + +static void +ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo) +{ + memset(cmd, 0, sizeof(struct scsi_cmnd)); + cmd->device = ahd->platform_data->dv_scsi_dev; + cmd->scsi_done = ahd_linux_dv_complete; +} + +/* + * Synthesize an inquiry command. On the return trip, it'll be + * sniffed and the device transfer settings set for us. + */ +static void +ahd_linux_dv_inq(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ, + u_int request_length) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending INQ\n"); + } +#endif + if (targ->inq_data == NULL) + targ->inq_data = malloc(AHD_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) { + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHD_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + } + + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 6; + cmd->cmnd[0] = INQUIRY; + cmd->cmnd[4] = request_length; + cmd->request_bufflen = request_length; + if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) + cmd->request_buffer = targ->dv_buffer; + else + cmd->request_buffer = targ->inq_data; + memset(cmd->request_buffer, 0, AHD_LINUX_DV_INQ_LEN); +} + +static void +ahd_linux_dv_tur(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending TUR\n"); + } +#endif + /* Do a TUR to clear out any non-fatal transitional state */ + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = TEST_UNIT_READY; +} + +#define AHD_REBD_LEN 4 + +static void +ahd_linux_dv_rebd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending REBD\n"); + } +#endif + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHD_REBD_LEN, M_DEVBUF, M_WAITOK); + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0b; + scsi_ulto3b(AHD_REBD_LEN, &cmd->cmnd[6]); + cmd->request_bufflen = AHD_REBD_LEN; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; +} + +static void +ahd_linux_dv_web(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending WEB\n"); + } +#endif + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_WRITE; + cmd->cmd_len = 10; + cmd->cmnd[0] = WRITE_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; +} + +static void +ahd_linux_dv_reb(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending REB\n"); + } +#endif + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer1; +} + +static void +ahd_linux_dv_su(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ) +{ + u_int le; + + le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0; + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending SU\n"); + } +#endif + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = START_STOP_UNIT; + cmd->cmnd[4] = le | SSS_START; +} + +static __inline int +ahd_linux_dv_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + u_long s; + int retval; + + ahd_lock(ahd, &s); + retval = ahd_linux_fallback(ahd, devinfo); + ahd_unlock(ahd, &s); + + return (retval); +} + +static int +ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct ahd_linux_target *targ; + struct ahd_initiator_tinfo *tinfo; + struct ahd_transinfo *goal; + struct ahd_tmode_tstate *tstate; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int cur_speed; + u_int wide_speed; + u_int narrow_speed; + u_int fallback_speed; + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Trying to fallback\n"); + } +#endif + targ = ahd->platform_data->targets[devinfo->target_offset]; + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + goal = &tinfo->goal; + width = goal->width; + period = goal->period; + offset = goal->offset; + ppr_options = goal->ppr_options; + if (offset == 0) + period = AHD_ASYNC_XFER_PERIOD; + if (targ->dv_next_narrow_period == 0) + targ->dv_next_narrow_period = MAX(period, AHD_SYNCRATE_ULTRA2); + if (targ->dv_next_wide_period == 0) + targ->dv_next_wide_period = period; + if (targ->dv_max_width == 0) + targ->dv_max_width = width; + if (targ->dv_max_ppr_options == 0) + targ->dv_max_ppr_options = ppr_options; + if (targ->dv_last_ppr_options == 0) + targ->dv_last_ppr_options = ppr_options; + + cur_speed = aic_calc_speed(width, period, offset, AHD_SYNCRATE_MIN); + wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, + targ->dv_next_wide_period, + MAX_OFFSET, AHD_SYNCRATE_MIN); + narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, + targ->dv_next_narrow_period, + MAX_OFFSET, AHD_SYNCRATE_MIN); + fallback_speed = aic_calc_speed(width, period+1, offset, + AHD_SYNCRATE_MIN); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " + "fallback_speed= %d\n", cur_speed, wide_speed, + narrow_speed, fallback_speed); + } +#endif + + if (cur_speed > 160000) { + /* + * Paced/DT/IU_REQ only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + } else if (cur_speed > 80000) { + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + /* + * Try without IU_REQ as it may be confusing + * an expander. + */ + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else { + /* + * Paced/DT only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + ppr_options = targ->dv_max_ppr_options; + } + } else if (cur_speed > 3300) { + + /* + * In this range we the following + * options ordered from highest to + * lowest desireability: + * + * o Wide/DT + * o Wide/non-DT + * o Narrow at a potentally higher sync rate. + * + * All modes are tested with and without IU_REQ + * set since using IUs may confuse an expander. + */ + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + /* + * Try going non-DT. + */ + ppr_options = targ->dv_max_ppr_options; + ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } else if (targ->dv_last_ppr_options != 0) { + /* + * Try without QAS or any other PPR options. + * We may need a non-PPR message to work with + * an expander. We look at the "last PPR options" + * so we will perform this fallback even if the + * target responded to our PPR negotiation with + * no option bits set. + */ + ppr_options = 0; + } else if (width == MSG_EXT_WDTR_BUS_16_BIT) { + /* + * If the next narrow speed is greater than + * the next wide speed, fallback to narrow. + * Otherwise fallback to the next DT/Wide setting. + * The narrow async speed will always be smaller + * than the wide async speed, so handle this case + * specifically. + */ + ppr_options = targ->dv_max_ppr_options; + if (narrow_speed > fallback_speed + || period >= AHD_ASYNC_XFER_PERIOD) { + targ->dv_next_wide_period = period+1; + width = MSG_EXT_WDTR_BUS_8_BIT; + period = targ->dv_next_narrow_period; + } else { + period++; + } + } else if ((ahd->features & AHD_WIDE) != 0 + && targ->dv_max_width != 0 + && wide_speed >= fallback_speed + && (targ->dv_next_wide_period <= AHD_ASYNC_XFER_PERIOD + || period >= AHD_ASYNC_XFER_PERIOD)) { + + /* + * We are narrow. Try falling back + * to the next wide speed with + * all supported ppr options set. + */ + targ->dv_next_narrow_period = period+1; + width = MSG_EXT_WDTR_BUS_16_BIT; + period = targ->dv_next_wide_period; + ppr_options = targ->dv_max_ppr_options; + } else { + /* Only narrow fallback is allowed. */ + period++; + ppr_options = targ->dv_max_ppr_options; + } + } else { + return (-1); + } + offset = MAX_OFFSET; + ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_PACED); + ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, FALSE); + if (period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + if (width == MSG_EXT_WDTR_BUS_8_BIT) + targ->dv_next_narrow_period = AHD_ASYNC_XFER_PERIOD; + else + targ->dv_next_wide_period = AHD_ASYNC_XFER_PERIOD; + } + ahd_set_syncrate(ahd, devinfo, period, offset, + ppr_options, AHD_TRANS_GOAL, FALSE); + targ->dv_last_ppr_options = ppr_options; + return (0); +} + +static void +ahd_linux_dv_timeout(struct scsi_cmnd *cmd) +{ + struct ahd_softc *ahd; + struct ahd_cmd *acmd; + struct ahd_linux_device *next_dev; + struct scb *scb; + u_long flags; + + ahd = *((struct ahd_softc **)cmd->device->host->hostdata); + ahd_lock(ahd, &flags); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + printf("%s: Timeout while doing DV command %x.\n", + ahd_name(ahd), cmd->cmnd[0]); + ahd_dump_card_state(ahd); + } +#endif + + /* + * Guard against "done race". No action is + * required if we just completed. + */ + if ((scb = (struct scb *)cmd->host_scribble) == NULL) { + ahd_unlock(ahd, &flags); + return; + } + + /* + * Command has not completed. Mark this + * SCB as having failing status prior to + * resetting the bus, so we get the correct + * error code. + */ + if ((scb->flags & SCB_SENSE) != 0) + ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); + else + ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); + ahd_reset_channel(ahd, cmd->channel + 'A', /*initiate*/TRUE); + + /* + * Add a minimal bus settle delay for devices that are slow to + * respond after bus resets. + */ + ahd_freeze_simq(ahd); + init_timer(&ahd->platform_data->reset_timer); + ahd->platform_data->reset_timer.data = (u_long)ahd; + ahd->platform_data->reset_timer.expires = jiffies + HZ / 2; + ahd->platform_data->reset_timer.function = + (ahd_linux_callback_t *)ahd_release_simq; + add_timer(&ahd->platform_data->reset_timer); + /* + * In 2.5.X, the "done lock" is the ahd_lock. + * Instead of dropping and re-acquiring the same + * lock in the 2.5.X case, just hold our ahd_lock + * the whole time. ahd_done_lock() has been + * made a no-op for 2.5.X too. + */ + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + next_dev = ahd_linux_next_device_to_run(ahd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif + if (next_dev) + ahd_schedule_runq(ahd); + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &flags); +#endif + ahd_schedule_completeq(ahd, acmd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif + } + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif +} + +static void +ahd_linux_dv_complete(struct scsi_cmnd *cmd) +{ + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)cmd->device->host->hostdata); + + /* Delete the DV timer before it goes off! */ + scsi_delete_timer(cmd); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s:%c:%d: Command completed, status= 0x%x\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->result); +#endif + + /* Wake up the state machine */ + up(&ahd->platform_data->dv_cmd_sem); +} + +static void +ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ) +{ + uint16_t b; + u_int i; + u_int j; + + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); + + i = 0; + + b = 0x0001; + for (j = 0 ; i < targ->dv_echo_size; j++) { + if (j < 32) { + /* + * 32bytes of sequential numbers. + */ + targ->dv_buffer[i++] = j & 0xff; + } else if (j < 48) { + /* + * 32bytes of repeating 0x0000, 0xffff. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00; + } else if (j < 64) { + /* + * 32bytes of repeating 0x5555, 0xaaaa. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55; + } else { + /* + * Remaining buffer is filled with a repeating + * patter of: + * + * 0xffff + * ~0x0001 << shifted once in each loop. + */ + if (j & 0x02) { + if (j & 0x01) { + targ->dv_buffer[i++] = ~(b >> 8) & 0xff; + b <<= 1; + if (b == 0x0000) + b = 0x0001; + } else { + targ->dv_buffer[i++] = (~b & 0xff); + } + } else { + targ->dv_buffer[i++] = 0xff; + } + } + } +} + +static u_int +ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + static int warned_user; + u_int tags; + + tags = 0; + if ((ahd->user_discenable & devinfo->target_mask) != 0) { + if (warned_user == 0 + && ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) { + + printf("aic79xx: WARNING, insufficient " + "tag_info instances for installed " + "controllers. Using defaults\n"); + printf("aic79xx: Please update the " + "aic79xx_tag_info array in the " + "aic79xx.c source file.\n"); + tags = AHD_MAX_QUEUE; + warned_user++; + } else { + adapter_tag_info_t *tag_info; + + tag_info = &aic79xx_tag_info[ahd->unit]; + tags = tag_info->tag_commands[devinfo->target_offset]; + if (tags > AHD_MAX_QUEUE) + tags = AHD_MAX_QUEUE; + } + } + return (tags); +} + +static u_int +ahd_linux_user_dv_setting(struct ahd_softc *ahd) +{ + static int warned_user; + int dv; + + if (warned_user == 0 + && ahd->unit >= NUM_ELEMENTS(aic79xx_dv_settings)) { + + printf("aic79xx: WARNING, insufficient " + "dv settings instances for installed " + "controllers. Using defaults\n"); + printf("aic79xx: Please update the " + "aic79xx_dv_settings array in the " + "aic79xx.c source file.\n"); + dv = -1; + warned_user++; + } else { + + dv = aic79xx_dv_settings[ahd->unit]; + } + + if (dv < 0) { + /* + * Apply the default. + */ + dv = 1; + if (ahd->seep_config != 0) + dv = (ahd->seep_config->bios_control & CFENABLEDV); + } + return (dv); +} + +/* + * Determines the queue depth for a given device. + */ +static void +ahd_linux_device_queue_depth(struct ahd_softc *ahd, + struct ahd_linux_device *dev) +{ + struct ahd_devinfo devinfo; + u_int tags; + + ahd_compile_devinfo(&devinfo, + ahd->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', + ROLE_INITIATOR); + tags = ahd_linux_user_tagdepth(ahd, &devinfo); + if (tags != 0 + && dev->scsi_device != NULL + && dev->scsi_device->tagged_supported != 0) { + + ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); + printf("scsi%d:%c:%d:%d: Tagged Queuing enabled. Depth %d\n", + ahd->platform_data->host->host_no, devinfo.channel, + devinfo.target, devinfo.lun, tags); + } else { + ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); + } +} + +static void +ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) +{ + struct ahd_cmd *acmd; + struct scsi_cmnd *cmd; + struct scb *scb; + struct hardware_scb *hscb; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int col_idx; + uint16_t mask; + + if ((dev->flags & AHD_DEV_ON_RUN_LIST) != 0) + panic("running device on run list"); + + while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL + && dev->openings > 0 && dev->qfrozen == 0) { + + /* + * Schedule us to run later. The only reason we are not + * running is because the whole controller Q is frozen. + */ + if (ahd->platform_data->qfrozen != 0 + && AHD_DV_SIMQ_FROZEN(ahd) == 0) { + + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, + dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + return; + } + + cmd = &acmd_scsi_cmd(acmd); + + /* + * Get an scb to use. + */ + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + cmd->device->id, &tstate); + if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0 + || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + col_idx = AHD_NEVER_COL_IDX; + } else { + col_idx = AHD_BUILD_COL_IDX(cmd->device->id, + cmd->device->lun); + } + if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, + dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + ahd->flags |= AHD_RESOURCE_SHORTAGE; + return; + } + TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe); + scb->io_ctx = cmd; + scb->platform_data->dev = dev; + hscb = scb->hscb; + cmd->host_scribble = (char *)scb; + + /* + * Fill out basics of the HSCB. + */ + hscb->control = 0; + hscb->scsiid = BUILD_SCSIID(ahd, cmd); + hscb->lun = cmd->lun; + scb->hscb->task_management = 0; + mask = SCB_GET_TARGET_MASK(ahd, scb); + + if ((ahd->user_discenable & mask) != 0) + hscb->control |= DISCENB; + + if (AHD_DV_CMD(cmd) != 0) + scb->flags |= SCB_SILENT; + + if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) + scb->flags |= SCB_PACKETIZED; + + if ((tstate->auto_negotiate & mask) != 0) { + scb->flags |= SCB_AUTO_NEGOTIATE; + scb->hscb->control |= MK_MESSAGE; + } + + if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + int msg_bytes; + uint8_t tag_msgs[2]; + + msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); + if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { + hscb->control |= tag_msgs[0]; + if (tag_msgs[0] == MSG_ORDERED_TASK) + dev->commands_since_idle_or_otag = 0; + } else +#endif + if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH + && (dev->flags & AHD_DEV_Q_TAGGED) != 0) { + hscb->control |= MSG_ORDERED_TASK; + dev->commands_since_idle_or_otag = 0; + } else { + hscb->control |= MSG_SIMPLE_TASK; + } + } + + hscb->cdb_len = cmd->cmd_len; + memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len); + + scb->sg_count = 0; + ahd_set_residual(scb, 0); + ahd_set_sense_residual(scb, 0); + if (cmd->use_sg != 0) { + void *sg; + struct scatterlist *cur_seg; + u_int nseg; + int dir; + + cur_seg = (struct scatterlist *)cmd->request_buffer; + dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + nseg = pci_map_sg(ahd->dev_softc, cur_seg, + cmd->use_sg, dir); + scb->platform_data->xfer_len = 0; + for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) { + bus_addr_t addr; + bus_size_t len; + + addr = sg_dma_address(cur_seg); + len = sg_dma_len(cur_seg); + scb->platform_data->xfer_len += len; + sg = ahd_sg_setup(ahd, scb, sg, addr, len, + /*last*/nseg == 1); + } + } else if (cmd->request_bufflen != 0) { + void *sg; + bus_addr_t addr; + int dir; + + sg = scb->sg_list; + dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + addr = pci_map_single(ahd->dev_softc, + cmd->request_buffer, + cmd->request_bufflen, dir); + scb->platform_data->xfer_len = cmd->request_bufflen; + scb->platform_data->buf_busaddr = addr; + sg = ahd_sg_setup(ahd, scb, sg, addr, + cmd->request_bufflen, /*last*/TRUE); + } + + LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); + dev->openings--; + dev->active++; + dev->commands_issued++; + + /* Update the error counting bucket and dump if needed */ + if (dev->target->cmds_since_error) { + dev->target->cmds_since_error++; + if (dev->target->cmds_since_error > + AHD_LINUX_ERR_THRESH) + dev->target->cmds_since_error = 0; + } + + if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0) + dev->commands_since_idle_or_otag++; + scb->flags |= SCB_ACTIVE; + ahd_queue_scb(ahd, scb); + } +} + +/* + * SCSI controller interrupt handler. + */ +void +ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) +{ + struct ahd_softc *ahd; + struct ahd_cmd *acmd; + u_long flags; + struct ahd_linux_device *next_dev; + + ahd = (struct ahd_softc *) dev_id; + ahd_lock(ahd, &flags); + ahd_intr(ahd); + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + next_dev = ahd_linux_next_device_to_run(ahd); + /* + * In 2.5.X, the "done lock" is the ahd_lock. + * Instead of dropping and re-acquiring the same + * lock in the 2.5.X case, just hold our ahd_lock + * the whole time. ahd_done_lock() has been + * made a no-op for 2.5.X too. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif + if (next_dev) + ahd_schedule_runq(ahd); + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &flags); +#endif + ahd_schedule_completeq(ahd, acmd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif + } + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &flags); +#endif +} + +void +ahd_platform_flushwork(struct ahd_softc *ahd) +{ + struct ahd_cmd *acmd; + + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + while (acmd != NULL) + acmd = ahd_linux_run_complete_queue(ahd, acmd); +} + +static struct ahd_linux_target* +ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target) +{ + struct ahd_linux_target *targ; + u_int target_offset; + + target_offset = target; + /* + * Never allow allocation of a target object for + * our own SCSIID. + */ + if (target == ahd->our_id) { + ahd->platform_data->targets[target_offset] = NULL; + return (NULL); + } + + targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT); + if (targ == NULL) + return (NULL); + memset(targ, 0, sizeof(*targ)); + targ->channel = channel; + targ->target = target; + targ->ahd = ahd; + targ->flags = AHD_DV_REQUIRED; + ahd->platform_data->targets[target_offset] = targ; + return (targ); +} + +static void +ahd_linux_free_target(struct ahd_softc *ahd, struct ahd_linux_target *targ) +{ + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int our_id; + u_int target_offset; + char channel; + + /* + * Force a negotiation to async/narrow on any + * future command to this device unless a bus + * reset occurs between now and that command. + */ + channel = 'A' + targ->channel; + our_id = ahd->our_id; + target_offset = targ->target; + tinfo = ahd_fetch_transinfo(ahd, channel, our_id, + targ->target, &tstate); + ahd_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD, + channel, ROLE_INITIATOR); + ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_update_neg_request(ahd, &devinfo, tstate, tinfo, AHD_NEG_ALWAYS); + ahd->platform_data->targets[target_offset] = NULL; + if (targ->inq_data != NULL) + free(targ->inq_data, M_DEVBUF); + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + free(targ, M_DEVBUF); +} + +static struct ahd_linux_device* +ahd_linux_alloc_device(struct ahd_softc *ahd, + struct ahd_linux_target *targ, u_int lun) +{ + struct ahd_linux_device *dev; + + dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT); + if (dev == NULL) + return (NULL); + memset(dev, 0, sizeof(*dev)); + init_timer(&dev->timer); + TAILQ_INIT(&dev->busyq); + dev->flags = AHD_DEV_UNCONFIGURED; + dev->lun = lun; + dev->target = targ; + + /* + * We start out life using untagged + * transactions of which we allow one. + */ + dev->openings = 1; + + /* + * Set maxtags to 0. This will be changed if we + * later determine that we are dealing with + * a tagged queuing capable device. + */ + dev->maxtags = 0; + + targ->refcount++; + targ->devices[lun] = dev; + return (dev); +} + +static void +ahd_linux_free_device(struct ahd_softc *ahd, struct ahd_linux_device *dev) +{ + struct ahd_linux_target *targ; + + del_timer(&dev->timer); + targ = dev->target; + targ->devices[dev->lun] = NULL; + free(dev, M_DEVBUF); + targ->refcount--; + if (targ->refcount == 0 + && (targ->flags & AHD_DV_REQUIRED) == 0) + ahd_linux_free_target(ahd, targ); +} + +void +ahd_send_async(struct ahd_softc *ahd, char channel, + u_int target, u_int lun, ac_code code, void *arg) +{ + switch (code) { + case AC_TRANSFER_NEG: + { + char buf[80]; + struct ahd_linux_target *targ; + struct info_str info; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + info.buffer = buf; + info.length = sizeof(buf); + info.offset = 0; + info.pos = 0; + tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id, + target, &tstate); + + /* + * Don't bother reporting results while + * negotiations are still pending. + */ + if (tinfo->curr.period != tinfo->goal.period + || tinfo->curr.width != tinfo->goal.width + || tinfo->curr.offset != tinfo->goal.offset + || tinfo->curr.ppr_options != tinfo->goal.ppr_options) + if (bootverbose == 0) + break; + + /* + * Don't bother reporting results that + * are identical to those last reported. + */ + targ = ahd->platform_data->targets[target]; + if (targ == NULL) + break; + if (tinfo->curr.period == targ->last_tinfo.period + && tinfo->curr.width == targ->last_tinfo.width + && tinfo->curr.offset == targ->last_tinfo.offset + && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options) + if (bootverbose == 0) + break; + + targ->last_tinfo.period = tinfo->curr.period; + targ->last_tinfo.width = tinfo->curr.width; + targ->last_tinfo.offset = tinfo->curr.offset; + targ->last_tinfo.ppr_options = tinfo->curr.ppr_options; + + printf("(%s:%c:", ahd_name(ahd), channel); + if (target == CAM_TARGET_WILDCARD) + printf("*): "); + else + printf("%d): ", target); + ahd_format_transinfo(&info, &tinfo->curr); + if (info.pos < info.length) + *info.buffer = '\0'; + else + buf[info.length - 1] = '\0'; + printf("%s", buf); + break; + } + case AC_SENT_BDR: + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + Scsi_Device *scsi_dev; + + /* + * Find the SCSI device associated with this + * request and indicate that a UA is expected. + * XXX This should really be handled by the mid-layer. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + list_for_each_entry(scsi_dev, + &ahd->platform_data->host->my_devices, + siblings) { +#else + for (scsi_dev = ahd->platform_data->host->host_queue; + scsi_dev != NULL; scsi_dev = scsi_dev->next) { +#endif + if (channel - 'A' == scsi_dev->channel + && target == scsi_dev->id + && (lun == CAM_LUN_WILDCARD + || lun == scsi_dev->lun)) { + scsi_dev->was_reset = 1; + scsi_dev->expecting_cc_ua = 1; + } + } +#endif + break; + } + case AC_BUS_RESET: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + if (ahd->platform_data->host != NULL) { + scsi_report_bus_reset(ahd->platform_data->host, + channel - 'A'); + } +#endif + break; + default: + panic("ahd_send_async: Unexpected async event"); + } +} + +/* + * Calls the higher level scsi done function and frees the scb. + */ +void +ahd_done(struct ahd_softc *ahd, struct scb *scb) +{ + Scsi_Cmnd *cmd; + struct ahd_linux_device *dev; + + LIST_REMOVE(scb, pending_links); + + if ((scb->flags & SCB_ACTIVE) == 0) { + printf("SCB %d done'd twice\n", scb->hscb->tag); + ahd_dump_card_state(ahd); + panic("Stopping for safety"); + } + cmd = scb->io_ctx; + dev = scb->platform_data->dev; + dev->active--; + dev->openings++; + if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) { + cmd->result &= ~(CAM_DEV_QFRZN << 16); + dev->qfrozen--; + } + ahd_linux_unmap_scb(ahd, scb); + + /* + * Guard against stale sense data. + * The Linux mid-layer assumes that sense + * was retrieved anytime the first byte of + * the sense buffer looks "sane". + */ + cmd->sense_buffer[0] = 0; + if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) { + uint32_t amount_xferred; + + amount_xferred = + ahd_get_transfer_length(scb) - ahd_get_residual(scb); + if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) { + ahd_print_path(ahd, scb); + printf("Set CAM_UNCOR_PARITY\n"); + } +#endif + ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); + } else if (amount_xferred < scb->io_ctx->underflow) { + printf("Saw underflow (%ld of %ld bytes). " + "Treated as error\n", + ahd_get_residual(scb), + ahd_get_transfer_length(scb)); + ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); + } else { + ahd_set_transaction_status(scb, CAM_REQ_CMP); + } + } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { + ahd_linux_handle_scsi_status(ahd, dev, scb); + } else if (ahd_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { + dev->flags |= AHD_DEV_UNCONFIGURED; + if (AHD_DV_CMD(cmd) == FALSE) + dev->target->flags &= ~AHD_DV_REQUIRED; + } + /* + * Start DV for devices that require it assuming the first command + * sent does not result in a selection timeout. + */ + if (ahd_get_transaction_status(scb) != CAM_SEL_TIMEOUT + && (dev->target->flags & AHD_DV_REQUIRED) != 0) + ahd_linux_start_dv(ahd); + + if (dev->openings == 1 + && ahd_get_transaction_status(scb) == CAM_REQ_CMP + && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL) + dev->tag_success_count++; + /* + * Some devices deal with temporary internal resource + * shortages by returning queue full. When the queue + * full occurrs, we throttle back. Slowly try to get + * back to our previous queue depth. + */ + if ((dev->openings + dev->active) < dev->maxtags + && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) { + dev->tag_success_count = 0; + dev->openings++; + } + + if (dev->active == 0) + dev->commands_since_idle_or_otag = 0; + + if (TAILQ_EMPTY(&dev->busyq)) { + if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 + && dev->active == 0) + ahd_linux_free_device(ahd, dev); + } else if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + } + + if ((scb->flags & SCB_RECOVERY_SCB) != 0) { + printf("Recovery SCB completes\n"); + if (ahd_get_transaction_status(scb) == CAM_BDR_SENT + || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) + ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); + if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { + ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; + up(&ahd->platform_data->eh_sem); + } + } + + ahd_free_scb(ahd, scb); + ahd_linux_queue_cmd_complete(ahd, cmd); + + if ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_EMPTY) != 0 + && LIST_FIRST(&ahd->pending_scbs) == NULL) { + ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY; + up(&ahd->platform_data->dv_sem); + } +} + +static void +ahd_linux_handle_scsi_status(struct ahd_softc *ahd, + struct ahd_linux_device *dev, struct scb *scb) +{ + struct ahd_devinfo devinfo; + + ahd_compile_devinfo(&devinfo, + ahd->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', + ROLE_INITIATOR); + + /* + * We don't currently trust the mid-layer to + * properly deal with queue full or busy. So, + * when one occurs, we tell the mid-layer to + * unconditionally requeue the command to us + * so that we can retry it ourselves. We also + * implement our own throttling mechanism so + * we don't clobber the device with too many + * commands. + */ + switch (ahd_get_scsi_status(scb)) { + default: + break; + case SCSI_STATUS_CHECK_COND: + case SCSI_STATUS_CMD_TERMINATED: + { + Scsi_Cmnd *cmd; + + /* + * Copy sense information to the OS's cmd + * structure if it is available. + */ + cmd = scb->io_ctx; + if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) { + struct scsi_status_iu_header *siu; + u_int sense_size; + u_int sense_offset; + + if (scb->flags & SCB_SENSE) { + sense_size = MIN(sizeof(struct scsi_sense_data) + - ahd_get_sense_residual(scb), + sizeof(cmd->sense_buffer)); + sense_offset = 0; + } else { + /* + * Copy only the sense data into the provided + * buffer. + */ + siu = (struct scsi_status_iu_header *) + scb->sense_data; + sense_size = MIN(scsi_4btoul(siu->sense_length), + sizeof(cmd->sense_buffer)); + sense_offset = SIU_SENSE_OFFSET(siu); + } + + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); + memcpy(cmd->sense_buffer, + ahd_get_sense_buf(ahd, scb) + + sense_offset, sense_size); + cmd->result |= (DRIVER_SENSE << 24); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_SENSE) { + int i; + + printf("Copied %d bytes of sense data at %d:", + sense_size, sense_offset); + for (i = 0; i < sense_size; i++) { + if ((i & 0xF) == 0) + printf("\n"); + printf("0x%x ", cmd->sense_buffer[i]); + } + printf("\n"); + } +#endif + } + break; + } + case SCSI_STATUS_QUEUE_FULL: + { + /* + * By the time the core driver has returned this + * command, all other commands that were queued + * to us but not the device have been returned. + * This ensures that dev->active is equal to + * the number of commands actually queued to + * the device. + */ + dev->tag_success_count = 0; + if (dev->active != 0) { + /* + * Drop our opening count to the number + * of commands currently outstanding. + */ + dev->openings = 0; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_QFULL) { + ahd_print_path(ahd, scb); + printf("Dropping tag count to %d\n", + dev->active); + } +#endif + if (dev->active == dev->tags_on_last_queuefull) { + + dev->last_queuefull_same_count++; + /* + * If we repeatedly see a queue full + * at the same queue depth, this + * device has a fixed number of tag + * slots. Lock in this tag depth + * so we stop seeing queue fulls from + * this device. + */ + if (dev->last_queuefull_same_count + == AHD_LOCK_TAGS_COUNT) { + dev->maxtags = dev->active; + ahd_print_path(ahd, scb); + printf("Locking max tag count at %d\n", + dev->active); + } + } else { + dev->tags_on_last_queuefull = dev->active; + dev->last_queuefull_same_count = 0; + } + ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); + ahd_set_scsi_status(scb, SCSI_STATUS_OK); + ahd_set_tags(ahd, &devinfo, + (dev->flags & AHD_DEV_Q_BASIC) + ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); + break; + } + /* + * Drop down to a single opening, and treat this + * as if the target returned BUSY SCSI status. + */ + dev->openings = 1; + ahd_set_tags(ahd, &devinfo, + (dev->flags & AHD_DEV_Q_BASIC) + ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); + ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); + /* FALLTHROUGH */ + } + case SCSI_STATUS_BUSY: + /* + * Set a short timer to defer sending commands for + * a bit since Linux will not delay in this case. + */ + if ((dev->flags & AHD_DEV_TIMER_ACTIVE) != 0) { + printf("%s:%c:%d: Device Timer still active during " + "busy processing\n", ahd_name(ahd), + dev->target->channel, dev->target->target); + break; + } + dev->flags |= AHD_DEV_TIMER_ACTIVE; + dev->qfrozen++; + init_timer(&dev->timer); + dev->timer.data = (u_long)dev; + dev->timer.expires = jiffies + (HZ/2); + dev->timer.function = ahd_linux_dev_timed_unfreeze; + add_timer(&dev->timer); + break; + } +} + +static void +ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, Scsi_Cmnd *cmd) +{ + /* + * Typically, the complete queue has very few entries + * queued to it before the queue is emptied by + * ahd_linux_run_complete_queue, so sorting the entries + * by generation number should be inexpensive. + * We perform the sort so that commands that complete + * with an error are retuned in the order origionally + * queued to the controller so that any subsequent retries + * are performed in order. The underlying ahd routines do + * not guarantee the order that aborted commands will be + * returned to us. + */ + struct ahd_completeq *completeq; + struct ahd_cmd *list_cmd; + struct ahd_cmd *acmd; + + /* + * Map CAM error codes into Linux Error codes. We + * avoid the conversion so that the DV code has the + * full error information available when making + * state change decisions. + */ + if (AHD_DV_CMD(cmd) == FALSE) { + uint32_t status; + u_int new_status; + + status = ahd_cmd_get_transaction_status(cmd); + if (status != CAM_REQ_CMP) { + struct ahd_linux_device *dev; + struct ahd_devinfo devinfo; + cam_status cam_status; + uint32_t action; + u_int scsi_status; + + dev = ahd_linux_get_device(ahd, cmd->channel, + cmd->device->id, + cmd->device->lun, + /*alloc*/FALSE); + + if (dev == NULL) + goto no_fallback; + + ahd_compile_devinfo(&devinfo, + ahd->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A':'B', + ROLE_INITIATOR); + + scsi_status = ahd_cmd_get_scsi_status(cmd); + cam_status = ahd_cmd_get_transaction_status(cmd); + action = aic_error_action(cmd, dev->target->inq_data, + cam_status, scsi_status); + if ((action & SSQ_FALLBACK) != 0) { + + /* Update stats */ + dev->target->errors_detected++; + if (dev->target->cmds_since_error == 0) + dev->target->cmds_since_error++; + else { + dev->target->cmds_since_error = 0; + ahd_linux_fallback(ahd, &devinfo); + } + } + } +no_fallback: + switch (status) { + case CAM_REQ_INPROG: + case CAM_REQ_CMP: + case CAM_SCSI_STATUS_ERROR: + new_status = DID_OK; + break; + case CAM_REQ_ABORTED: + new_status = DID_ABORT; + break; + case CAM_BUSY: + new_status = DID_BUS_BUSY; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + new_status = DID_BAD_TARGET; + break; + case CAM_SEL_TIMEOUT: + new_status = DID_NO_CONNECT; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + new_status = DID_RESET; + break; + case CAM_UNCOR_PARITY: + new_status = DID_PARITY; + break; + case CAM_CMD_TIMEOUT: + new_status = DID_TIME_OUT; + break; + case CAM_UA_ABORT: + case CAM_REQ_CMP_ERR: + case CAM_AUTOSENSE_FAIL: + case CAM_NO_HBA: + case CAM_DATA_RUN_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_SEQUENCE_FAIL: + case CAM_CCB_LEN_ERR: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TERMIO: + case CAM_UNREC_HBA_ERROR: + case CAM_REQ_TOO_BIG: + new_status = DID_ERROR; + break; + case CAM_REQUEUE_REQ: + /* + * If we want the request requeued, make sure there + * are sufficent retries. In the old scsi error code, + * we used to be able to specify a result code that + * bypassed the retry count. Now we must use this + * hack. We also "fake" a check condition with + * a sense code of ABORTED COMMAND. This seems to + * evoke a retry even if this command is being sent + * via the eh thread. Ick! Ick! Ick! + */ + if (cmd->retries > 0) + cmd->retries--; + new_status = DID_OK; + ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); + cmd->result |= (DRIVER_SENSE << 24); + memset(cmd->sense_buffer, 0, + sizeof(cmd->sense_buffer)); + cmd->sense_buffer[0] = SSD_ERRCODE_VALID + | SSD_CURRENT_ERROR; + cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; + break; + default: + /* We should never get here */ + new_status = DID_ERROR; + break; + } + + ahd_cmd_set_transaction_status(cmd, new_status); + } + + completeq = &ahd->platform_data->completeq; + list_cmd = TAILQ_FIRST(completeq); + acmd = (struct ahd_cmd *)cmd; + while (list_cmd != NULL + && acmd_scsi_cmd(list_cmd).serial_number + < acmd_scsi_cmd(acmd).serial_number) + list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); + if (list_cmd != NULL) + TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); + else + TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); +} + +static void +ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct scsi_inquiry_data *sid; + struct ahd_initiator_tinfo *tinfo; + struct ahd_transinfo *user; + struct ahd_transinfo *goal; + struct ahd_transinfo *curr; + struct ahd_tmode_tstate *tstate; + struct ahd_linux_device *dev; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int trans_version; + u_int prot_version; + static int warned_user; + + /* + * Determine if this lun actually exists. If so, + * hold on to its corresponding device structure. + * If not, make sure we release the device and + * don't bother processing the rest of this inquiry + * command. + */ + dev = ahd_linux_get_device(ahd, devinfo->channel - 'A', + devinfo->target, devinfo->lun, + /*alloc*/TRUE); + + sid = (struct scsi_inquiry_data *)dev->target->inq_data; + if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { + + dev->flags &= ~AHD_DEV_UNCONFIGURED; + } else { + dev->flags |= AHD_DEV_UNCONFIGURED; + return; + } + + /* + * Update our notion of this device's transfer + * negotiation capabilities. + */ + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + user = &tinfo->user; + goal = &tinfo->goal; + curr = &tinfo->curr; + width = user->width; + period = user->period; + offset = user->offset; + ppr_options = user->ppr_options; + trans_version = user->transport_version; + prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid)); + + /* + * If we have read streaming info for this controller, + * apply it to this target. + */ + if (warned_user == 0 + && ahd->unit >= NUM_ELEMENTS(aic79xx_rd_strm_info)) { + + printf("aic79xx: WARNING, insufficient rd_strm instances " + "for installed controllers. Using defaults\n"); + printf("aic79xx: Please update the aic79xx_rd_strm_info " + "array in the aic79xx_osm.c source file.\n"); + warned_user++; + } else { + uint16_t rd_strm_mask; + + rd_strm_mask = aic79xx_rd_strm_info[ahd->unit]; + if ((rd_strm_mask & devinfo->target_mask) == 0) + ppr_options &= ~MSG_EXT_PPR_RD_STRM; + } + + /* + * Only attempt SPI3/4 once we've verified that + * the device claims to support SPI3/4 features. + */ + if (prot_version < SCSI_REV_2) + trans_version = SID_ANSI_REV(sid); + else + trans_version = SCSI_REV_2; + + if ((sid->flags & SID_WBus16) == 0) + width = MSG_EXT_WDTR_BUS_8_BIT; + if ((sid->flags & SID_Sync) == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + if ((sid->spi3data & SID_SPI_QAS) == 0) + ppr_options &= ~MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_IUS) == 0) + ppr_options &= (MSG_EXT_PPR_DT_REQ + | MSG_EXT_PPR_QAS_REQ); + + if (prot_version > SCSI_REV_2 + && ppr_options != 0) + trans_version = user->transport_version; + + ahd_validate_width(ahd, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN); + ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX); + ahd_validate_offset(ahd, /*tinfo limit*/NULL, period, + &offset, width, ROLE_UNKNOWN); + if (offset == 0 || period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + /* Apply our filtered user settings. */ + curr->transport_version = trans_version; + curr->protocol_version = prot_version; + ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_set_syncrate(ahd, devinfo, period, offset, ppr_options, + AHD_TRANS_GOAL, /*paused*/FALSE); +} + +void +ahd_freeze_simq(struct ahd_softc *ahd) +{ + ahd->platform_data->qfrozen++; + if (ahd->platform_data->qfrozen == 1) { + scsi_block_requests(ahd->platform_data->host); + ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ); + } +} + +void +ahd_release_simq(struct ahd_softc *ahd) +{ + u_long s; + int unblock_reqs; + + unblock_reqs = 0; + ahd_lock(ahd, &s); + if (ahd->platform_data->qfrozen > 0) + ahd->platform_data->qfrozen--; + if (ahd->platform_data->qfrozen == 0) { + unblock_reqs = 1; + } + if (AHD_DV_SIMQ_FROZEN(ahd) + && ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_RELEASE) != 0)) { + ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE; + up(&ahd->platform_data->dv_sem); + } + ahd_unlock(ahd, &s); + /* + * There is still a race here. The mid-layer + * should keep its own freeze count and use + * a bottom half handler to run the queues + * so we can unblock with our own lock held. + */ + if (unblock_reqs) + scsi_unblock_requests(ahd->platform_data->host); + + ahd_schedule_runq(ahd); +} + +static void +ahd_linux_sem_timeout(u_long arg) +{ + struct ahd_softc *ahd; + u_long s; + + ahd = (struct ahd_softc *)arg; + ahd_lock(ahd, &s); + if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { + ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; + up(&ahd->platform_data->eh_sem); + } + ahd_unlock(ahd, &s); +} + +static void +ahd_linux_dev_timed_unfreeze(u_long arg) +{ + struct ahd_linux_device *dev; + struct ahd_softc *ahd; + u_long s; + + dev = (struct ahd_linux_device *)arg; + ahd = dev->target->ahd; + ahd_lock(ahd, &s); + dev->flags &= ~AHD_DEV_TIMER_ACTIVE; + if (dev->qfrozen > 0) + dev->qfrozen--; + if (dev->qfrozen == 0 + && (dev->flags & AHD_DEV_ON_RUN_LIST) == 0) + ahd_linux_run_device_queue(ahd, dev); + ahd_unlock(ahd, &s); +} + +void +ahd_platform_dump_card_state(struct ahd_softc *ahd) +{ + struct ahd_linux_device *dev; + int target; + int maxtarget; + int lun; + int i; + + maxtarget = (ahd->features & AHD_WIDE) ? 15 : 7; + for (target = 0; target <=maxtarget; target++) { + + for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + struct ahd_cmd *acmd; + + dev = ahd_linux_get_device(ahd, 0, target, + lun, /*alloc*/FALSE); + if (dev == NULL) + continue; + + printf("DevQ(%d:%d:%d): ", 0, target, lun); + i = 0; + TAILQ_FOREACH(acmd, &dev->busyq, acmd_links.tqe) { + if (i++ > AHD_SCB_MAX) + break; + } + printf("%d waiting\n", i); + } + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_osm.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_osm.h --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_osm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_osm.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,1288 @@ +/* + * Adaptec AIC79xx device driver for Linux. + * + * Copyright (c) 2000-2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#108 $ + * + */ +#ifndef _AIC79XX_LINUX_H_ +#define _AIC79XX_LINUX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef AHD_MODVERSION_FILE +#define __NO_VERSION__ +#endif +#include +#include +#include + +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include /* For tasklet support. */ +#include +#include +#else +#include +#endif + +/* Core SCSI definitions */ +#define AIC_LIB_PREFIX ahd +#include "scsi.h" +#include "hosts.h" + +/* Name space conflict with BSD queue macros */ +#ifdef LIST_HEAD +#undef LIST_HEAD +#endif + +#include "cam.h" +#include "queue.h" +#include "scsi_message.h" +#include "scsi_iu.h" +#include "aiclib.h" + +/*********************************** Debugging ********************************/ +#ifdef CONFIG_AIC79XX_DEBUG_ENABLE +#ifdef CONFIG_AIC79XX_DEBUG_MASK +#define AHD_DEBUG 1 +#define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK +#else +/* + * Compile in debugging code, but do not enable any printfs. + */ +#define AHD_DEBUG 1 +#endif +/* No debugging code. */ +#endif + +/********************************** Misc Macros *******************************/ +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#define powerof2(x) ((((x)-1)&(x))==0) + +/************************* Forward Declarations *******************************/ +struct ahd_softc; +typedef struct pci_dev *ahd_dev_softc_t; +typedef Scsi_Cmnd *ahd_io_ctx_t; + +/******************************* Byte Order ***********************************/ +#define ahd_htobe16(x) cpu_to_be16(x) +#define ahd_htobe32(x) cpu_to_be32(x) +#define ahd_htobe64(x) cpu_to_be64(x) +#define ahd_htole16(x) cpu_to_le16(x) +#define ahd_htole32(x) cpu_to_le32(x) +#define ahd_htole64(x) cpu_to_le64(x) + +#define ahd_be16toh(x) be16_to_cpu(x) +#define ahd_be32toh(x) be32_to_cpu(x) +#define ahd_be64toh(x) be64_to_cpu(x) +#define ahd_le16toh(x) le16_to_cpu(x) +#define ahd_le32toh(x) le32_to_cpu(x) +#define ahd_le64toh(x) le64_to_cpu(x) + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#ifndef BYTE_ORDER +#if defined(__BIG_ENDIAN) +#define BYTE_ORDER BIG_ENDIAN +#endif +#if defined(__LITTLE_ENDIAN) +#define BYTE_ORDER LITTLE_ENDIAN +#endif +#endif /* BYTE_ORDER */ + +/************************* Configuration Data *********************************/ +extern int aic79xx_allow_memio; +extern int aic79xx_detect_complete; +extern Scsi_Host_Template aic79xx_driver_template; + +/***************************** Bus Space/DMA **********************************/ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17) +typedef dma_addr_t bus_addr_t; +#else +typedef uint32_t bus_addr_t; +#endif +typedef uint32_t bus_size_t; + +typedef enum { + BUS_SPACE_MEMIO, + BUS_SPACE_PIO +} bus_space_tag_t; + +typedef union { + u_long ioport; + volatile uint8_t *maddr; +} bus_space_handle_t; + +typedef struct bus_dma_segment +{ + bus_addr_t ds_addr; + bus_size_t ds_len; +} bus_dma_segment_t; + +struct ahd_linux_dma_tag +{ + bus_size_t alignment; + bus_size_t boundary; + bus_size_t maxsize; +}; +typedef struct ahd_linux_dma_tag* bus_dma_tag_t; + +struct ahd_linux_dmamap +{ + bus_addr_t bus_addr; +}; +typedef struct ahd_linux_dmamap* bus_dmamap_t; + +typedef int bus_dma_filter_t(void*, bus_addr_t); +typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); + +#define BUS_DMA_WAITOK 0x0 +#define BUS_DMA_NOWAIT 0x1 +#define BUS_DMA_ALLOCNOW 0x2 +#define BUS_DMA_LOAD_SEGS 0x4 /* + * Argument is an S/G list not + * a single buffer. + */ + +#define BUS_SPACE_MAXADDR 0xFFFFFFFF +#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF +#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF + +int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/, + bus_size_t /*alignment*/, bus_size_t /*boundary*/, + bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/, + bus_dma_filter_t*/*filter*/, void */*filterarg*/, + bus_size_t /*maxsize*/, int /*nsegments*/, + bus_size_t /*maxsegsz*/, int /*flags*/, + bus_dma_tag_t */*dma_tagp*/); + +void ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/); + +int ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/, + void** /*vaddr*/, int /*flags*/, + bus_dmamap_t* /*mapp*/); + +void ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/, + void* /*vaddr*/, bus_dmamap_t /*map*/); + +void ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/, + bus_dmamap_t /*map*/); + +int ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/, + bus_dmamap_t /*map*/, void * /*buf*/, + bus_size_t /*buflen*/, bus_dmamap_callback_t *, + void */*callback_arg*/, int /*flags*/); + +int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t); + +/* + * Operations performed by ahd_dmamap_sync(). + */ +#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ +#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ +#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ +#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ + +/* + * XXX + * ahd_dmamap_sync is only used on buffers allocated with + * the pci_alloc_consistent() API. Although I'm not sure how + * this works on architectures with a write buffer, Linux does + * not have an API to sync "coherent" memory. Perhaps we need + * to do an mb()? + */ +#define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op) + +/************************** Timer DataStructures ******************************/ +typedef struct timer_list ahd_timer_t; + +/********************************** Includes **********************************/ +#if CONFIG_AIC79XX_REG_PRETTY_PRINT +#define AIC_DEBUG_REGISTERS 1 +#else +#define AIC_DEBUG_REGISTERS 0 +#endif +#include "aic79xx.h" + +/***************************** Timer Facilities *******************************/ +#define ahd_timer_init init_timer +#define ahd_timer_stop del_timer +typedef void ahd_linux_callback_t (u_long); +static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec, + ahd_callback_t *func, void *arg); +static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec); + +static __inline void +ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg) +{ + struct ahd_softc *ahd; + + ahd = (struct ahd_softc *)arg; + del_timer(timer); + timer->data = (u_long)arg; + timer->expires = jiffies + (usec * HZ)/1000000; + timer->function = (ahd_linux_callback_t*)func; + add_timer(timer); +} + +static __inline void +ahd_scb_timer_reset(struct scb *scb, u_int usec) +{ + mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); +} + +/***************************** SMP support ************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) +#include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) +#include +#endif + +#define AIC79XX_DRIVER_VERSION "1.3.0" + +/**************************** Front End Queues ********************************/ +/* + * Data structure used to cast the Linux struct scsi_cmnd to something + * that allows us to use the queue macros. The linux structure has + * plenty of space to hold the links fields as required by the queue + * macros, but the queue macors require them to have the correct type. + */ +struct ahd_cmd_internal { + /* Area owned by the Linux scsi layer. */ + uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)]; + union { + STAILQ_ENTRY(ahd_cmd) ste; + LIST_ENTRY(ahd_cmd) le; + TAILQ_ENTRY(ahd_cmd) tqe; + } links; + uint32_t end; +}; + +struct ahd_cmd { + union { + struct ahd_cmd_internal icmd; + struct scsi_cmnd scsi_cmd; + } un; +}; + +#define acmd_icmd(cmd) ((cmd)->un.icmd) +#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd) +#define acmd_links un.icmd.links + +/*************************** Device Data Structures ***************************/ +/* + * A per probed device structure used to deal with some error recovery + * scenarios that the Linux mid-layer code just doesn't know how to + * handle. The structure allocated for a device only becomes persistant + * after a successfully completed inquiry command to the target when + * that inquiry data indicates a lun is present. + */ +TAILQ_HEAD(ahd_busyq, ahd_cmd); +typedef enum { + AHD_DEV_UNCONFIGURED = 0x01, + AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ + AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ + AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ + AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ + AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ + AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ + AHD_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ +} ahd_linux_dev_flags; + +struct ahd_linux_target; +struct ahd_linux_device { + TAILQ_ENTRY(ahd_linux_device) links; + struct ahd_busyq busyq; + + /* + * The number of transactions currently + * queued to the device. + */ + int active; + + /* + * The currently allowed number of + * transactions that can be queued to + * the device. Must be signed for + * conversion from tagged to untagged + * mode where the device may have more + * than one outstanding active transaction. + */ + int openings; + + /* + * A positive count indicates that this + * device's queue is halted. + */ + u_int qfrozen; + + /* + * Cumulative command counter. + */ + u_long commands_issued; + + /* + * The number of tagged transactions when + * running at our current opening level + * that have been successfully received by + * this device since the last QUEUE FULL. + */ + u_int tag_success_count; +#define AHD_TAG_SUCCESS_INTERVAL 50 + + ahd_linux_dev_flags flags; + + /* + * Per device timer. + */ + struct timer_list timer; + + /* + * The high limit for the tags variable. + */ + u_int maxtags; + + /* + * The computed number of tags outstanding + * at the time of the last QUEUE FULL event. + */ + u_int tags_on_last_queuefull; + + /* + * How many times we have seen a queue full + * with the same number of tags. This is used + * to stop our adaptive queue depth algorithm + * on devices with a fixed number of tags. + */ + u_int last_queuefull_same_count; +#define AHD_LOCK_TAGS_COUNT 50 + + /* + * How many transactions have been queued + * without the device going idle. We use + * this statistic to determine when to issue + * an ordered tag to prevent transaction + * starvation. This statistic is only updated + * if the AHD_DEV_PERIODIC_OTAG flag is set + * on this device. + */ + u_int commands_since_idle_or_otag; +#define AHD_OTAG_THRESH 500 + + int lun; + Scsi_Device *scsi_device; + struct ahd_linux_target *target; +}; + +typedef enum { + AHD_DV_REQUIRED = 0x01, + AHD_INQ_VALID = 0x02, + AHD_BASIC_DV = 0x04, + AHD_ENHANCED_DV = 0x08 +} ahd_linux_targ_flags; + +/* DV States */ +typedef enum { + AHD_DV_STATE_EXIT = 0, + AHD_DV_STATE_INQ_SHORT_ASYNC, + AHD_DV_STATE_INQ_ASYNC, + AHD_DV_STATE_INQ_ASYNC_VERIFY, + AHD_DV_STATE_TUR, + AHD_DV_STATE_REBD, + AHD_DV_STATE_INQ_VERIFY, + AHD_DV_STATE_WEB, + AHD_DV_STATE_REB, + AHD_DV_STATE_SU, + AHD_DV_STATE_BUSY +} ahd_dv_state; + +struct ahd_linux_target { + struct ahd_linux_device *devices[AHD_NUM_LUNS]; + int channel; + int target; + int refcount; + struct ahd_transinfo last_tinfo; + struct ahd_softc *ahd; + ahd_linux_targ_flags flags; + struct scsi_inquiry_data *inq_data; + /* + * The next "fallback" period to use for narrow/wide transfers. + */ + uint8_t dv_next_narrow_period; + uint8_t dv_next_wide_period; + uint8_t dv_max_width; + uint8_t dv_max_ppr_options; + uint8_t dv_last_ppr_options; + u_int dv_echo_size; + ahd_dv_state dv_state; + u_int dv_state_retry; + uint8_t *dv_buffer; + uint8_t *dv_buffer1; + + /* + * Cumulative counter of errors. + */ + u_long errors_detected; + u_long cmds_since_error; +}; + +/********************* Definitions Required by the Core ***********************/ +/* + * Number of SG segments we require. So long as the S/G segments for + * a particular transaction are allocated in a physically contiguous + * manner and are allocated below 4GB, the number of S/G segments is + * unrestricted. + */ +#define AHD_NSEG 128 + +/* + * Per-SCB OSM storage. + */ +typedef enum { + AHD_UP_EH_SEMAPHORE = 0x1 +} ahd_linux_scb_flags; + +struct scb_platform_data { + struct ahd_linux_device *dev; + bus_addr_t buf_busaddr; + uint32_t xfer_len; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) + uint32_t resid; /* Transfer residual */ +#endif + uint32_t sense_resid; /* Auto-Sense residual */ + ahd_linux_scb_flags flags; +}; + +/* + * Define a structure used for each host adapter. All members are + * aligned on a boundary >= the size of the member to honor the + * alignment restrictions of the various platforms supported by + * this driver. + */ +typedef enum { + AHD_DV_WAIT_SIMQ_EMPTY = 0x01, + AHD_DV_WAIT_SIMQ_RELEASE = 0x02, + AHD_DV_ACTIVE = 0x04, + AHD_DV_SHUTDOWN = 0x08, + AHD_RUN_CMPLT_Q_TIMER = 0x10 +} ahd_linux_softc_flags; + +TAILQ_HEAD(ahd_completeq, ahd_cmd); + +struct ahd_platform_data { + /* + * Fields accessed from interrupt context. + */ + struct ahd_linux_target *targets[AHD_NUM_TARGETS]; + TAILQ_HEAD(, ahd_linux_device) device_runq; + struct ahd_completeq completeq; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) + spinlock_t spin_lock; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + struct tasklet_struct runq_tasklet; +#endif + u_int qfrozen; + pid_t dv_pid; + struct timer_list completeq_timer; + struct timer_list reset_timer; + struct timer_list stats_timer; + struct semaphore eh_sem; + struct semaphore dv_sem; + struct semaphore dv_cmd_sem; /* XXX This needs to be in + * the target struct + */ + struct scsi_device *dv_scsi_dev; + struct Scsi_Host *host; /* pointer to scsi host */ +#define AHD_LINUX_NOIRQ ((uint32_t)~0) + uint32_t irq; /* IRQ for this adapter */ + uint32_t bios_address; + uint32_t mem_busaddr; /* Mem Base Addr */ + bus_addr_t hw_dma_mask; + ahd_linux_softc_flags flags; +}; + +/************************** OS Utility Wrappers *******************************/ +#define printf printk +#define M_NOWAIT GFP_ATOMIC +#define M_WAITOK 0 +#define malloc(size, type, flags) kmalloc(size, flags) +#define free(ptr, type) kfree(ptr) + +static __inline void ahd_delay(long); +static __inline void +ahd_delay(long usec) +{ + /* + * udelay on Linux can have problems for + * multi-millisecond waits. Wait at most + * 1024us per call. + */ + while (usec > 0) { + udelay(usec % 1024); + usec -= 1024; + } +} + + +/***************************** Low Level I/O **********************************/ +#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__) +#define MMAPIO +#endif + +static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port); +static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port); +static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val); +static __inline void ahd_outw_atomic(struct ahd_softc * ahd, + long port, uint16_t val); +static __inline void ahd_outsb(struct ahd_softc * ahd, long port, + uint8_t *, int count); +static __inline void ahd_insb(struct ahd_softc * ahd, long port, + uint8_t *, int count); + +static __inline uint8_t +ahd_inb(struct ahd_softc * ahd, long port) +{ + uint8_t x; +#ifdef MMAPIO + + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + x = readb(ahd->bshs[0].maddr + port); + } else { + x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); + } +#else + x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); +#endif + mb(); + return (x); +} + +static __inline uint16_t +ahd_inw_atomic(struct ahd_softc * ahd, long port) +{ + uint8_t x; +#ifdef MMAPIO + + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + x = readw(ahd->bshs[0].maddr + port); + } else { + x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); + } +#else + x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); +#endif + mb(); + return (x); +} + +static __inline void +ahd_outb(struct ahd_softc * ahd, long port, uint8_t val) +{ +#ifdef MMAPIO + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + writeb(val, ahd->bshs[0].maddr + port); + } else { + outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); + } +#else + outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); +#endif + mb(); +} + +static __inline void +ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val) +{ +#ifdef MMAPIO + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + writew(val, ahd->bshs[0].maddr + port); + } else { + outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); + } +#else + outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); +#endif + mb(); +} + +static __inline void +ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count) +{ + int i; + + /* + * There is probably a more efficient way to do this on Linux + * but we don't use this for anything speed critical and this + * should work. + */ + for (i = 0; i < count; i++) + ahd_outb(ahd, port, *array++); +} + +static __inline void +ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count) +{ + int i; + + /* + * There is probably a more efficient way to do this on Linux + * but we don't use this for anything speed critical and this + * should work. + */ + for (i = 0; i < count; i++) + *array++ = ahd_inb(ahd, port); +} + +/**************************** Initialization **********************************/ +int ahd_linux_register_host(struct ahd_softc *, + Scsi_Host_Template *); + +uint64_t ahd_linux_get_memsize(void); + +/*************************** Pretty Printing **********************************/ +struct info_str { + char *buffer; + int length; + off_t offset; + int pos; +}; + +void ahd_format_transinfo(struct info_str *info, + struct ahd_transinfo *tinfo); + +/******************************** Locking *************************************/ +/* Lock protecting internal data structures */ +static __inline void ahd_lockinit(struct ahd_softc *); +static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags); +static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags); + +/* Lock acquisition and release of the above lock in midlayer entry points. */ +static __inline void ahd_midlayer_entrypoint_lock(struct ahd_softc *, + unsigned long *flags); +static __inline void ahd_midlayer_entrypoint_unlock(struct ahd_softc *, + unsigned long *flags); + +/* Lock held during command compeletion to the upper layer */ +static __inline void ahd_done_lockinit(struct ahd_softc *); +static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags); +static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags); + +/* Lock held during ahd_list manipulation and ahd softc frees */ +extern spinlock_t ahd_list_spinlock; +static __inline void ahd_list_lockinit(void); +static __inline void ahd_list_lock(unsigned long *flags); +static __inline void ahd_list_unlock(unsigned long *flags); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) +static __inline void +ahd_lockinit(struct ahd_softc *ahd) +{ + spin_lock_init(&ahd->platform_data->spin_lock); +} + +static __inline void +ahd_lock(struct ahd_softc *ahd, unsigned long *flags) +{ + *flags = 0; + spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags); +} + +static __inline void +ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ + spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); +} + +static __inline void +ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags) +{ + /* + * In 2.5.X, the midlayer takes our lock just before + * calling us, so avoid locking again. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, flags); +#endif +} + +static __inline void +ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ + /* + * In 2.5.X, the midlayer takes our lock just before + * calling us and unlocks when we return, so let it do the unlock. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, flags); +#endif +} + +static __inline void +ahd_done_lockinit(struct ahd_softc *ahd) +{ + /* + * In 2.5.X, our own lock is held during completions. + * In previous versions, the io_request_lock is used. + * In either case, we can't initialize this lock again. + */ +} + +static __inline void +ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + *flags = 0; + spin_lock_irqsave(&io_request_lock, *flags); +#endif +} + +static __inline void +ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irqrestore(&io_request_lock, *flags); +#endif +} + +static __inline void +ahd_list_lockinit() +{ + spin_lock_init(&ahd_list_spinlock); +} + +static __inline void +ahd_list_lock(unsigned long *flags) +{ + *flags = 0; + spin_lock_irqsave(&ahd_list_spinlock, *flags); +} + +static __inline void +ahd_list_unlock(unsigned long *flags) +{ + spin_unlock_irqrestore(&ahd_list_spinlock, *flags); +} + +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ + +ahd_lockinit(struct ahd_softc *ahd) +{ +} + +static __inline void +ahd_lock(struct ahd_softc *ahd, unsigned long *flags) +{ + *flags = 0; + save_flags(*flags); + cli(); +} + +static __inline void +ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ + restore_flags(*flags); +} + +ahd_done_lockinit(struct ahd_softc *ahd) +{ +} + +static __inline void +ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) +{ + /* + * The done lock is always held while + * the ahd lock is held so blocking + * interrupts again would have no effect. + */ +} + +static __inline void +ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ +} + +static __inline void +ahd_list_lockinit() +{ +} + +static __inline void +ahd_list_lock(unsigned long *flags) +{ + *flags = 0; + save_flags(*flags); + cli(); +} + +static __inline void +ahd_list_unlock(unsigned long *flags) +{ + restore_flags(*flags); +} +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ + +/******************************* PCI Definitions ******************************/ +/* + * PCIM_xxx: mask to locate subfield in register + * PCIR_xxx: config register offset + * PCIC_xxx: device class + * PCIS_xxx: device subclass + * PCIP_xxx: device programming interface + * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) + * PCID_xxx: device ID + */ +#define PCIR_DEVVENDOR 0x00 +#define PCIR_VENDOR 0x00 +#define PCIR_DEVICE 0x02 +#define PCIR_COMMAND 0x04 +#define PCIM_CMD_PORTEN 0x0001 +#define PCIM_CMD_MEMEN 0x0002 +#define PCIM_CMD_BUSMASTEREN 0x0004 +#define PCIM_CMD_MWRICEN 0x0010 +#define PCIM_CMD_PERRESPEN 0x0040 +#define PCIM_CMD_SERRESPEN 0x0100 +#define PCIR_STATUS 0x06 +#define PCIR_REVID 0x08 +#define PCIR_PROGIF 0x09 +#define PCIR_SUBCLASS 0x0a +#define PCIR_CLASS 0x0b +#define PCIR_CACHELNSZ 0x0c +#define PCIR_LATTIMER 0x0d +#define PCIR_HEADERTYPE 0x0e +#define PCIM_MFDEV 0x80 +#define PCIR_BIST 0x0f +#define PCIR_CAP_PTR 0x34 + +/* config registers for header type 0 devices */ +#define PCIR_MAPS 0x10 +#define PCIR_SUBVEND_0 0x2c +#define PCIR_SUBDEV_0 0x2e + +/****************************** PCI-X definitions *****************************/ +#define PCIXR_COMMAND 0x96 +#define PCIXR_DEVADDR 0x98 +#define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */ +#define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */ +#define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */ +#define PCIXR_STATUS 0x9A +#define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */ +#define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */ +#define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */ +#define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */ +#define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */ +#define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */ +#define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */ +#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ +#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +extern struct pci_driver aic79xx_pci_driver; +#endif + +typedef enum +{ + AHD_POWER_STATE_D0, + AHD_POWER_STATE_D1, + AHD_POWER_STATE_D2, + AHD_POWER_STATE_D3 +} ahd_power_state; + +void ahd_power_state_change(struct ahd_softc *ahd, + ahd_power_state new_state); + +/******************************* PCI Routines *********************************/ +/* + * We need to use the bios32.h routines if we are kernel version 2.1.92 or less. + */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) +#if defined(__sparc_v9__) || defined(__powerpc__) +#error "PPC and Sparc platforms are only support under 2.1.92 and above" +#endif +#include +#endif + +int ahd_linux_pci_probe(Scsi_Host_Template *); +int ahd_pci_map_registers(struct ahd_softc *ahd); +int ahd_pci_map_int(struct ahd_softc *ahd); + +static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci, + int reg, int width); + +static __inline uint32_t +ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width) +{ + switch (width) { + case 1: + { + uint8_t retval; + + pci_read_config_byte(pci, reg, &retval); + return (retval); + } + case 2: + { + uint16_t retval; + pci_read_config_word(pci, reg, &retval); + return (retval); + } + case 4: + { + uint32_t retval; + pci_read_config_dword(pci, reg, &retval); + return (retval); + } + default: + panic("ahd_pci_read_config: Read size too big"); + /* NOTREACHED */ + return (0); + } +} + +static __inline void ahd_pci_write_config(ahd_dev_softc_t pci, + int reg, uint32_t value, + int width); + +static __inline void +ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width) +{ + switch (width) { + case 1: + pci_write_config_byte(pci, reg, value); + break; + case 2: + pci_write_config_word(pci, reg, value); + break; + case 4: + pci_write_config_dword(pci, reg, value); + break; + default: + panic("ahd_pci_write_config: Write size too big"); + /* NOTREACHED */ + } +} + +static __inline int ahd_get_pci_function(ahd_dev_softc_t); +static __inline int +ahd_get_pci_function(ahd_dev_softc_t pci) +{ + return (PCI_FUNC(pci->devfn)); +} + +static __inline int ahd_get_pci_slot(ahd_dev_softc_t); +static __inline int +ahd_get_pci_slot(ahd_dev_softc_t pci) +{ + return (PCI_SLOT(pci->devfn)); +} + +static __inline int ahd_get_pci_bus(ahd_dev_softc_t); +static __inline int +ahd_get_pci_bus(ahd_dev_softc_t pci) +{ + return (pci->bus->number); +} + +static __inline void ahd_flush_device_writes(struct ahd_softc *); +static __inline void +ahd_flush_device_writes(struct ahd_softc *ahd) +{ + /* XXX Is this sufficient for all architectures??? */ + ahd_inb(ahd, INTSTAT); +} + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0) +#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg) +#define pci_unmap_sg(pdev, sg_list, nseg, direction) +#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address)) +#define sg_dma_len(sg) ((sg)->length) +#define pci_map_single(pdev, buffer, bufflen, direction) \ + (VIRT_TO_BUS(buffer)) +#define pci_unmap_single(pdev, buffer, buflen, direction) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) +#define ahd_pci_set_dma_mask pci_set_dma_mask +#else +/* + * Always "return" 0 for success. + */ +#define ahd_pci_set_dma_mask(dev_softc, mask) \ + (((dev_softc)->dma_mask = mask) && 0) +#endif +/**************************** Proc FS Support *********************************/ +int ahd_linux_proc_info(char *, char **, off_t, int, int, int); + +/*************************** Domain Validation ********************************/ +#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) +#define AHD_DV_SIMQ_FROZEN(ahd) \ + ((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0) \ + && (ahd)->platform_data->qfrozen == 1) + +/*********************** Transaction Access Wrappers **************************/ +static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); +static __inline void ahd_set_transaction_status(struct scb *, uint32_t); +static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); +static __inline void ahd_set_scsi_status(struct scb *, uint32_t); +static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahd_get_transaction_status(struct scb *); +static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahd_get_scsi_status(struct scb *); +static __inline void ahd_set_transaction_tag(struct scb *, int, u_int); +static __inline u_long ahd_get_transfer_length(struct scb *); +static __inline int ahd_get_transfer_dir(struct scb *); +static __inline void ahd_set_residual(struct scb *, u_long); +static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid); +static __inline u_long ahd_get_residual(struct scb *); +static __inline u_long ahd_get_sense_residual(struct scb *); +static __inline int ahd_perform_autosense(struct scb *); +static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *, + struct scb *); +static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *, + struct ahd_devinfo *); +static __inline void ahd_platform_scb_free(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_freeze_scb(struct scb *scb); + +static __inline +void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~(CAM_STATUS_MASK << 16); + cmd->result |= status << 16; +} + +static __inline +void ahd_set_transaction_status(struct scb *scb, uint32_t status) +{ + ahd_cmd_set_transaction_status(scb->io_ctx,status); +} + +static __inline +void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~0xFFFF; + cmd->result |= status; +} + +static __inline +void ahd_set_scsi_status(struct scb *scb, uint32_t status) +{ + ahd_cmd_set_scsi_status(scb->io_ctx, status); +} + +static __inline +uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd) +{ + return ((cmd->result >> 16) & CAM_STATUS_MASK); +} + +static __inline +uint32_t ahd_get_transaction_status(struct scb *scb) +{ + return (ahd_cmd_get_transaction_status(scb->io_ctx)); +} + +static __inline +uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd) +{ + return (cmd->result & 0xFFFF); +} + +static __inline +uint32_t ahd_get_scsi_status(struct scb *scb) +{ + return (ahd_cmd_get_scsi_status(scb->io_ctx)); +} + +static __inline +void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type) +{ + /* + * Nothing to do for linux as the incoming transaction + * has no concept of tag/non tagged, etc. + */ +} + +static __inline +u_long ahd_get_transfer_length(struct scb *scb) +{ + return (scb->platform_data->xfer_len); +} + +static __inline +int ahd_get_transfer_dir(struct scb *scb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40) + return (scb->io_ctx->sc_data_direction); +#else + if (scb->io_ctx->bufflen == 0) + return (CAM_DIR_NONE); + + switch(scb->io_ctx->cmnd[0]) { + case 0x08: /* READ(6) */ + case 0x28: /* READ(10) */ + case 0xA8: /* READ(12) */ + return (CAM_DIR_IN); + case 0x0A: /* WRITE(6) */ + case 0x2A: /* WRITE(10) */ + case 0xAA: /* WRITE(12) */ + return (CAM_DIR_OUT); + default: + return (CAM_DIR_NONE); + } +#endif +} + +static __inline +void ahd_set_residual(struct scb *scb, u_long resid) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + scb->io_ctx->resid = resid; +#else + scb->platform_data->resid = resid; +#endif +} + +static __inline +void ahd_set_sense_residual(struct scb *scb, u_long resid) +{ + scb->platform_data->sense_resid = resid; +} + +static __inline +u_long ahd_get_residual(struct scb *scb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + return (scb->io_ctx->resid); +#else + return (scb->platform_data->resid); +#endif +} + +static __inline +u_long ahd_get_sense_residual(struct scb *scb) +{ + return (scb->platform_data->sense_resid); +} + +static __inline +int ahd_perform_autosense(struct scb *scb) +{ + /* + * We always perform autosense in Linux. + * On other platforms this is set on a + * per-transaction basis. + */ + return (1); +} + +static __inline uint32_t +ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb) +{ + return (sizeof(struct scsi_sense_data)); +} + +static __inline void +ahd_notify_xfer_settings_change(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo) +{ + /* Nothing to do here for linux */ +} + +static __inline void +ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb) +{ + ahd->flags &= ~AHD_RESOURCE_SHORTAGE; +} + +int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); +void ahd_platform_free(struct ahd_softc *ahd); +void ahd_platform_init(struct ahd_softc *ahd); +void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb); +void ahd_freeze_simq(struct ahd_softc *ahd); +void ahd_release_simq(struct ahd_softc *ahd); + +static __inline void +ahd_freeze_scb(struct scb *scb) +{ + if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { + scb->io_ctx->result |= CAM_DEV_QFRZN << 16; + scb->platform_data->dev->qfrozen++; + } +} + +void ahd_platform_set_tags(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, ahd_queue_alg); +int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status); +void ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); +void ahd_platform_flushwork(struct ahd_softc *ahd); +int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *); +void ahd_done(struct ahd_softc*, struct scb*); +void ahd_send_async(struct ahd_softc *, char channel, + u_int target, u_int lun, ac_code, void *); +void ahd_print_path(struct ahd_softc *, struct scb *); +void ahd_platform_dump_card_state(struct ahd_softc *ahd); + +#ifdef CONFIG_PCI +#define AHD_PCI_CONFIG 1 +#else +#define AHD_PCI_CONFIG 0 +#endif +#define bootverbose aic79xx_verbose +extern int aic79xx_verbose; +#endif /* _AIC79XX_LINUX_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_osm_pci.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_osm_pci.c --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,432 @@ +/* + * Linux driver attachment glue for PCI based U320 controllers. + * + * Copyright (c) 2000-2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#20 $ + */ + +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +struct pci_device_id +{ +}; +#endif + +static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, + u_long *base, u_long *base2); +static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, + u_long *bus_addr, + uint8_t **maddr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); + +/* We do our own ID filtering. So, grab all SCSI storage class devices. */ +static struct pci_device_id ahd_linux_pci_id_table[] = { + { + 0x9005, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0 + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); + +struct pci_driver aic79xx_pci_driver = { + name: "aic79xx", + probe: ahd_linux_pci_dev_probe, + remove: ahd_linux_pci_dev_remove, + id_table: ahd_linux_pci_id_table +}; + +static void +ahd_linux_pci_dev_remove(struct pci_dev *pdev) +{ + struct ahd_softc *ahd; + u_long l; + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahd_list_lock(&l); + ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev)); + if (ahd != NULL) { + u_long s; + + ahd_lock(ahd, &s); + ahd_intr_enable(ahd, FALSE); + ahd_unlock(ahd, &s); + ahd_free(ahd); + } + ahd_list_unlock(&l); +} +#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */ + +static int +ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + char buf[80]; + struct ahd_softc *ahd; + ahd_dev_softc_t pci; + struct ahd_pci_identity *entry; + char *name; + int error; + + /* + * Some BIOSen report the same device multiple times. + */ + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + struct pci_dev *probed_pdev; + + probed_pdev = ahd->dev_softc; + if (probed_pdev->bus->number == pdev->bus->number + && probed_pdev->devfn == pdev->devfn) + break; + } + if (ahd != NULL) { + /* Skip duplicate. */ + return (-ENODEV); + } + + pci = pdev; + entry = ahd_find_pci_device(pci); + if (entry == NULL) + return (-ENODEV); + + /* + * Allocate a softc for this card and + * set it up for attachment by our + * common detect routine. + */ + sprintf(buf, "ahd_pci:%d:%d:%d", + ahd_get_pci_bus(pci), + ahd_get_pci_slot(pci), + ahd_get_pci_function(pci)); + name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (name == NULL) + return (-ENOMEM); + strcpy(name, buf); + ahd = ahd_alloc(NULL, name); + if (ahd == NULL) + return (-ENOMEM); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + if (pci_enable_device(pdev)) { + ahd_free(ahd); + return (-ENODEV); + } + pci_set_master(pdev); + + if (sizeof(bus_addr_t) > 4) { + uint64_t memsize; + + memsize = ahd_linux_get_memsize(); + if (memsize >= 0x8000000000 + && ahd_pci_set_dma_mask(pdev, 0xFFFFFFFFFFFFFFFFULL) == 0) { + ahd->flags |= AHD_64BIT_ADDRESSING; + ahd->platform_data->hw_dma_mask = + (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0); + } else if (memsize > 0x80000000 + && ahd_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) { + ahd->flags |= AHD_39BIT_ADDRESSING; + ahd->platform_data->hw_dma_mask = + (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); + } + } else { + ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF); + ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; + } +#endif + ahd->dev_softc = pci; + error = ahd_pci_config(ahd, entry); + if (error != 0) { + ahd_free(ahd); + return (-error); + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pci_set_drvdata(pdev, ahd); + if (aic79xx_detect_complete) + ahd_linux_register_host(ahd, &aic79xx_driver_template); +#endif + return (0); +} + +int +ahd_linux_pci_probe(Scsi_Host_Template *template) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + return (pci_module_init(&aic79xx_pci_driver)); +#else + struct pci_dev *pdev; + u_int class; + int found; + + /* If we don't have a PCI bus, we can't find any adapters. */ + if (pci_present() == 0) + return (0); + + found = 0; + pdev = NULL; + class = PCI_CLASS_STORAGE_SCSI << 8; + while ((pdev = pci_find_class(class, pdev)) != NULL) { + ahd_dev_softc_t pci; + int error; + + pci = pdev; + error = ahd_linux_pci_dev_probe(pdev, /*pci_devid*/NULL); + if (error == 0) + found++; + } + return (found); +#endif +} + +static int +ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, + u_long *base2) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + *base = pci_resource_start(ahd->dev_softc, 0); + /* + * This is really the 3rd bar and should be at index 2, + * but the Linux PCI code doesn't know how to "count" 64bit + * bars. + */ + *base2 = pci_resource_start(ahd->dev_softc, 3); +#else + *base = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR0, 4); + *base2 = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR1, 4); + *base &= PCI_BASE_ADDRESS_IO_MASK; + *base2 &= PCI_BASE_ADDRESS_IO_MASK; +#endif + if (*base == 0 || *base2 == 0) + return (ENOMEM); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + if (check_region(*base, 256) != 0 + || check_region(*base2, 256) != 0) + return (ENOMEM); + request_region(*base, 256, "aic79xx"); + request_region(*base2, 256, "aic79xx"); +#else + if (request_region(*base, 256, "aic79xx") == 0) + return (ENOMEM); + if (request_region(*base2, 256, "aic79xx") == 0) { + release_region(*base2, 256); + return (ENOMEM); + } +#endif + return (0); +} + +static int +ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, + u_long *bus_addr, + uint8_t **maddr) +{ + u_long start; + u_long base_page; + u_long base_offset; + int error; + + if (aic79xx_allow_memio == 0) + return (ENOMEM); + + if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0) + return (ENOMEM); + + error = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + start = pci_resource_start(ahd->dev_softc, 1); + base_page = start & PAGE_MASK; + base_offset = start - base_page; +#else + start = ahd_pci_read_config(ahd->dev_softc, PCIR_MAPS+4, 4); + base_offset = start & PCI_BASE_ADDRESS_MEM_MASK; + base_page = base_offset & PAGE_MASK; + base_offset -= base_page; +#endif + if (start != 0) { + *bus_addr = start; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + if (request_mem_region(start, 0x1000, "aic79xx") == 0) + error = ENOMEM; +#endif + if (error == 0) { + *maddr = ioremap_nocache(base_page, base_offset + 256); + if (*maddr == NULL) { + error = ENOMEM; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(start, 0x1000); +#endif + } else + *maddr += base_offset; + } + } else + error = ENOMEM; + return (error); +} + +int +ahd_pci_map_registers(struct ahd_softc *ahd) +{ + uint32_t command; + u_long base; + uint8_t *maddr; + int error; + + /* + * If its allowed, we prefer memory mapped access. + */ + command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4); + command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); + base = 0; + maddr = NULL; +#ifdef MMAPIO + error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr); + if (error == 0) { + ahd->platform_data->mem_busaddr = base; + ahd->tags[0] = BUS_SPACE_MEMIO; + ahd->bshs[0].maddr = maddr; + ahd->tags[1] = BUS_SPACE_MEMIO; + ahd->bshs[1].maddr = maddr + 0x100; + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + command | PCIM_CMD_MEMEN, 4); + + if (ahd_pci_test_register_access(ahd) != 0) { + + printf("aic79xx: PCI Device %d:%d:%d " + "failed memory mapped test. Using PIO.\n", + ahd_get_pci_bus(ahd->dev_softc), + ahd_get_pci_slot(ahd->dev_softc), + ahd_get_pci_function(ahd->dev_softc)); + iounmap((void *)((u_long)maddr & PAGE_MASK)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(ahd->platform_data->mem_busaddr, + 0x1000); +#endif + ahd->bshs[0].maddr = NULL; + maddr = NULL; + } else + command |= PCIM_CMD_MEMEN; + } else if (bootverbose) { + printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx " + "unavailable. Cannot memory map device.\n", + ahd_get_pci_bus(ahd->dev_softc), + ahd_get_pci_slot(ahd->dev_softc), + ahd_get_pci_function(ahd->dev_softc), + base); + } +#endif + + if (maddr == NULL) { + u_long base2; + + error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2); + if (error == 0) { + ahd->tags[0] = BUS_SPACE_PIO; + ahd->tags[1] = BUS_SPACE_PIO; + ahd->bshs[0].ioport = base; + ahd->bshs[1].ioport = base2; + command |= PCIM_CMD_PORTEN; + } else { + printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx" + "unavailable. Cannot map device.\n", + ahd_get_pci_bus(ahd->dev_softc), + ahd_get_pci_slot(ahd->dev_softc), + ahd_get_pci_function(ahd->dev_softc), + base, base2); + } + } + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); + return (error); +} + +int +ahd_pci_map_int(struct ahd_softc *ahd) +{ + int error; + + error = request_irq(ahd->dev_softc->irq, ahd_linux_isr, + SA_SHIRQ, "aic79xx", ahd); + if (error == 0) + ahd->platform_data->irq = ahd->dev_softc->irq; + + return (-error); +} + +void +ahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pci_set_power_state(ahd->dev_softc, new_state); +#else + uint32_t cap; + u_int cap_offset; + + /* + * Traverse the capability list looking for + * the power management capability. + */ + cap = 0; + cap_offset = ahd_pci_read_config(ahd->dev_softc, + PCIR_CAP_PTR, /*bytes*/1); + while (cap_offset != 0) { + + cap = ahd_pci_read_config(ahd->dev_softc, + cap_offset, /*bytes*/4); + if ((cap & 0xFF) == 1 + && ((cap >> 16) & 0x3) > 0) { + uint32_t pm_control; + + pm_control = ahd_pci_read_config(ahd->dev_softc, + cap_offset + 4, + /*bytes*/4); + pm_control &= ~0x3; + pm_control |= new_state; + ahd_pci_write_config(ahd->dev_softc, + cap_offset + 4, + pm_control, /*bytes*/2); + break; + } + cap_offset = (cap >> 8) & 0xFF; + } +#endif +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_pci.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_pci.c --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_pci.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,923 @@ +/* + * Product specific probe and attach routines for: + * aic7901 and aic7902 SCSI controllers + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#61 $ + * + * $FreeBSD$ + */ + +#ifdef __linux__ +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" +#else +#include +#include +#endif + +static __inline uint64_t +ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) +{ + uint64_t id; + + id = subvendor + | (subdevice << 16) + | ((uint64_t)vendor << 32) + | ((uint64_t)device << 48); + + return (id); +} + +#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull +#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull +#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull + +#define ID_AIC7901 0x800F9005FFFF9005ull +#define ID_AIC7901A 0x801E9005FFFF9005ull +#define ID_AIC7901A_IROC 0x809E9005FFFF9005ull +#define ID_AHA_29320A 0x8000900500609005ull +#define ID_AHA_29320LP 0x8014900500449005ull +#define ID_AHA_29320LP_IROC 0x8094900500449005ull + +#define ID_AIC7902 0x801F9005FFFF9005ull +#define ID_AIC7902_IROC 0x809F9005FFFF9005ull +#define ID_AIC7902_B 0x801D9005FFFF9005ull +#define ID_AIC7902_B_IROC 0x809D9005FFFF9005ull +#define ID_AHA_39320 0x8010900500409005ull +#define ID_AHA_39320D 0x8011900500419005ull +#define ID_AHA_39320D_B 0x801C900500419005ull +#define ID_AHA_39320D_HP 0x8011900500AC0E11ull +#define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull +#define ID_AHA_29320 0x8012900500429005ull +#define ID_AHA_29320B 0x8013900500439005ull +#define ID_AIC7902_PCI_REV_A4 0x3 +#define ID_AIC7902_PCI_REV_B0 0x10 +#define SUBID_HP 0x0E11 + +#define DEVID_9005_TYPE(id) ((id) & 0xF) +#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ +#define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */ +#define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */ +#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */ + +#define DEVID_9005_MFUNC(id) ((id) & 0x10) + +#define DEVID_9005_PACKETIZED(id) ((id) & 0x8000) + +#define SUBID_9005_TYPE(id) ((id) & 0xF) +#define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */ +#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */ + +#define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0) + +#define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20) + +#define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6) +#define SUBID_9005_SEEPTYPE_NONE 0x0 +#define SUBID_9005_SEEPTYPE_4K 0x1 + +static ahd_device_setup_t ahd_aic7901A_setup; +static ahd_device_setup_t ahd_aic7902_setup; + +struct ahd_pci_identity ahd_pci_ident_table [] = +{ + /* aic7901A based controllers */ + { + ID_AHA_29320LP, + ID_ALL_MASK, + "Adaptec 29320LP Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + { + ID_AHA_29320A, + ID_ALL_MASK, + "Adaptec 29320A Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + /* aic7902 based controllers */ + { + ID_AHA_39320, + ID_ALL_MASK, + "Adaptec 39320 Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D, + ID_ALL_MASK, + "Adaptec 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D_HP, + ID_ALL_MASK, + "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D_B, + ID_ALL_MASK, + "Adaptec 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D_B_HP, + ID_ALL_MASK, + "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_29320, + ID_ALL_MASK, + "Adaptec 29320 Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_29320B, + ID_ALL_MASK, + "Adaptec 29320B Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + /* Generic chip probes for devices we don't know 'exactly' */ + { + ID_AIC7901A & ID_DEV_VENDOR_MASK, + ID_DEV_VENDOR_MASK, + "Adaptec AIC7901A Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + { + ID_AIC7902 & ID_9005_GENERIC_MASK, + ID_9005_GENERIC_MASK, + "Adaptec AIC7902 Ultra320 SCSI adapter", + ahd_aic7902_setup + } +}; + +const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table); + +#define DEVCONFIG 0x40 +#define PCIXINITPAT 0x0000E000ul +#define PCIXINIT_PCI33_66 0x0000E000ul +#define PCIXINIT_PCIX50_66 0x0000C000ul +#define PCIXINIT_PCIX66_100 0x0000A000ul +#define PCIXINIT_PCIX100_133 0x00008000ul +#define PCI_BUS_MODES_INDEX(devconfig) \ + (((devconfig) & PCIXINITPAT) >> 13) +static const char *pci_bus_modes[] = +{ + "PCI bus mode unknown", + "PCI bus mode unknown", + "PCI bus mode unknown", + "PCI bus mode unknown", + "PCI-X 101-133Mhz", + "PCI-X 67-100Mhz", + "PCI-X 50-66Mhz", + "PCI 33 or 66Mhz" +}; + +#define TESTMODE 0x00000800ul +#define IRDY_RST 0x00000200ul +#define FRAME_RST 0x00000100ul +#define PCI64BIT 0x00000080ul +#define MRDCEN 0x00000040ul +#define ENDIANSEL 0x00000020ul +#define MIXQWENDIANEN 0x00000008ul +#define DACEN 0x00000004ul +#define STPWLEVEL 0x00000002ul +#define QWENDIANSEL 0x00000001ul + +#define DEVCONFIG1 0x44 +#define PREQDIS 0x01 + +#define CSIZE_LATTIME 0x0c +#define CACHESIZE 0x000000fful +#define LATTIME 0x0000ff00ul + +static int ahd_check_extport(struct ahd_softc *ahd); +static void ahd_configure_termination(struct ahd_softc *ahd, + u_int adapter_control); +static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); + +struct ahd_pci_identity * +ahd_find_pci_device(ahd_dev_softc_t pci) +{ + uint64_t full_id; + uint16_t device; + uint16_t vendor; + uint16_t subdevice; + uint16_t subvendor; + struct ahd_pci_identity *entry; + u_int i; + + vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2); + device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2); + subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2); + subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2); + full_id = ahd_compose_id(device, + vendor, + subdevice, + subvendor); + + for (i = 0; i < ahd_num_pci_devs; i++) { + entry = &ahd_pci_ident_table[i]; + if (entry->full_id == (full_id & entry->id_mask)) { + /* Honor exclusion entries. */ + if (entry->name == NULL) + return (NULL); + return (entry); + } + } + return (NULL); +} + +int +ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) +{ + struct scb_data *shared_scb_data; + u_long l; + u_int command; + uint32_t devconfig; + uint16_t subvendor; + int error; + + shared_scb_data = NULL; + ahd->description = entry->name; + /* + * Record if this is an HP board. + */ + subvendor = ahd_pci_read_config(ahd->dev_softc, + PCIR_SUBVEND_0, /*bytes*/2); + if (subvendor == SUBID_HP) + ahd->flags |= AHD_HP_BOARD; + + error = entry->setup(ahd); + if (error != 0) + return (error); + + devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); + if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) { + ahd->chip |= AHD_PCI; + /* Disable PCIX workarounds when running in PCI mode. */ + ahd->bugs &= ~AHD_PCIX_BUG_MASK; + } else { + ahd->chip |= AHD_PCIX; + } + ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)]; + + ahd_power_state_change(ahd, AHD_POWER_STATE_D0); + + error = ahd_pci_map_registers(ahd); + if (error != 0) + return (error); + + /* + * If we need to support high memory, enable dual + * address cycles. This bit must be set to enable + * high address bit generation even if we are on a + * 64bit bus (PCI64BIT set in devconfig). + */ + if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) { + uint32_t devconfig; + + if (bootverbose) + printf("%s: Enabling 39Bit Addressing\n", + ahd_name(ahd)); + devconfig = ahd_pci_read_config(ahd->dev_softc, + DEVCONFIG, /*bytes*/4); + devconfig |= DACEN; + ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, + devconfig, /*bytes*/4); + } + + /* Ensure busmastering is enabled */ + command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1); + command |= PCIM_CMD_BUSMASTEREN; + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/1); + + error = ahd_softc_init(ahd); + if (error != 0) + return (error); + + ahd->bus_intr = ahd_pci_intr; + + error = ahd_reset(ahd); + if (error != 0) + return (ENXIO); + + ahd->pci_cachesize = + ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, + /*bytes*/1) & CACHESIZE; + ahd->pci_cachesize *= 4; + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + /* See if we have a SEEPROM and perform auto-term */ + error = ahd_check_extport(ahd); + if (error != 0) + return (error); + + /* Core initialization */ + error = ahd_init(ahd); + if (error != 0) + return (error); + + /* + * Allow interrupts now that we are completely setup. + */ + error = ahd_pci_map_int(ahd); + if (error != 0) + return (error); + + ahd_list_lock(&l); + /* + * Link this softc in with all other ahd instances. + */ + ahd_softc_insert(ahd); + ahd_list_unlock(&l); + return (0); +} + +/* + * Perform some simple tests that should catch situations where + * our registers are invalidly mapped. + */ +int +ahd_pci_test_register_access(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + uint32_t cmd; + int error; + uint8_t hcntrl; + + saved_modes = ahd_save_modes(ahd); + error = EIO; + + /* + * Enable PCI error interrupt status, but suppress NMIs + * generated by SERR raised due to target aborts. + */ + cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); + + /* + * First a simple test to see if any + * registers can be read. Reading + * HCNTRL has no side effects and has + * at least one bit that is guaranteed to + * be zero so it is a good register to + * use for this test. + */ + hcntrl = ahd_inb(ahd, HCNTRL); + if (hcntrl == 0xFF) + goto fail; + + /* + * Next create a situation where write combining + * or read prefetching could be initiated by the + * CPU or host bridge. Our device does not support + * either, so look for data corruption and/or flaged + * PCI errors. + */ + ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); + while (ahd_is_paused(ahd) == 0) + ; + ahd_outb(ahd, SEQCTL0, PERRORDIS); + ahd_outl(ahd, SRAM_BASE, 0x5aa555aa); + if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa) + goto fail; + + if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { + u_int targpcistat; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + targpcistat = ahd_inb(ahd, TARGPCISTAT); + if ((targpcistat & STA) != 0) + goto fail; + } + + error = 0; + +fail: + if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { + u_int targpcistat; + u_int pci_status1; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + targpcistat = ahd_inb(ahd, TARGPCISTAT); + + /* Silently clear any latched errors. */ + ahd_outb(ahd, TARGPCISTAT, targpcistat); + pci_status1 = ahd_pci_read_config(ahd->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + pci_status1, /*bytes*/1); + ahd_outb(ahd, CLRINT, CLRPCIINT); + } + + ahd_restore_modes(ahd, saved_modes); + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); + return (error); +} + +/* + * Check the external port logic for a serial eeprom + * and termination/cable detection contrls. + */ +static int +ahd_check_extport(struct ahd_softc *ahd) +{ + struct seeprom_config *sc; + u_int adapter_control; + int have_seeprom; + int error; + + sc = ahd->seep_config; + have_seeprom = ahd_acquire_seeprom(ahd); + if (have_seeprom) { + u_int start_addr; + + if (bootverbose) + printf("%s: Reading SEEPROM...", ahd_name(ahd)); + + /* Address is always in units of 16bit words */ + start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A'); + + error = ahd_read_seeprom(ahd, (uint16_t *)sc, + start_addr, sizeof(*sc)/2); + + if (error != 0) { + printf("Unable to read SEEPROM\n"); + have_seeprom = 0; + } else { + have_seeprom = ahd_verify_cksum(sc); + + if (bootverbose) { + if (have_seeprom == 0) + printf ("checksum error\n"); + else + printf ("done.\n"); + } + } + ahd_release_seeprom(ahd); + } + + if (!have_seeprom) { + u_int nvram_scb; + + /* + * Pull scratch ram settings and treat them as + * if they are the contents of an seeprom if + * the 'ADPT', 'BIOS', or 'ASPI' signature is found + * in SCB 0xFF. We manually compose the data as 16bit + * values to avoid endian issues. + */ + ahd_set_scbptr(ahd, 0xFF); + nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET); + if (nvram_scb != 0xFF + && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' + && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D' + && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' + && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T') + || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B' + && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I' + && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O' + && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S') + || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' + && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S' + && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' + && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) { + uint16_t *sc_data; + int i; + + ahd_set_scbptr(ahd, nvram_scb); + sc_data = (uint16_t *)sc; + for (i = 0; i < 64; i += 2) + *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i); + have_seeprom = ahd_verify_cksum(sc); + if (have_seeprom) + ahd->flags |= AHD_SCB_CONFIG_USED; + } + } + +#if AHD_DEBUG + if (have_seeprom != 0 + && (ahd_debug & AHD_DUMP_SEEPROM) != 0) { + uint8_t *sc_data; + int i; + + printf("%s: Seeprom Contents:", ahd_name(ahd)); + sc_data = (uint8_t *)sc; + for (i = 0; i < (sizeof(*sc)); i += 2) + printf("\n\t0x%.4x", + sc_data[i] | (sc_data[i+1] << 8)); + printf("\n"); + } +#endif + + if (!have_seeprom) { + if (bootverbose) + printf("%s: No SEEPROM available.\n", ahd_name(ahd)); + ahd->flags |= AHD_USEDEFAULTS; + error = ahd_default_config(ahd); + adapter_control = CFAUTOTERM|CFSEAUTOTERM; + free(ahd->seep_config, M_DEVBUF); + ahd->seep_config = NULL; + } else { + error = ahd_parse_cfgdata(ahd, sc); + adapter_control = sc->adapter_control; + } + if (error != 0) + return (error); + + ahd_configure_termination(ahd, adapter_control); + + return (0); +} + +static void +ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control) +{ + int error; + u_int sxfrctl1; + uint8_t termctl; + uint32_t devconfig; + + devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); + devconfig &= ~STPWLEVEL; + if ((ahd->flags & AHD_STPWLEVEL_A) != 0) + devconfig |= STPWLEVEL; + if (bootverbose) + printf("%s: STPWLEVEL is %s\n", + ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off"); + ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); + + /* Make sure current sensing is off. */ + if ((ahd->flags & AHD_CURRENT_SENSING) != 0) { + (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); + } + + /* + * Read to sense. Write to set. + */ + error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl); + if ((adapter_control & CFAUTOTERM) == 0) { + if (bootverbose) + printf("%s: Manual Primary Termination\n", + ahd_name(ahd)); + termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH); + if ((adapter_control & CFSTERM) != 0) + termctl |= FLX_TERMCTL_ENPRILOW; + if ((adapter_control & CFWSTERM) != 0) + termctl |= FLX_TERMCTL_ENPRIHIGH; + } else if (error != 0) { + printf("%s: Primary Auto-Term Sensing failed! " + "Using Defaults.\n", ahd_name(ahd)); + termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH; + } + + if ((adapter_control & CFSEAUTOTERM) == 0) { + if (bootverbose) + printf("%s: Manual Secondary Termination\n", + ahd_name(ahd)); + termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH); + if ((adapter_control & CFSELOWTERM) != 0) + termctl |= FLX_TERMCTL_ENSECLOW; + if ((adapter_control & CFSEHIGHTERM) != 0) + termctl |= FLX_TERMCTL_ENSECHIGH; + } else if (error != 0) { + printf("%s: Secondary Auto-Term Sensing failed! " + "Using Defaults.\n", ahd_name(ahd)); + termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH; + } + + /* + * Now set the termination based on what we found. + */ + sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN; + if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) { + ahd->flags |= AHD_TERM_ENB_A; + sxfrctl1 |= STPWEN; + } + /* Must set the latch once in order to be effective. */ + ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); + ahd_outb(ahd, SXFRCTL1, sxfrctl1); + + error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl); + if (error != 0) { + printf("%s: Unable to set termination settings!\n", + ahd_name(ahd)); + } else if (bootverbose) { + printf("%s: Primary High byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis"); + + printf("%s: Primary Low byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis"); + + printf("%s: Secondary High byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis"); + + printf("%s: Secondary Low byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis"); + } + return; +} + +#define DPE 0x80 +#define SSE 0x40 +#define RMA 0x20 +#define RTA 0x10 +#define STA 0x08 +#define DPR 0x01 + +static const char *split_status_source[] = +{ + "DFF0", + "DFF1", + "OVLY", + "CMC", +}; + +static const char *pci_status_source[] = +{ + "DFF0", + "DFF1", + "SG", + "CMC", + "OVLY", + "NONE", + "MSI", + "TARG" +}; + +static const char *split_status_strings[] = +{ + "%s: Received split response in %s.\n" + "%s: Received split completion error message in %s\n", + "%s: Receive overrun in %s\n", + "%s: Count not complete in %s\n", + "%s: Split completion data bucket in %s\n", + "%s: Split completion address error in %s\n", + "%s: Split completion byte count error in %s\n", + "%s: Signaled Target-abort to early terminate a split in %s\n", +}; + +static const char *pci_status_strings[] = +{ + "%s: Data Parity Error has been reported via PERR# in %s\n", + "%s: Target initial wait state error in %s\n", + "%s: Split completion read data parity error in %s\n", + "%s: Split completion address attribute parity error in %s\n", + "%s: Received a Target Abort in %s\n", + "%s: Received a Master Abort in %s\n", + "%s: Signal System Error Detected in %s\n", + "%s: Address or Write Phase Parity Error Detected in %s.\n" +}; + +void +ahd_pci_intr(struct ahd_softc *ahd) +{ + uint8_t pci_status[8]; + ahd_mode_state saved_modes; + u_int pci_status1; + u_int intstat; + u_int i; + u_int reg; + + intstat = ahd_inb(ahd, INTSTAT); + + if ((intstat & SPLTINT) != 0) + ahd_pci_split_intr(ahd, intstat); + + if ((intstat & PCIINT) == 0) + return; + + printf("%s: PCI error Interrupt\n", ahd_name(ahd)); + saved_modes = ahd_save_modes(ahd); + ahd_dump_card_state(ahd); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) { + + if (i == 5) + continue; + pci_status[i] = ahd_inb(ahd, reg); + /* Clear latched errors. So our interupt deasserts. */ + ahd_outb(ahd, reg, pci_status[i]); + } + + for (i = 0; i < 8; i++) { + u_int bit; + + if (i == 5) + continue; + + for (bit = 0; bit < 8; bit++) { + + if ((pci_status[i] & (0x1 << bit)) != 0) { + static const char *s; + + s = pci_status_strings[bit]; + if (i == 7/*TARG*/ && bit == 3) + s = "%s: Signaled Target Abort\n"; + printf(s, ahd_name(ahd), pci_status_source[i]); + } + } + } + pci_status1 = ahd_pci_read_config(ahd->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + pci_status1, /*bytes*/1); + ahd_restore_modes(ahd, saved_modes); + ahd_outb(ahd, CLRINT, CLRPCIINT); + ahd_unpause(ahd); +} + +static void +ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) +{ + uint8_t split_status[4]; + uint8_t split_status1[4]; + uint8_t sg_split_status[2]; + uint8_t sg_split_status1[2]; + ahd_mode_state saved_modes; + u_int i; + uint16_t pcix_status; + + /* + * Check for splits in all modes. Modes 0 and 1 + * additionally have SG engine splits to look at. + */ + pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS, + /*bytes*/2); + printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n", + ahd_name(ahd), pcix_status); + saved_modes = ahd_save_modes(ahd); + for (i = 0; i < 4; i++) { + ahd_set_modes(ahd, i, i); + + split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0); + split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1); + /* Clear latched errors. So our interupt deasserts. */ + ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]); + ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]); + if (i != 0) + continue; + sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0); + sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1); + /* Clear latched errors. So our interupt deasserts. */ + ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]); + ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]); + } + + for (i = 0; i < 4; i++) { + u_int bit; + + for (bit = 0; bit < 8; bit++) { + + if ((split_status[i] & (0x1 << bit)) != 0) { + static const char *s; + + s = split_status_strings[bit]; + printf(s, ahd_name(ahd), + split_status_source[i]); + } + + if (i != 0) + continue; + + if ((sg_split_status[i] & (0x1 << bit)) != 0) { + static const char *s; + + s = split_status_strings[bit]; + printf(s, ahd_name(ahd), "SG"); + } + } + } + /* + * Clear PCI-X status bits. + */ + ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS, + pcix_status, /*bytes*/2); + ahd_outb(ahd, CLRINT, CLRSPLTINT); + ahd_restore_modes(ahd, saved_modes); +} + +static int +ahd_aic7901A_setup(struct ahd_softc *ahd) +{ + int error; + + error = ahd_aic7902_setup(ahd); + if (error != 0) + return (error); + ahd->chip = AHD_AIC7901A; + return (0); +} + +static int +ahd_aic7902_setup(struct ahd_softc *ahd) +{ + ahd_dev_softc_t pci; + u_int rev; + + pci = ahd->dev_softc; + rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1); + if (rev < ID_AIC7902_PCI_REV_A4) { + printf("%s: Unable to attach to unsupported chip revision %d\n", + ahd_name(ahd), rev); + ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/1); + return (ENXIO); + } + ahd->channel = ahd_get_pci_function(pci) + 'A'; + ahd->chip = AHD_AIC7902; + ahd->features = AHD_AIC7902_FE; + if (rev < ID_AIC7902_PCI_REV_B0) { + /* + * Enable A series workarounds. + */ + ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG + | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG + | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG + | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG + | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG + | AHD_PCIX_CHIPRST_BUG|AHD_PKTIZED_STATUS_BUG + | AHD_PKT_LUN_BUG|AHD_MDFF_WSCBPTR_BUG + | AHD_REG_SLOW_SETTLE_BUG|AHD_SET_MODE_BUG + | AHD_BUSFREEREV_BUG|AHD_NONPACKFIFO_BUG + | AHD_PACED_NEGTABLE_BUG; + + /* + * IO Cell paramter setup. + */ + AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); + + if ((ahd->flags & AHD_HP_BOARD) == 0) + AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA); + } else { + u_int devconfig1; + + ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS + | AHD_NEW_DFCNTRL_OPTS; + ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG + | AHD_INTCOLLISION_BUG; + + /* + * IO Cell paramter setup. + */ + AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); + AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB); + AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF); + + /* + * Set the PREQDIS bit for H2B which disables some workaround + * that doesn't work on regular PCI busses. + * XXX - Find out exactly what this does from the hardware + * folks! + */ + devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1); + ahd_pci_write_config(pci, DEVCONFIG1, + devconfig1|PREQDIS, /*bytes*/1); + devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1); + } + + return (0); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_proc.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_proc.c --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_proc.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2000-2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * String handling code courtesy of Gerard Roudier's + * sym driver. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#11 $ + */ +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" + +static void copy_mem_info(struct info_str *info, char *data, int len); +static int copy_info(struct info_str *info, char *fmt, ...); +static void ahd_dump_target_state(struct ahd_softc *ahd, + struct info_str *info, + u_int our_id, char channel, + u_int target_id, u_int target_offset); +static void ahd_dump_device_state(struct info_str *info, + struct ahd_linux_device *dev); +static int ahd_proc_write_seeprom(struct ahd_softc *ahd, + char *buffer, int length); + +static void +copy_mem_info(struct info_str *info, char *data, int len) +{ + if (info->pos + len > info->offset + info->length) + len = info->offset + info->length - info->pos; + + if (info->pos + len < info->offset) { + info->pos += len; + return; + } + + if (info->pos < info->offset) { + off_t partial; + + partial = info->offset - info->pos; + data += partial; + info->pos += partial; + len -= partial; + } + + if (len > 0) { + memcpy(info->buffer, data, len); + info->pos += len; + info->buffer += len; + } +} + +static int +copy_info(struct info_str *info, char *fmt, ...) +{ + va_list args; + char buf[256]; + int len; + + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); + + copy_mem_info(info, buf, len); + return (len); +} + +void +ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) +{ + u_int speed; + u_int freq; + u_int mb; + + if (tinfo->period == AHD_PERIOD_UNKNOWN) { + copy_info(info, "Renegotiation Pending\n"); + return; + } + speed = 3300; + freq = 0; + if (tinfo->offset != 0) { + freq = aic_calc_syncsrate(tinfo->period); + speed = freq; + } + speed *= (0x01 << tinfo->width); + mb = speed / 1000; + if (mb > 0) + copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000); + else + copy_info(info, "%dKB/s transfers", speed); + + if (freq != 0) { + int printed_options; + + printed_options = 0; + copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000); + if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + copy_info(info, " DT"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + copy_info(info, "%s", printed_options ? "|IU" : " IU"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) { + copy_info(info, "%s", + printed_options ? "|RTI" : " RTI"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { + copy_info(info, "%s", + printed_options ? "|QAS" : " QAS"); + printed_options++; + } + } + + if (tinfo->width > 0) { + if (freq != 0) { + copy_info(info, ", "); + } else { + copy_info(info, " ("); + } + copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width)); + } else if (freq != 0) { + copy_info(info, ")"); + } + copy_info(info, "\n"); +} + +static void +ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, + u_int our_id, char channel, u_int target_id, + u_int target_offset) +{ + struct ahd_linux_target *targ; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + int lun; + + tinfo = ahd_fetch_transinfo(ahd, channel, our_id, + target_id, &tstate); + copy_info(info, "Channel %c Target %d Negotiation Settings\n", + channel, target_id); + copy_info(info, "\tUser: "); + ahd_format_transinfo(info, &tinfo->user); + targ = ahd->platform_data->targets[target_offset]; + if (targ == NULL) + return; + + copy_info(info, "\tGoal: "); + ahd_format_transinfo(info, &tinfo->goal); + copy_info(info, "\tCurr: "); + ahd_format_transinfo(info, &tinfo->curr); + copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected); + + for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + struct ahd_linux_device *dev; + + dev = targ->devices[lun]; + + if (dev == NULL) + continue; + + ahd_dump_device_state(info, dev); + } +} + +static void +ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev) +{ + copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", + dev->target->channel + 'A', dev->target->target, dev->lun); + + copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); + copy_info(info, "\t\tCommands Active %d\n", dev->active); + copy_info(info, "\t\tCommand Openings %d\n", dev->openings); + copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags); + copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); +} + +static int +ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length) +{ + ahd_mode_state saved_modes; + int have_seeprom; + u_long s; + int paused; + int written; + + /* Default to failure. */ + written = -EINVAL; + ahd_lock(ahd, &s); + paused = ahd_is_paused(ahd); + if (!paused) + ahd_pause(ahd); + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + if (length != sizeof(struct seeprom_config)) { + printf("ahd_proc_write_seeprom: incorrect buffer size\n"); + goto done; + } + + have_seeprom = ahd_verify_cksum((struct seeprom_config*)buffer); + if (have_seeprom == 0) { + printf("ahd_proc_write_seeprom: cksum verification failed\n"); + goto done; + } + + have_seeprom = ahd_acquire_seeprom(ahd); + if (!have_seeprom) { + printf("ahd_proc_write_seeprom: No Serial EEPROM\n"); + goto done; + } else { + u_int start_addr; + + if (ahd->seep_config == NULL) { + ahd->seep_config = malloc(sizeof(*ahd->seep_config), + M_DEVBUF, M_NOWAIT); + if (ahd->seep_config == NULL) { + printf("aic79xx: Unable to allocate serial " + "eeprom buffer. Write failing\n"); + goto done; + } + } + printf("aic79xx: Writing Serial EEPROM\n"); + start_addr = 32 * (ahd->channel - 'A'); + ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr, + sizeof(struct seeprom_config)/2); + ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config, + start_addr, sizeof(struct seeprom_config)/2); + ahd_release_seeprom(ahd); + written = length; + } + +done: + ahd_restore_modes(ahd, saved_modes); + if (!paused) + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + return (written); +} +/* + * Return information to handle /proc support for the driver. + */ +int +ahd_linux_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout) +{ + struct ahd_softc *ahd; + struct info_str info; + char ahd_info[256]; + u_long l; + u_int max_targ; + u_int i; + int retval; + + retval = -EINVAL; + ahd_list_lock(&l); + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + if (ahd->platform_data->host->host_no == hostno) + break; + } + + if (ahd == NULL) + goto done; + + /* Has data been written to the file? */ + if (inout == TRUE) { + retval = ahd_proc_write_seeprom(ahd, buffer, length); + goto done; + } + + if (start) + *start = buffer; + + info.buffer = buffer; + info.length = length; + info.offset = offset; + info.pos = 0; + + copy_info(&info, "Adaptec AIC79xx driver version: %s\n", + AIC79XX_DRIVER_VERSION); + ahd_controller_info(ahd, ahd_info); + copy_info(&info, "%s\n\n", ahd_info); + + if (ahd->seep_config == NULL) + copy_info(&info, "No Serial EEPROM\n"); + else { + copy_info(&info, "Serial EEPROM:\n"); + for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) { + if (((i % 8) == 0) && (i != 0)) { + copy_info(&info, "\n"); + } + copy_info(&info, "0x%.4x ", + ((uint16_t*)ahd->seep_config)[i]); + } + copy_info(&info, "\n"); + } + copy_info(&info, "\n"); + + max_targ = 15; + if ((ahd->features & AHD_WIDE) == 0) + max_targ = 7; + + for (i = 0; i <= max_targ; i++) { + + ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', + /*target_id*/i, /*target_offset*/i); + } + retval = info.pos > info.offset ? info.pos - info.offset : 0; +done: + ahd_list_unlock(&l); + return (retval); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx.reg linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx.reg --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx.reg 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx.reg 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,3950 @@ +/* + * Aic79xx register and scratch ram definitions. + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $" + +/* + * This file is processed by the aic7xxx_asm utility for use in assembling + * firmware for the aic79xx family of SCSI host adapters as well as to generate + * a C header file for use in the kernel portion of the Aic79xx driver. + */ + +/* Register window Modes */ +#define M_DFF0 0 +#define M_DFF1 1 +#define M_CCHAN 2 +#define M_SCSI 3 +#define M_CFG 4 +#define M_DST_SHIFT 4 + +#define MK_MODE(src, dst) ((src) | ((dst) << M_DST_SHIFT)) +#define SET_MODE(src, dst) \ + SET_SRC_MODE src; \ + SET_DST_MODE dst; \ + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ + mvi MK_MODE(src, dst) call set_mode_work_around; \ + } else { \ + mvi MODE_PTR, MK_MODE(src, dst); \ + } + +#define TOGGLE_DFF_MODE \ + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ + call toggle_dff_mode_work_around; \ + } else { \ + xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); \ + } + +#define RESTORE_MODE(mode) \ + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ + mov mode call set_mode_work_around; \ + } else { \ + mov MODE_PTR, mode; \ + } + +#define SET_SEQINTCODE(code) \ + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { \ + mvi code call set_seqint_work_around; \ + } else { \ + mvi SEQINTCODE, code; \ + } + +/* + * Mode Pointer + * Controls which of the 5, 512byte, address spaces should be used + * as the source and destination of any register accesses in our + * register window. + */ +register MODE_PTR { + address 0x000 + access_mode RW + field DST_MODE 0x70 + field SRC_MODE 0x07 + mode_pointer +} + +const SRC_MODE_SHIFT 0 +const DST_MODE_SHIFT 4 + +/* + * Host Interrupt Status + */ +register INTSTAT { + address 0x001 + access_mode RW + field HWERRINT 0x80 + field BRKADRINT 0x40 + field SWTMINT 0x20 + field PCIINT 0x10 + field SCSIINT 0x08 + field SEQINT 0x04 + field CMDCMPLT 0x02 + field SPLTINT 0x01 + mask INT_PEND 0xFF +} + +/* + * Sequencer Interrupt Code + */ +register SEQINTCODE { + address 0x002 + access_mode RW + field { + NO_SEQINT, /* No seqint pending. */ + BAD_PHASE, /* unknown scsi bus phase */ + SEND_REJECT, /* sending a message reject */ + PROTO_VIOLATION, /* Protocol Violation */ + NO_MATCH, /* no cmd match for reconnect */ + IGN_WIDE_RES, /* Complex IGN Wide Res Msg */ + PDATA_REINIT, /* + * Returned to data phase + * that requires data + * transfer pointers to be + * recalculated from the + * transfer residual. + */ + HOST_MSG_LOOP, /* + * The bus is ready for the + * host to perform another + * message transaction. This + * mechanism is used for things + * like sync/wide negotiation + * that require a kernel based + * message state engine. + */ + BAD_STATUS, /* Bad status from target */ + DATA_OVERRUN, /* + * Target attempted to write + * beyond the bounds of its + * command. + */ + MKMSG_FAILED, /* + * Target completed command + * without honoring our ATN + * request to issue a message. + */ + MISSED_BUSFREE, /* + * The sequencer never saw + * the bus go free after + * either a command complete + * or disconnect message. + */ + DUMP_CARD_STATE, + ILLEGAL_PHASE, + INVALID_SEQINT, + CFG4ISTAT_INTR, + STATUS_OVERRUN, + CFG4OVERRUN, + ENTERING_NONPACK, + TASKMGMT_FUNC_COMPLETE, /* + * Task management function + * request completed with + * an expected busfree. + */ + TASKMGMT_CMD_CMPLT_OKAY, /* + * A command with a non-zero + * task management function + * has completed via the normal + * command completion method + * for commands with a zero + * task management function. + * This happens when an attempt + * to abort a command loses + * the race for the command to + * complete normally. + */ + TRACEPOINT0, + TRACEPOINT1, + TRACEPOINT2, + TRACEPOINT3, + SAW_HWERR + } +} + +/* + * Clear Host Interrupt + */ +register CLRINT { + address 0x003 + access_mode WO + field CLRHWERRINT 0x80 /* Rev B or greater */ + field CLRBRKADRINT 0x40 + field CLRSWTMINT 0x20 + field CLRPCIINT 0x10 + field CLRSCSIINT 0x08 + field CLRSEQINT 0x04 + field CLRCMDINT 0x02 + field CLRSPLTINT 0x01 +} + +/* + * Error Register + */ +register ERROR { + address 0x004 + access_mode RO + field CIOPARERR 0x80 + field CIOACCESFAIL 0x40 /* Rev B or greater */ + field MPARERR 0x20 + field DPARERR 0x10 + field SQPARERR 0x08 + field ILLOPCODE 0x04 + field DSCTMOUT 0x02 +} + +/* + * Clear Error + */ +register CLRERR { + address 0x004 + access_mode WO + field CLRCIOPARERR 0x80 + field CLRCIOACCESFAIL 0x40 /* Rev B or greater */ + field CLRMPARERR 0x20 + field CLRDPARERR 0x10 + field CLRSQPARERR 0x08 + field CLRILLOPCODE 0x04 + field CLRDSCTMOUT 0x02 +} + +/* + * Host Control Register + * Overall host control of the device. + */ +register HCNTRL { + address 0x005 + access_mode RW + field SEQ_RESET 0x80 /* Rev B or greater */ + field POWRDN 0x40 + field SWINT 0x10 + field SWTIMER_START_B 0x08 /* Rev B or greater */ + field PAUSE 0x04 + field INTEN 0x02 + field CHIPRST 0x01 + field CHIPRSTACK 0x01 +} + +/* + * Host New SCB Queue Offset + */ +register HNSCB_QOFF { + address 0x006 + access_mode RW + size 2 +} + +/* + * Host Empty SCB Queue Offset + */ +register HESCB_QOFF { + address 0x008 + access_mode RW +} + +/* + * Host Mailbox + */ +register HS_MAILBOX { + address 0x00B + access_mode RW + mask HOST_TQINPOS 0x80 /* Boundary at either 0 or 128 */ + mask ENINT_COALESS 0x40 /* Perform interrupt coalessing */ +} + +/* + * Sequencer Interupt Status + */ +register SEQINTSTAT { + address 0x00C + access_mode RO + field SEQ_SWTMRTO 0x10 + field SEQ_SEQINT 0x08 + field SEQ_SCSIINT 0x04 + field SEQ_PCIINT 0x02 + field SEQ_SPLTINT 0x01 +} + +/* + * Clear SEQ Interrupt + */ +register CLRSEQINTSTAT { + address 0x00C + access_mode WO + field CLRSEQ_SWTMRTO 0x10 + field CLRSEQ_SEQINT 0x08 + field CLRSEQ_SCSIINT 0x04 + field CLRSEQ_PCIINT 0x02 + field CLRSEQ_SPLTINT 0x01 +} + +/* + * Software Timer + */ +register SWTIMER { + address 0x00E + access_mode RW + size 2 +} + +/* + * SEQ New SCB Queue Offset + */ +register SNSCB_QOFF { + address 0x010 + access_mode RW + size 2 + modes M_CCHAN +} + +/* + * SEQ Empty SCB Queue Offset + */ +register SESCB_QOFF { + address 0x012 + access_mode RW + modes M_CCHAN +} + +/* + * SEQ Done SCB Queue Offset + */ +register SDSCB_QOFF { + address 0x014 + access_mode RW + modes M_CCHAN + size 2 +} + +/* + * Queue Offset Control & Status + */ +register QOFF_CTLSTA { + address 0x016 + access_mode RW + modes M_CCHAN + field EMPTY_SCB_AVAIL 0x80 + field NEW_SCB_AVAIL 0x40 + field SDSCB_ROLLOVR 0x20 + field HS_MAILBOX_ACT 0x10 + field SCB_QSIZE 0x0F { + SCB_QSIZE_4, + SCB_QSIZE_8, + SCB_QSIZE_16, + SCB_QSIZE_32, + SCB_QSIZE_64, + SCB_QSIZE_128, + SCB_QSIZE_256, + SCB_QSIZE_512, + SCB_QSIZE_1024, + SCB_QSIZE_2048, + SCB_QSIZE_4096, + SCB_QSIZE_8192, + SCB_QSIZE_16384 + } +} + +/* + * Interrupt Control + */ +register INTCTL { + address 0x018 + access_mode RW + field SWTMINTMASK 0x80 + field SWTMINTEN 0x40 + field SWTIMER_START 0x20 + field AUTOCLRCMDINT 0x10 + field PCIINTEN 0x08 + field SCSIINTEN 0x04 + field SEQINTEN 0x02 + field SPLTINTEN 0x01 +} + +/* + * Data FIFO Control + */ +register DFCNTRL { + address 0x019 + access_mode RW + modes M_DFF0, M_DFF1 + field PRELOADEN 0x80 + field SCSIENWRDIS 0x40 /* Rev B only. */ + field SCSIEN 0x20 + field SCSIENACK 0x20 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 + field DIRECTIONACK 0x04 + field FIFOFLUSH 0x02 + field FIFOFLUSHACK 0x02 + field DIRECTIONEN 0x01 +} + +/* + * Device Space Command 0 + */ +register DSCOMMAND0 { + address 0x019 + access_mode RW + modes M_CFG + field CACHETHEN 0x80 /* Cache Threshold enable */ + field DPARCKEN 0x40 /* Data Parity Check Enable */ + field MPARCKEN 0x20 /* Memory Parity Check Enable */ + field EXTREQLCK 0x10 /* External Request Lock */ + field DISABLE_TWATE 0x02 /* Rev B or greater */ + field CIOPARCKEN 0x01 /* Internal bus parity error enable */ +} + +/* + * Data FIFO Status + */ +register DFSTATUS { + address 0x01A + access_mode RO + modes M_DFF0, M_DFF1 + field PRELOAD_AVAIL 0x80 + field PKT_PRELOAD_AVAIL 0x40 + field MREQPEND 0x10 + field HDONE 0x08 + field DFTHRESH 0x04 + field FIFOFULL 0x02 + field FIFOEMP 0x01 +} + +/* + * S/G Cache Pointer + */ +register SG_CACHE_PRE { + address 0x01B + access_mode WO + modes M_DFF0, M_DFF1 + field SG_ADDR_MASK 0xf8 + field ODD_SEG 0x04 + field LAST_SEG 0x02 +} + +register SG_CACHE_SHADOW { + address 0x01B + access_mode RO + modes M_DFF0, M_DFF1 + field SG_ADDR_MASK 0xf8 + field ODD_SEG 0x04 + field LAST_SEG 0x02 + field LAST_SEG_DONE 0x01 +} + +/* + * Arbiter Control + */ +register ARBCTL { + address 0x01B + access_mode RW + modes M_CFG + field RESET_HARB 0x80 + field RETRY_SWEN 0x08 + field USE_TIME 0x07 +} + +/* + * Data Channel Host Address + */ +register HADDR { + address 0x070 + access_mode RW + size 8 + modes M_DFF0, M_DFF1 +} + +/* + * Host Overlay DMA Address + */ +register HODMAADR { + address 0x070 + access_mode RW + size 8 + modes M_SCSI +} + +/* + * PCI PLL Delay. + */ +register PLLDELAY { + address 0x070 + access_mode RW + size 1 + modes M_CFG + field SPLIT_DROP_REQ 0x80 +} + +/* + * Data Channel Host Count + */ +register HCNT { + address 0x078 + access_mode RW + size 3 + modes M_DFF0, M_DFF1 +} + +/* + * Host Overlay DMA Count + */ +register HODMACNT { + address 0x078 + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Host Overlay DMA Enable + */ +register HODMAEN { + address 0x07A + access_mode RW + modes M_SCSI +} + +/* + * Scatter/Gather Host Address + */ +register SGHADDR { + address 0x07C + access_mode RW + size 8 + modes M_DFF0, M_DFF1 +} + +/* + * SCB Host Address + */ +register SCBHADDR { + address 0x07C + access_mode RW + size 8 + modes M_CCHAN +} + +/* + * Scatter/Gather Host Count + */ +register SGHCNT { + address 0x084 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * SCB Host Count + */ +register SCBHCNT { + address 0x084 + access_mode RW + modes M_CCHAN +} + +/* + * Data FIFO Threshold + */ +register DFF_THRSH { + address 0x088 + access_mode RW + modes M_CFG + field WR_DFTHRSH 0x70 { + WR_DFTHRSH_MIN, + WR_DFTHRSH_25, + WR_DFTHRSH_50, + WR_DFTHRSH_63, + WR_DFTHRSH_75, + WR_DFTHRSH_85, + WR_DFTHRSH_90, + WR_DFTHRSH_MAX + } + field RD_DFTHRSH 0x07 { + RD_DFTHRSH_MIN, + RD_DFTHRSH_25, + RD_DFTHRSH_50, + RD_DFTHRSH_63, + RD_DFTHRSH_75, + RD_DFTHRSH_85, + RD_DFTHRSH_90, + RD_DFTHRSH_MAX + } +} + +/* + * ROM Address + */ +register ROMADDR { + address 0x08A + access_mode RW + size 3 +} + +/* + * ROM Control + */ +register ROMCNTRL { + address 0x08D + access_mode RW + field ROMOP 0xE0 + field ROMSPD 0x18 + field REPEAT 0x02 + field RDY 0x01 +} + +/* + * ROM Data + */ +register ROMDATA { + address 0x08E + access_mode RW +} + +/* + * Data Channel Receive Message 0 + */ +register DCHRXMSG0 { + address 0x090 + access_mode RO + modes M_DFF0, M_DFF1 + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * CMC Recieve Message 0 + */ +register CMCRXMSG0 { + address 0x090 + access_mode RO + modes M_CCHAN + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * Overlay Recieve Message 0 + */ +register OVLYRXMSG0 { + address 0x090 + access_mode RO + modes M_SCSI + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * Relaxed Order Enable + */ +register ROENABLE { + address 0x090 + access_mode RW + modes M_CFG + field MSIROEN 0x20 + field OVLYROEN 0x10 + field CMCROEN 0x08 + field SGROEN 0x04 + field DCH1ROEN 0x02 + field DCH0ROEN 0x01 +} + +/* + * Data Channel Receive Message 1 + */ +register DCHRXMSG1 { + address 0x091 + access_mode RO + modes M_DFF0, M_DFF1 + field CBNUM 0xFF +} + +/* + * CMC Recieve Message 1 + */ +register CMCRXMSG1 { + address 0x091 + access_mode RO + modes M_CCHAN + field CBNUM 0xFF +} + +/* + * Overlay Recieve Message 1 + */ +register OVLYRXMSG1 { + address 0x091 + access_mode RO + modes M_SCSI + field CBNUM 0xFF +} + +/* + * No Snoop Enable + */ +register NSENABLE { + address 0x091 + access_mode RW + modes M_CFG + field MSINSEN 0x20 + field OVLYNSEN 0x10 + field CMCNSEN 0x08 + field SGNSEN 0x04 + field DCH1NSEN 0x02 + field DCH0NSEN 0x01 +} + +/* + * Data Channel Receive Message 2 + */ +register DCHRXMSG2 { + address 0x092 + access_mode RO + modes M_DFF0, M_DFF1 + field MINDEX 0xFF +} + +/* + * CMC Recieve Message 2 + */ +register CMCRXMSG2 { + address 0x092 + access_mode RO + modes M_CCHAN + field MINDEX 0xFF +} + +/* + * Overlay Recieve Message 2 + */ +register OVLYRXMSG2 { + address 0x092 + access_mode RO + modes M_SCSI + field MINDEX 0xFF +} + +/* + * Outstanding Split Transactions + */ +register OST { + address 0x092 + access_mode RW + modes M_CFG +} + +/* + * Data Channel Receive Message 3 + */ +register DCHRXMSG3 { + address 0x093 + access_mode RO + modes M_DFF0, M_DFF1 + field MCLASS 0x0F +} + +/* + * CMC Recieve Message 3 + */ +register CMCRXMSG3 { + address 0x093 + access_mode RO + modes M_CCHAN + field MCLASS 0x0F +} + +/* + * Overlay Recieve Message 3 + */ +register OVLYRXMSG3 { + address 0x093 + access_mode RO + modes M_SCSI + field MCLASS 0x0F +} + +/* + * PCI-X Control + */ +register PCIXCTL { + address 0x093 + access_mode RW + modes M_CFG + field SERRPULSE 0x80 + field UNEXPSCIEN 0x20 + field SPLTSMADIS 0x10 + field SPLTSTADIS 0x08 + field SRSPDPEEN 0x04 + field TSCSERREN 0x02 + field CMPABCDIS 0x01 +} + +/* + * CMC Sequencer Byte Count + */ +register CMCSEQBCNT { + address 0x094 + access_mode RO + modes M_CCHAN +} + +/* + * Overlay Sequencer Byte Count + */ +register OVLYSEQBCNT { + address 0x094 + access_mode RO + modes M_SCSI +} + +/* + * Data Channel Sequencer Byte Count + */ +register DCHSEQBCNT { + address 0x094 + access_mode RO + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Data Channel Split Status 0 + */ +register DCHSPLTSTAT0 { + address 0x096 + access_mode RW + modes M_DFF0, M_DFF1 + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * CMC Split Status 0 + */ +register CMCSPLTSTAT0 { + address 0x096 + access_mode RW + modes M_CCHAN + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * Overlay Split Status 0 + */ +register OVLYSPLTSTAT0 { + address 0x096 + access_mode RW + modes M_SCSI + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * Data Channel Split Status 1 + */ +register DCHSPLTSTAT1 { + address 0x097 + access_mode RW + modes M_DFF0, M_DFF1 + field RXDATABUCKET 0x01 +} + +/* + * CMC Split Status 1 + */ +register CMCSPLTSTAT1 { + address 0x097 + access_mode RW + modes M_CCHAN + field RXDATABUCKET 0x01 +} + +/* + * Overlay Split Status 1 + */ +register OVLYSPLTSTAT1 { + address 0x097 + access_mode RW + modes M_SCSI + field RXDATABUCKET 0x01 +} + +/* + * S/G Receive Message 0 + */ +register SGRXMSG0 { + address 0x098 + access_mode RO + modes M_DFF0, M_DFF1 + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * S/G Receive Message 1 + */ +register SGRXMSG1 { + address 0x099 + access_mode RO + modes M_DFF0, M_DFF1 + field CBNUM 0xFF +} + +/* + * S/G Receive Message 2 + */ +register SGRXMSG2 { + address 0x09A + access_mode RO + modes M_DFF0, M_DFF1 + field MINDEX 0xFF +} + +/* + * S/G Receive Message 3 + */ +register SGRXMSG3 { + address 0x09B + access_mode RO + modes M_DFF0, M_DFF1 + field MCLASS 0x0F +} + +/* + * Slave Split Out Address 0 + */ +register SLVSPLTOUTADR0 { + address 0x098 + access_mode RO + modes M_SCSI + field LOWER_ADDR 0x7F +} + +/* + * Slave Split Out Address 1 + */ +register SLVSPLTOUTADR1 { + address 0x099 + access_mode RO + modes M_SCSI + field REQ_DNUM 0xF8 + field REQ_FNUM 0x07 +} + +/* + * Slave Split Out Address 2 + */ +register SLVSPLTOUTADR2 { + address 0x09A + access_mode RO + modes M_SCSI + field REQ_BNUM 0xFF +} + +/* + * Slave Split Out Address 3 + */ +register SLVSPLTOUTADR3 { + address 0x09B + access_mode RO + modes M_SCSI + field RLXORD 020 + field TAG_NUM 0x1F +} + +/* + * SG Sequencer Byte Count + */ +register SGSEQBCNT { + address 0x09C + access_mode RO + modes M_DFF0, M_DFF1 +} + +/* + * Slave Split Out Attribute 0 + */ +register SLVSPLTOUTATTR0 { + address 0x09C + access_mode RO + modes M_SCSI + field LOWER_BCNT 0xFF +} + +/* + * Slave Split Out Attribute 1 + */ +register SLVSPLTOUTATTR1 { + address 0x09D + access_mode RO + modes M_SCSI + field CMPLT_DNUM 0xF8 + field CMPLT_FNUM 0x07 +} + +/* + * Slave Split Out Attribute 2 + */ +register SLVSPLTOUTATTR2 { + address 0x09E + access_mode RO + size 2 + modes M_SCSI + field CMPLT_BNUM 0xFF +} +/* + * S/G Split Status 0 + */ +register SGSPLTSTAT0 { + address 0x09E + access_mode RW + modes M_DFF0, M_DFF1 + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * S/G Split Status 1 + */ +register SGSPLTSTAT1 { + address 0x09F + access_mode RW + modes M_DFF0, M_DFF1 + field RXDATABUCKET 0x01 +} + +/* + * Special Function + */ +register SFUNCT { + address 0x09f + access_mode RW + modes M_CFG + field TEST_GROUP 0xF0 + field TEST_NUM 0x0F +} + +/* + * Data FIFO 0 PCI Status + */ +register DF0PCISTAT { + address 0x0A0 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * Data FIFO 1 PCI Status + */ +register DF1PCISTAT { + address 0x0A1 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * S/G PCI Status + */ +register SGPCISTAT { + address 0x0A2 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field DPR 0x01 +} + +/* + * CMC PCI Status + */ +register CMCPCISTAT { + address 0x0A3 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * Overlay PCI Status + */ +register OVLYPCISTAT { + address 0x0A4 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field DPR 0x01 +} + +/* + * PCI Status for MSI Master DMA Transfer + */ +register MSIPCISTAT { + address 0x0A6 + access_mode RW + modes M_CFG + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field CLRPENDMSI 0x08 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * PCI Status for Target + */ +register TARGPCISTAT { + address 0x0A7 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field STA 0x08 + field TWATERR 0x02 +} + +/* + * LQ Packet In + * The last LQ Packet recieved + */ +register LQIN { + address 0x020 + access_mode RW + size 20 + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * SCB Type Pointer + * SCB offset for Target Mode SCB type information + */ +register TYPEPTR { + address 0x020 + access_mode RW + modes M_CFG +} + +/* + * Queue Tag Pointer + * SCB offset to the Two Byte tag identifier used for target mode. + */ +register TAGPTR { + address 0x021 + access_mode RW + modes M_CFG +} + +/* + * Logical Unit Number Pointer + * SCB offset to the LSB (little endian) of the lun field. + */ +register LUNPTR { + address 0x022 + access_mode RW + modes M_CFG +} + +/* + * Data Length Pointer + * SCB offset for the 4 byte data length field in target mode. + */ +register DATALENPTR { + address 0x023 + access_mode RW + modes M_CFG +} + +/* + * Status Length Pointer + * SCB offset to the two byte status field in target SCBs. + */ +register STATLENPTR { + address 0x024 + access_mode RW + modes M_CFG +} + +/* + * Command Length Pointer + * Scb offset for the CDB length field in initiator SCBs. + */ +register CMDLENPTR { + address 0x025 + access_mode RW + modes M_CFG +} + +/* + * Task Attribute Pointer + * Scb offset for the byte field specifying the attribute byte + * to be used in command packets. + */ +register ATTRPTR { + address 0x026 + access_mode RW + modes M_CFG +} + +/* + * Task Management Flags Pointer + * Scb offset for the byte field specifying the attribute flags + * byte to be used in command packets. + */ +register FLAGPTR { + address 0x027 + access_mode RW + modes M_CFG +} + +/* + * Command Pointer + * Scb offset for the first byte in the CDB for initiator SCBs. + */ +register CMDPTR { + address 0x028 + access_mode RW + modes M_CFG +} + +/* + * Queue Next Pointer + * Scb offset for the 2 byte "next scb link". + */ +register QNEXTPTR { + address 0x029 + access_mode RW + modes M_CFG +} + +/* + * SCSI ID Pointer + * Scb offset to the value to place in the SCSIID register + * during target mode connections. + */ +register IDPTR { + address 0x02A + access_mode RW + modes M_CFG +} + +/* + * Command Aborted Byte Pointer + * Offset to the SCB flags field that includes the + * "SCB aborted" status bit. + */ +register ABRTBYTEPTR { + address 0x02B + access_mode RW + modes M_CFG +} + +/* + * Command Aborted Bit Pointer + * Bit offset in the SCB flags field for "SCB aborted" status. + */ +register ABRTBITPTR { + address 0x02C + access_mode RW + modes M_CFG +} + +/* + * Rev B or greater. + */ +register MAXCMDBYTES { + address 0x02D + access_mode RW + modes M_CFG +} + +/* + * Rev B or greater. + */ +register MAXCMD2RCV { + address 0x02E + access_mode RW + modes M_CFG +} + +/* + * Rev B or greater. + */ +register SHORTTHRESH { + address 0x02F + access_mode RW + modes M_CFG +} + +/* + * Logical Unit Number Length + * The length, in bytes, of the SCB lun field. + */ +register LUNLEN { + address 0x030 + access_mode RW + modes M_CFG +} + +/* + * CDB Limit + * The size, in bytes, of the embedded CDB field in initator SCBs. + */ +register CDBLIMIT { + address 0x031 + access_mode RW + modes M_CFG +} + +/* + * Maximum Commands + * The maximum number of commands to issue during a + * single packetized connection. + */ +register MAXCMD { + address 0x032 + access_mode RW + modes M_CFG +} + +/* + * Maximum Command Counter + * The number of commands already sent during this connection + */ +register MAXCMDCNT { + address 0x033 + access_mode RW + modes M_CFG +} + +/* + * LQ Packet Reserved Bytes + * The bytes to be sent in the currently reserved fileds + * of all LQ packets. + */ +register LQRSVD01 { + address 0x034 + access_mode RW + modes M_SCSI +} +register LQRSVD16 { + address 0x035 + access_mode RW + modes M_SCSI +} +register LQRSVD17 { + address 0x036 + access_mode RW + modes M_SCSI +} + +/* + * Command Reserved 0 + * The byte to be sent for the reserved byte 0 of + * outgoing command packets. + */ +register CMDRSVD0 { + address 0x037 + access_mode RW + modes M_CFG +} + +/* + * LQ Manager Control 0 + */ +register LQCTL0 { + address 0x038 + access_mode RW + modes M_CFG + field LQITARGCLT 0xC0 + field LQIINITGCLT 0x30 + field LQ0TARGCLT 0x0C + field LQ0INITGCLT 0x03 +} + +/* + * LQ Manager Control 1 + */ +register LQCTL1 { + address 0x038 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field PCI2PCI 0x04 + field SINGLECMD 0x02 + field ABORTPENDING 0x01 +} + +/* + * LQ Manager Control 2 + */ +register LQCTL2 { + address 0x039 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field LQIRETRY 0x80 + field LQICONTINUE 0x40 + field LQITOIDLE 0x20 + field LQIPAUSE 0x10 + field LQORETRY 0x08 + field LQOCONTINUE 0x04 + field LQOTOIDLE 0x02 + field LQOPAUSE 0x01 +} + +/* + * SCSI RAM BIST0 + */ +register SCSBIST0 { + address 0x039 + access_mode RW + modes M_CFG + field GSBISTERR 0x40 + field GSBISTDONE 0x20 + field GSBISTRUN 0x10 + field OSBISTERR 0x04 + field OSBISTDONE 0x02 + field OSBISTRUN 0x01 +} + +/* + * SCSI Sequence Control0 + */ +register SCSISEQ0 { + address 0x03A + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field TEMODEO 0x80 + field ENSELO 0x40 + field ENARBO 0x20 + field FORCEBUSFREE 0x10 + field SCSIRSTO 0x01 +} + +/* + * SCSI RAM BIST 1 + */ +register SCSBIST1 { + address 0x03A + access_mode RW + modes M_CFG + field NTBISTERR 0x04 + field NTBISTDONE 0x02 + field NTBISTRUN 0x01 +} + +/* + * SCSI Sequence Control 1 + */ +register SCSISEQ1 { + address 0x03B + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field MANUALCTL 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field MANUALP 0x0C + field ENAUTOATNP 0x02 + field ALTSTIM 0x01 +} + +/* + * SCSI Transfer Control 0 + */ +register SXFRCTL0 { + address 0x03C + access_mode RW + modes M_SCSI + field DFON 0x80 + field DFPEXP 0x40 + field BIOSCANCELEN 0x10 + field SPIOEN 0x08 +} + +/* + * SCSI Transfer Control 1 + */ +register SXFRCTL1 { + address 0x03D + access_mode RW + modes M_SCSI + field BITBUCKET 0x80 + field ENSACHK 0x40 + field ENSPCHK 0x20 + field STIMESEL 0x18 + field ENSTIMER 0x04 + field ACTNEGEN 0x02 + field STPWEN 0x01 +} + +/* + * SCSI Transfer Control 2 + */ +register SXFRCTL2 { + address 0x03E + access_mode RW + modes M_SCSI + field AUTORSTDIS 0x10 + field CMDDMAEN 0x08 + field ASU 0x07 +} + +/* + * SCSI Bus Initiator IDs + * Bitmask of observed initiators on the bus. + */ +register BUSINITID { + address 0x03C + access_mode RW + modes M_CFG + size 2 +} + +/* + * Data Length Counters + * Packet byte counter. + */ +register DLCOUNT { + address 0x03C + access_mode RW + modes M_DFF0, M_DFF1 + size 3 +} + +/* + * Data FIFO Status + */ +register DFFSTAT { + address 0x03F + access_mode RW + modes M_SCSI + field FIFO1FREE 0x20 + field FIFO0FREE 0x10 + /* + * On the B, this enum only works + * in the read direction. For writes, + * you must use the B version of the + * CURRFIFO_0 definition which is defined + * as a constant outside of this register + * definition to avoid confusing the + * register pretty printing code. + */ + enum CURRFIFO 0x03 { + CURRFIFO_0, + CURRFIFO_1, + CURRFIFO_NONE 0x3 + } +} + +const B_CURRFIFO_0 0x2 + +/* + * SCSI Bus Target IDs + * Bitmask of observed targets on the bus. + */ +register BUSTARGID { + address 0x03E + access_mode RW + modes M_CFG + size 2 +} + +/* + * SCSI Control Signal Out + */ +register SCSISIGO { + address 0x040 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field CDO 0x80 + field IOO 0x40 + field MSGO 0x20 + field ATNO 0x10 + field SELO 0x08 + field BSYO 0x04 + field REQO 0x02 + field ACKO 0x01 +/* + * Possible phases to write into SCSISIG0 + */ + enum PHASE_MASK CDO|IOO|MSGO { + P_DATAOUT 0x0, + P_DATAIN IOO, + P_DATAOUT_DT P_DATAOUT|MSGO, + P_DATAIN_DT P_DATAIN|MSGO, + P_COMMAND CDO, + P_MESGOUT CDO|MSGO, + P_STATUS CDO|IOO, + P_MESGIN CDO|IOO|MSGO + } +} + +register SCSISIGI { + address 0x041 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 + field ATNI 0x10 + field SELI 0x08 + field BSYI 0x04 + field REQI 0x02 + field ACKI 0x01 +/* + * Possible phases in SCSISIGI + */ + enum PHASE_MASK CDO|IOO|MSGO { + P_DATAOUT 0x0, + P_DATAIN IOO, + P_DATAOUT_DT P_DATAOUT|MSGO, + P_DATAIN_DT P_DATAIN|MSGO, + P_COMMAND CDO, + P_MESGOUT CDO|MSGO, + P_STATUS CDO|IOO, + P_MESGIN CDO|IOO|MSGO + } +} + +/* + * Multiple Target IDs + * Bitmask of ids to respond as a target. + */ +register MULTARGID { + address 0x040 + access_mode RW + modes M_CFG + size 2 +} + +/* + * SCSI Phase + */ +register SCSIPHASE { + address 0x042 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field STATUS_PHASE 0x20 + field COMMAND_PHASE 0x10 + field MSG_IN_PHASE 0x08 + field MSG_OUT_PHASE 0x04 + field DATA_PHASE_MASK 0x03 { + DATA_OUT_PHASE 0x01, + DATA_IN_PHASE 0x02 + } +} + +/* + * SCSI Data 0 Image + */ +register SCSIDAT0_IMG { + address 0x043 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * SCSI Latched Data + */ +register SCSIDAT { + address 0x044 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + size 2 +} + +/* + * SCSI Data Bus + */ +register SCSIBUS { + address 0x046 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + size 2 +} + +/* + * Target ID In + */ +register TARGIDIN { + address 0x048 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field CLKOUT 0x80 + field TARGID 0x0F +} + +/* + * Selection/Reselection ID + * Upper four bits are the device id. The ONEBIT is set when the re/selecting + * device did not set its own ID. + */ +register SELID { + address 0x049 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field SELID_MASK 0xf0 + field ONEBIT 0x08 +} + +/* + * SCSI Block Control + * Controls Bus type and channel selection. SELWIDE allows for the + * coexistence of 8bit and 16bit devices on a wide bus. + */ +register SBLKCTL { + address 0x04A + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field DIAGLEDEN 0x80 + field DIAGLEDON 0x40 + field ENAB40 0x08 /* LVD transceiver active */ + field ENAB20 0x04 /* SE/HVD transceiver active */ + field SELWIDE 0x02 +} + +/* + * Option Mode + */ +register OPTIONMODE { + address 0x04A + access_mode RW + modes M_CFG + field BIOSCANCTL 0x80 + field AUTOACKEN 0x40 + field BIASCANCTL 0x20 + field BUSFREEREV 0x10 + field ENDGFORMCHK 0x04 + field AUTO_MSGOUT_DE 0x02 + mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE +} + +/* + * SCSI Status 0 + */ +register SSTAT0 { + address 0x04B + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field TARGET 0x80 /* Board acting as target */ + field SELDO 0x40 /* Selection Done */ + field SELDI 0x20 /* Board has been selected */ + field SELINGO 0x10 /* Selection In Progress */ + field IOERR 0x08 /* LVD Tranceiver mode changed */ + field OVERRUN 0x04 /* SCSI Offset overrun detected */ + field SPIORDY 0x02 /* SCSI PIO Ready */ + field ARBDO 0x01 /* Arbitration Done Out */ +} + +/* + * Clear SCSI Interrupt 0 + * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0. + */ +register CLRSINT0 { + address 0x04B + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRSELDO 0x40 + field CLRSELDI 0x20 + field CLRSELINGO 0x10 + field CLRIOERR 0x08 + field CLROVERRUN 0x04 + field CLRSPIORDY 0x02 + field CLRARBDO 0x01 +} + +/* + * SCSI Interrupt Mode 0 + * Setting any bit will enable the corresponding function + * in SIMODE0 to interrupt via the IRQ pin. + */ +register SIMODE0 { + address 0x04B + access_mode RW + modes M_CFG + field ENSELDO 0x40 + field ENSELDI 0x20 + field ENSELINGO 0x10 + field ENIOERR 0x08 + field ENOVERRUN 0x04 + field ENSPIORDY 0x02 + field ENARBDO 0x01 +} + +/* + * SCSI Status 1 + */ +register SSTAT1 { + address 0x04C + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field SELTO 0x80 + field ATNTARG 0x40 + field SCSIRSTI 0x20 + field PHASEMIS 0x10 + field BUSFREE 0x08 + field SCSIPERR 0x04 + field STRB2FAST 0x02 + field REQINIT 0x01 +} + +/* + * Clear SCSI Interrupt 1 + * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1. + */ +register CLRSINT1 { + address 0x04C + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRSELTIMEO 0x80 + field CLRATNO 0x40 + field CLRSCSIRSTI 0x20 + field CLRBUSFREE 0x08 + field CLRSCSIPERR 0x04 + field CLRSTRB2FAST 0x02 + field CLRREQINIT 0x01 +} + +/* + * SCSI Status 2 + */ +register SSTAT2 { + address 0x04d + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field BUSFREETIME 0xc0 { + BUSFREE_LQO 0x40, + BUSFREE_DFF0 0x80, + BUSFREE_DFF1 0xC0 + } + field NONPACKREQ 0x20 + field EXP_ACTIVE 0x10 /* SCSI Expander Active */ + field BSYX 0x08 /* Busy Expander */ + field WIDE_RES 0x04 /* Modes 0 and 1 only */ + field SDONE 0x02 /* Modes 0 and 1 only */ + field DMADONE 0x01 /* Modes 0 and 1 only */ +} + +/* + * Clear SCSI Interrupt 2 + */ +register CLRSINT2 { + address 0x04D + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRNONPACKREQ 0x20 + field CLRWIDE_RES 0x04 /* Modes 0 and 1 only */ + field CLRSDONE 0x02 /* Modes 0 and 1 only */ + field CLRDMADONE 0x01 /* Modes 0 and 1 only */ +} + +/* + * SCSI Interrupt Mode 2 + */ +register SIMODE2 { + address 0x04D + access_mode RW + modes M_CFG + field ENWIDE_RES 0x04 + field ENSDONE 0x02 + field ENDMADONE 0x01 +} + +/* + * Physical Error Diagnosis + */ +register PERRDIAG { + address 0x04E + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field HIZERO 0x80 + field HIPERR 0x40 + field PREVPHASE 0x20 + field PARITYERR 0x10 + field AIPERR 0x08 + field CRCERR 0x04 + field DGFORMERR 0x02 + field DTERR 0x01 +} + +/* + * LQI Manager Current State + */ +register LQISTATE { + address 0x04E + access_mode RO + modes M_CFG +} + +/* + * SCSI Offset Count + */ +register SOFFCNT { + address 0x04F + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * LQO Manager Current State + */ +register LQOSTATE { + address 0x04F + access_mode RO + modes M_CFG +} + +/* + * LQI Manager Status + */ +register LQISTAT0 { + address 0x050 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQIATNQAS 0x20 + field LQICRCT1 0x10 + field LQICRCT2 0x08 + field LQIBADLQT 0x04 + field LQIATNLQ 0x02 + field LQIATNCMD 0x01 +} + +/* + * Clear LQI Interrupts 0 + */ +register CLRLQIINT0 { + address 0x050 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQIATNQAS 0x20 + field CLRLQICRCT1 0x10 + field CLRLQICRCT2 0x08 + field CLRLQIBADLQT 0x04 + field CLRLQIATNLQ 0x02 + field CLRLQIATNCMD 0x01 +} + +/* + * LQI Manager Interrupt Mode 0 + */ +register LQIMODE0 { + address 0x050 + access_mode RW + modes M_CFG + field ENLQIATNQASK 0x20 + field ENLQICRCT1 0x10 + field ENLQICRCT2 0x08 + field ENLQIBADLQT 0x04 + field ENLQIATNLQ 0x02 + field ENLQIATNCMD 0x01 +} + +/* + * LQI Manager Status 1 + */ +register LQISTAT1 { + address 0x051 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQIPHASE_LQ 0x80 + field LQIPHASE_NLQ 0x40 + field LQIABORT 0x20 + field LQICRCI_LQ 0x10 + field LQICRCI_NLQ 0x08 + field LQIBADLQI 0x04 + field LQIOVERI_LQ 0x02 + field LQIOVERI_NLQ 0x01 +} + +/* + * Clear LQI Manager Interrupts1 + */ +register CLRLQIINT1 { + address 0x051 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQIPHASE_LQ 0x80 + field CLRLQIPHASE_NLQ 0x40 + field CLRLIQABORT 0x20 + field CLRLQICRCI_LQ 0x10 + field CLRLQICRCI_NLQ 0x08 + field CLRLQIBADLQI 0x04 + field CLRLQIOVERI_LQ 0x02 + field CLRLQIOVERI_NLQ 0x01 +} + +/* + * LQI Manager Interrupt Mode 1 + */ +register LQIMODE1 { + address 0x051 + access_mode RW + modes M_CFG + field ENLQIPHASE_LQ 0x80 + field ENLQIPHASE_NLQ 0x40 + field ENLIQABORT 0x20 + field ENLQICRCI_LQ 0x10 + field ENLQICRCI_NLQ 0x08 + field ENLQIBADLQI 0x04 + field ENLQIOVERI_LQ 0x02 + field ENLQIOVERI_NLQ 0x01 +} + +/* + * LQI Manager Status 2 + */ +register LQISTAT2 { + address 0x052 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field PACKETIZED 0x80 + field LQIPHASE_OUTPKT 0x40 + field LQIWORKONLQ 0x20 + field LQIWAITFIFO 0x10 + field LQISTOPPKT 0x08 + field LQISTOPLQ 0x04 + field LQISTOPCMD 0x02 + field LQIGSAVAIL 0x01 +} + +/* + * SCSI Status 3 + */ +register SSTAT3 { + address 0x053 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field NTRAMPERR 0x02 + field OSRAMPERR 0x01 +} + +/* + * Clear SCSI Status 3 + */ +register CLRSINT3 { + address 0x053 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRNTRAMPERR 0x02 + field CLROSRAMPERR 0x01 +} + +/* + * SCSI Interrupt Mode 3 + */ +register SIMODE3 { + address 0x053 + access_mode RW + modes M_CFG + field ENNTRAMPERR 0x02 + field ENOSRAMPERR 0x01 +} + +/* + * LQO Manager Status 0 + */ +register LQOSTAT0 { + address 0x054 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQOTARGSCBPERR 0x10 + field LQOSTOPT2 0x08 + field LQOATNLQ 0x04 + field LQOATNPKT 0x02 + field LQOTCRC 0x01 +} + +/* + * Clear LQO Manager interrupt 0 + */ +register CLRLQOINT0 { + address 0x054 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQOTARGSCBPERR 0x10 + field CLRLQOSTOPT2 0x08 + field CLRLQOATNLQ 0x04 + field CLRLQOATNPKT 0x02 + field CLRLQOTCRC 0x01 +} + +/* + * LQO Manager Interrupt Mode 0 + */ +register LQOMODE0 { + address 0x054 + access_mode RW + modes M_CFG + field ENLQOTARGSCBPERR 0x10 + field ENLQOSTOPT2 0x08 + field ENLQOATNLQ 0x04 + field ENLQOATNPKT 0x02 + field ENLQOTCRC 0x01 +} + +/* + * LQO Manager Status 1 + */ +register LQOSTAT1 { + address 0x055 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQOINITSCBPERR 0x10 + field LQOSTOPI2 0x08 + field LQOBADQAS 0x04 + field LQOBUSFREE 0x02 + field LQOPHACHGINPKT 0x01 +} + +/* + * Clear LOQ Interrupt 1 + */ +register CLRLQOINT1 { + address 0x055 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQOINITSCBPERR 0x10 + field CLRLQOSTOPI2 0x08 + field CLRLQOBADQAS 0x04 + field CLRLQOBUSFREE 0x02 + field CLRLQOPHACHGINPKT 0x01 +} + +/* + * LQO Manager Interrupt Mode 1 + */ +register LQOMODE1 { + address 0x055 + access_mode RW + modes M_CFG + field ENLQOINITSCBPERR 0x10 + field ENLQOSTOPI2 0x08 + field ENLQOBADQAS 0x04 + field ENLQOBUSFREE 0x02 + field ENLQOPHACHGINPKT 0x01 +} + +/* + * LQO Manager Status 2 + */ +register LQOSTAT2 { + address 0x056 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQOPKT 0xE0 + field LQOWAITFIFO 0x10 + field LQOPHACHGOUTPKT 0x02 /* outside of packet boundaries. */ + field LQOSTOP0 0x01 /* Stopped after sending all packets */ +} + +/* + * Output Synchronizer Space Count + */ +register OS_SPACE_CNT { + address 0x056 + access_mode RO + modes M_CFG +} + +/* + * SCSI Interrupt Mode 1 + * Setting any bit will enable the corresponding function + * in SIMODE1 to interrupt via the IRQ pin. + */ +register SIMODE1 { + address 0x057 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field ENSELTIMO 0x80 + field ENATNTARG 0x40 + field ENSCSIRST 0x20 + field ENPHASEMIS 0x10 + field ENBUSFREE 0x08 + field ENSCSIPERR 0x04 + field ENSTRB2FAST 0x02 + field ENREQINIT 0x01 +} + +/* + * Good Status FIFO + */ +register GSFIFO { + address 0x058 + access_mode RO + size 2 + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * Data FIFO SCSI Transfer Control + */ +register DFFSXFRCTL { + address 0x05A + access_mode RW + modes M_DFF0, M_DFF1 + field DFFBITBUCKET 0x08 + field CLRSHCNT 0x04 + field CLRCHN 0x02 + field RSTCHN 0x01 +} + +/* + * Next SCSI Control Block + */ +register NEXTSCB { + address 0x05A + access_mode RW + size 2 + modes M_SCSI +} + +/* Rev B only. */ +register LQOSCSCTL { + address 0x05A + access_mode RW + size 1 + modes M_CFG + field LQOH2A_VERSION 0x80 + field LQONOCHKOVER 0x01 +} + +/* + * SEQ Interrupts + */ +register SEQINTSRC { + address 0x05B + access_mode RO + modes M_DFF0, M_DFF1 + field CTXTDONE 0x40 + field SAVEPTRS 0x20 + field CFG4DATA 0x10 + field CFG4ISTAT 0x08 + field CFG4TSTAT 0x04 + field CFG4ICMD 0x02 + field CFG4TCMD 0x01 +} + +/* + * Clear Arp Interrupts + */ +register CLRSEQINTSRC { + address 0x05B + access_mode WO + modes M_DFF0, M_DFF1 + field CLRCTXTDONE 0x40 + field CLRSAVEPTRS 0x20 + field CLRCFG4DATA 0x10 + field CLRCFG4ISTAT 0x08 + field CLRCFG4TSTAT 0x04 + field CLRCFG4ICMD 0x02 + field CLRCFG4TCMD 0x01 +} + +/* + * SEQ Interrupt Enabled (Shared) + */ +register SEQIMODE { + address 0x05C + access_mode RW + modes M_DFF0, M_DFF1 + field ENCTXTDONE 0x40 + field ENSAVEPTRS 0x20 + field ENCFG4DATA 0x10 + field ENCFG4ISTAT 0x08 + field ENCFG4TSTAT 0x04 + field ENCFG4ICMD 0x02 + field ENCFG4TCMD 0x01 +} + +/* + * Current SCSI Control Block + */ +register CURRSCB { + address 0x05C + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Data FIFO Status + */ +register MDFFSTAT { + address 0x05D + access_mode RO + modes M_DFF0, M_DFF1 + field SHCNTNEGATIVE 0x40 /* Rev B or higher */ + field SHCNTMINUS1 0x20 /* Rev B or higher */ + field LASTSDONE 0x10 + field SHVALID 0x08 + field DLZERO 0x04 /* FIFO data ends on packet boundary. */ + field DATAINFIFO 0x02 + field FIFOFREE 0x01 +} + +/* + * CRC Control + */ +register CRCCONTROL { + address 0x05d + access_mode RW + modes M_CFG + field CRCVALCHKEN 0x40 +} + +/* + * SCSI Test Control + */ +register SCSITEST { + address 0x05E + access_mode RW + modes M_CFG + field CNTRTEST 0x08 + field SEL_TXPLL_DEBUG 0x04 +} + +/* + * Data FIFO Queue Tag + */ +register DFFTAG { + address 0x05E + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Last SCSI Control Block + */ +register LASTSCB { + address 0x05E + access_mode RW + size 2 + modes M_SCSI +} + +/* + * SCSI I/O Cell Power-down Control + */ +register IOPDNCTL { + address 0x05F + access_mode RW + modes M_CFG + field DISABLE_OE 0x80 + field PDN_IDIST 0x04 + field PDN_DIFFSENSE 0x01 +} + +/* + * Shaddow Host Address. + */ +register SHADDR { + address 0x060 + access_mode RO + size 8 + modes M_DFF0, M_DFF1 +} + +/* + * Data Group CRC Interval. + */ +register DGRPCRCI { + address 0x060 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Data Transfer Negotiation Address + */ +register NEGOADDR { + address 0x060 + access_mode RW + modes M_SCSI +} + +/* + * Data Transfer Negotiation Data - Period Byte + */ +register NEGPERIOD { + address 0x061 + access_mode RW + modes M_SCSI +} + +/* + * Packetized CRC Interval + */ +register PACKCRCI { + address 0x062 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Data Transfer Negotiation Data - Offset Byte + */ +register NEGOFFSET { + address 0x062 + access_mode RW + modes M_SCSI +} + +/* + * Data Transfer Negotiation Data - PPR Options + */ +register NEGPPROPTS { + address 0x063 + access_mode RW + modes M_SCSI + field PPROPT_PACE 0x08 + field PPROPT_QAS 0x04 + field PPROPT_DT 0x02 + field PPROPT_IUT 0x01 +} + +/* + * Data Transfer Negotiation Data - Connection Options + */ +register NEGCONOPTS { + address 0x064 + access_mode RW + modes M_SCSI + field ENSNAPSHOT 0x40 + field RTI_WRTDIS 0x20 + field RTI_OVRDTRN 0x10 + field ENSLOWCRC 0x08 + field ENAUTOATNI 0x04 + field ENAUTOATNO 0x02 + field WIDEXFER 0x01 +} + +/* + * Negotiation Table Annex Column Index. + */ +register ANNEXCOL { + address 0x065 + access_mode RW + modes M_SCSI +} + +register SCSCHKN { + address 0x066 + access_mode RW + modes M_CFG + field STSELSKIDDIS 0x40 + field CURRFIFODEF 0x20 + field WIDERESEN 0x10 + field SDONEMSKDIS 0x08 + field DFFACTCLR 0x04 + field SHVALIDSTDIS 0x02 + field LSTSGCLRDIS 0x01 +} + +const AHD_ANNEXCOL_PER_DEV0 4 +const AHD_NUM_PER_DEV_ANNEXCOLS 4 +const AHD_ANNEXCOL_PRECOMP_SLEW 4 +const AHD_PRECOMP_MASK 0x07 +const AHD_PRECOMP_SHIFT 0 +const AHD_PRECOMP_CUTBACK_17 0x04 +const AHD_PRECOMP_CUTBACK_29 0x06 +const AHD_PRECOMP_CUTBACK_37 0x07 +const AHD_SLEWRATE_MASK 0x78 +const AHD_SLEWRATE_SHIFT 3 +/* + * Rev A has only a single bit of slew adjustment. + * Rev B has 4 bits. + */ +const AHD_SLEWRATE_DEF_REVA 0x01 +const AHD_SLEWRATE_DEF_REVB 0x08 + +/* Rev A does not have any amplitude setting. */ +const AHD_ANNEXCOL_AMPLITUDE 6 +const AHD_AMPLITUDE_MASK 0x7 +const AHD_AMPLITUDE_SHIFT 0 +const AHD_AMPLITUDE_DEF 0x7 + +/* + * Negotiation Table Annex Data Port. + */ +register ANNEXDAT { + address 0x066 + access_mode RW + modes M_SCSI +} + +/* + * Initiator's Own Id. + * The SCSI ID to use for Selection Out and seen during a reselection.. + */ +register IOWNID { + address 0x067 + access_mode RW + modes M_SCSI +} + +/* + * 960MHz Phase-Locked Loop Control 0 + */ +register PLL960CTL0 { + address 0x068 + access_mode RW + modes M_CFG + field PLL_VCOSEL 0x80 + field PLL_PWDN 0x40 + field PLL_NS 0x30 + field PLL_ENLUD 0x08 + field PLL_ENLPF 0x04 + field PLL_DLPF 0x02 + field PLL_ENFBM 0x01 +} + +/* + * Target Own Id + */ +register TOWNID { + address 0x069 + access_mode RW + modes M_SCSI +} + +/* + * 960MHz Phase-Locked Loop Control 1 + */ +register PLL960CTL1 { + address 0x069 + access_mode RW + modes M_CFG + field PLL_CNTEN 0x80 + field PLL_CNTCLR 0x40 + field PLL_RST 0x01 +} + +/* + * Expander Signature + */ +register XSIG { + address 0x06A + access_mode RW + modes M_SCSI +} + +/* + * Shadow Byte Count + */ +register SHCNT { + address 0x068 + access_mode RW + size 3 + modes M_DFF0, M_DFF1 +} + +/* + * Selection Out ID + */ +register SELOID { + address 0x06B + access_mode RW + modes M_SCSI +} + +/* + * 960-MHz Phase-Locked Loop Test Count + */ +register PLL960CNT0 { + address 0x06A + access_mode RO + size 2 + modes M_CFG +} + +/* + * 400-MHz Phase-Locked Loop Control 0 + */ +register PLL400CTL0 { + address 0x06C + access_mode RW + modes M_CFG + field PLL_VCOSEL 0x80 + field PLL_PWDN 0x40 + field PLL_NS 0x30 + field PLL_ENLUD 0x08 + field PLL_ENLPF 0x04 + field PLL_DLPF 0x02 + field PLL_ENFBM 0x01 +} + +/* + * Arbitration Fairness + */ +register FAIRNESS { + address 0x06C + access_mode RW + size 2 + modes M_SCSI +} + +/* + * 400-MHz Phase-Locked Loop Control 1 + */ +register PLL400CTL1 { + address 0x06D + access_mode RW + modes M_CFG + field PLL_CNTEN 0x80 + field PLL_CNTCLR 0x40 + field PLL_RST 0x01 +} + +/* + * Arbitration Unfairness + */ +register UNFAIRNESS { + address 0x06E + access_mode RW + size 2 + modes M_SCSI +} + +/* + * 400-MHz Phase-Locked Loop Test Count + */ +register PLL400CNT0 { + address 0x06E + access_mode RO + size 2 + modes M_CFG +} + +/* + * SCB Page Pointer + */ +register SCBPTR { + address 0x0A8 + access_mode RW + size 2 + modes M_DFF0, M_DFF1, M_CCHAN, M_SCSI +} + +/* + * CMC SCB Array Count + * Number of bytes to transfer between CMC SCB memory and SCBRAM. + * Transfers must be 8byte aligned and sized. + */ +register CCSCBACNT { + address 0x0AB + access_mode RW + modes M_CCHAN +} + +/* + * SCB Autopointer + * SCB-Next Address Snooping logic. When an SCB is transferred to + * the card, the next SCB address to be used by the CMC array can + * be autoloaded from that transfer. + */ +register SCBAUTOPTR { + address 0x0AB + access_mode RW + modes M_CFG + field AUSCBPTR_EN 0x80 + field SCBPTR_ADDR 0x38 + field SCBPTR_OFF 0x07 +} + +/* + * CMC SG Ram Address Pointer + */ +register CCSGADDR { + address 0x0AC + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * CMC SCB RAM Address Pointer + */ +register CCSCBADDR { + address 0x0AC + access_mode RW + modes M_CCHAN +} + +/* + * CMC SCB Ram Back-up Address Pointer + * Indicates the true stop location of transfers halted prior + * to SCBHCNT going to 0. + */ +register CCSCBADR_BK { + address 0x0AC + access_mode RO + modes M_CFG +} + +/* + * CMC SG Control + */ +register CCSGCTL { + address 0x0AD + access_mode RW + modes M_DFF0, M_DFF1 + field CCSGDONE 0x80 + field SG_CACHE_AVAIL 0x10 + field CCSGENACK 0x08 + mask CCSGEN 0x0C + field SG_FETCH_REQ 0x02 + field CCSGRESET 0x01 +} + +/* + * CMD SCB Control + */ +register CCSCBCTL { + address 0x0AD + access_mode RW + modes M_CCHAN + field CCSCBDONE 0x80 + field ARRDONE 0x40 + field CCARREN 0x10 + field CCSCBEN 0x08 + field CCSCBDIR 0x04 + field CCSCBRESET 0x01 +} + +/* + * CMC Ram BIST + */ +register CMC_RAMBIST { + address 0x0AD + access_mode RW + modes M_CFG + field SG_ELEMENT_SIZE 0x80 + field SCBRAMBIST_FAIL 0x40 + field SG_BIST_FAIL 0x20 + field SG_BIST_EN 0x10 + field CMC_BUFFER_BIST_FAIL 0x02 + field CMC_BUFFER_BIST_EN 0x01 +} + +/* + * CMC SG RAM Data Port + */ +register CCSGRAM { + address 0x0B0 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * CMC SCB RAM Data Port + */ +register CCSCBRAM { + address 0x0B0 + access_mode RW + modes M_CCHAN +} + +/* + * Flex DMA Address. + */ +register FLEXADR { + address 0x0B0 + access_mode RW + size 3 + modes M_SCSI +} + +/* + * Flex DMA Byte Count + */ +register FLEXCNT { + address 0x0B3 + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Flex DMA Status + */ +register FLEXDMASTAT { + address 0x0B5 + access_mode RW + modes M_SCSI + field FLEXDMAERR 0x02 + field FLEXDMADONE 0x01 +} + +/* + * Flex DMA Data Port + */ +register FLEXDATA { + address 0x0B6 + access_mode RW + modes M_SCSI +} + +/* + * Board Data + */ +register BRDDAT { + address 0x0B8 + access_mode RW + modes M_SCSI +} + +/* + * Board Control + */ +register BRDCTL { + address 0x0B9 + access_mode RW + modes M_SCSI + field FLXARBACK 0x80 + field FLXARBREQ 0x40 + field BRDADDR 0x38 + field BRDEN 0x04 + field BRDRW 0x02 + field BRDSTB 0x01 +} + +/* + * Serial EEPROM Address + */ +register SEEADR { + address 0x0BA + access_mode RW + modes M_SCSI +} + +/* + * Serial EEPROM Data + */ +register SEEDAT { + address 0x0BC + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Serial EEPROM Status + */ +register SEESTAT { + address 0x0BE + access_mode RO + modes M_SCSI + field INIT_DONE 0x80 + field SEEOPCODE 0x70 + field LDALTID_L 0x08 + field SEEARBACK 0x04 + field SEEBUSY 0x02 + field SEESTART 0x01 +} + +/* + * Serial EEPROM Control + */ +register SEECTL { + address 0x0BE + access_mode RW + modes M_SCSI + field SEEOPCODE 0x70 { + SEEOP_ERASE 0x70, + SEEOP_READ 0x60, + SEEOP_WRITE 0x50, + /* + * The following four commands use special + * addresses for differentiation. + */ + SEEOP_ERAL 0x40 + } + mask SEEOP_EWEN 0x40 + mask SEEOP_WALL 0x40 + mask SEEOP_EWDS 0x40 + field SEERST 0x02 + field SEESTART 0x01 +} + +const SEEOP_ERAL_ADDR 0x80 +const SEEOP_EWEN_ADDR 0xC0 +const SEEOP_WRAL_ADDR 0x40 +const SEEOP_EWDS_ADDR 0x00 + +/* + * SCB Counter + */ +register SCBCNT { + address 0x0BF + access_mode RW + modes M_SCSI +} + +/* + * Data FIFO Write Address + * Pointer to the next QWD location to be written to the data FIFO. + */ +register DFWADDR { + address 0x0C0 + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * DSP Filter Control + */ +register DSPFLTRCTL { + address 0x0C0 + access_mode RW + modes M_CFG + field FLTRDISABLE 0x20 + field EDGESENSE 0x10 + field DSPFCNTSEL 0x0F +} + +/* + * DSP Data Channel Control + */ +register DSPDATACTL { + address 0x0C1 + access_mode RW + modes M_CFG + field BYPASSENAB 0x80 + field DESQDIS 0x10 + field RCVROFFSTDIS 0x04 + field XMITOFFSTDIS 0x02 +} + +/* + * Data FIFO Read Address + * Pointer to the next QWD location to be read from the data FIFO. + */ +register DFRADDR { + address 0x0C2 + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * DSP REQ Control + */ +register DSPREQCTL { + address 0x0C2 + access_mode RW + modes M_CFG + field MANREQCTL 0xC0 + field MANREQDLY 0x3F +} + +/* + * DSP ACK Control + */ +register DSPACKCTL { + address 0x0C3 + access_mode RW + modes M_CFG + field MANACKCTL 0xC0 + field MANACKDLY 0x3F +} + +/* + * Data FIFO Data + * Read/Write byte port into the data FIFO. The read and write + * FIFO pointers increment with each read and write respectively + * to this port. + */ +register DFDAT { + address 0x0C4 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * DSP Channel Select + */ +register DSPSELECT { + address 0x0C4 + access_mode RW + modes M_CFG + field AUTOINCEN 0x80 + field DSPSEL 0x1F +} + +const NUMDSPS 0x14 + +/* + * Write Bias Control + */ +register WRTBIASCTL { + address 0x0C5 + access_mode WO + modes M_CFG + field AUTOXBCDIS 0x80 + field XMITMANVAL 0x3F +} + +/* + * Currently the WRTBIASCTL is the same as the default. + */ +const WRTBIASCTL_HP_DEFAULT 0x0 + +/* + * Receiver Bias Control + */ +register RCVRBIOSCTL { + address 0x0C6 + access_mode WO + modes M_CFG + field AUTORBCDIS 0x80 + field RCVRMANVAL 0x3F +} + +/* + * Write Bias Calculator + */ +register WRTBIASCALC { + address 0x0C7 + access_mode RO + modes M_CFG +} + +/* + * Data FIFO Pointers + * Contains the byte offset from DFWADDR and DWRADDR to the current + * FIFO write/read locations. + */ +register DFPTRS { + address 0x0C8 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * Receiver Bias Calculator + */ +register RCVRBIASCALC { + address 0x0C8 + access_mode RO + modes M_CFG +} + +/* + * Data FIFO Backup Read Pointer + * Contains the data FIFO address to be restored if the last + * data accessed from the data FIFO was not transferred successfully. + */ +register DFBKPTR { + address 0x0C9 + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Skew Calculator + */ +register SKEWCALC { + address 0x0C9 + access_mode RO + modes M_CFG +} + +/* + * Data FIFO Debug Control + */ +register DFDBCTL { + address 0x0CB + access_mode RW + modes M_DFF0, M_DFF1 + field DFF_CIO_WR_RDY 0x20 + field DFF_CIO_RD_RDY 0x10 + field DFF_DIR_ERR 0x08 + field DFF_RAMBIST_FAIL 0x04 + field DFF_RAMBIST_DONE 0x02 + field DFF_RAMBIST_EN 0x01 +} + +/* + * Data FIFO Space Count + * Number of FIFO locations that are free. + */ +register DFSCNT { + address 0x0CC + access_mode RO + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Data FIFO Byte Count + * Number of filled FIFO locations. + */ +register DFBCNT { + address 0x0CE + access_mode RO + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Sequencer Program Overlay Address. + * Low address must be written prior to high address. + */ +register OVLYADDR { + address 0x0D4 + modes M_SCSI + size 2 + access_mode RW +} + +/* + * Sequencer Control 0 + * Error detection mode, speed configuration, + * single step, breakpoints and program load. + */ +register SEQCTL0 { + address 0x0D6 + access_mode RW + field PERRORDIS 0x80 + field PAUSEDIS 0x40 + field FAILDIS 0x20 + field FASTMODE 0x10 + field BRKADRINTEN 0x08 + field STEP 0x04 + field SEQRESET 0x02 + field LOADRAM 0x01 +} + +/* + * Sequencer Control 1 + * Instruction RAM Diagnostics + */ +register SEQCTL1 { + address 0x0D7 + access_mode RW + field OVRLAY_DATA_CHK 0x08 + field RAMBIST_DONE 0x04 + field RAMBIST_FAIL 0x02 + field RAMBIST_EN 0x01 +} + +/* + * Sequencer Flags + * Zero and Carry state of the ALU. + */ +register FLAGS { + address 0x0D8 + access_mode RO + field ZERO 0x02 + field CARRY 0x01 +} + +/* + * Sequencer Interrupt Control + */ +register SEQINTCTL { + address 0x0D9 + access_mode RW + field INTVEC1DSL 0x80 + field INT1_CONTEXT 0x20 + field SCS_SEQ_INT1M1 0x10 + field SCS_SEQ_INT1M0 0x08 + field INTMASK2 0x04 + field INTMASK1 0x02 + field IRET 0x01 +} + +/* + * Sequencer RAM Data Port + * Single byte window into the Sequencer Instruction Ram area starting + * at the address specified by OVLYADDR. To write a full instruction word, + * simply write four bytes in succession. OVLYADDR will increment after the + * most significant instrution byte (the byte with the parity bit) is written. + */ +register SEQRAM { + address 0x0DA + access_mode RW +} + +/* + * Sequencer Program Counter + * Low byte must be written prior to high byte. + */ +register PRGMCNT { + address 0x0DE + access_mode RW + size 2 +} + +/* + * Accumulator + */ +register ACCUM { + address 0x0E0 + access_mode RW + accumulator +} + +/* + * Source Index Register + * Incrementing index for reads of SINDIR and the destination (low byte only) + * for any immediate operands passed in jmp, jc, jnc, call instructions. + * Example: + * mvi 0xFF call some_routine; + * + * Will set SINDEX[0] to 0xFF and call the routine "some_routine. + */ +register SINDEX { + address 0x0E2 + access_mode RW + size 2 + sindex +} + +/* + * Destination Index Register + * Incrementing index for writes to DINDIR. Can be used as a scratch register. + */ +register DINDEX { + address 0x0E4 + access_mode RW + size 2 +} + +/* + * Break Address + * Sequencer instruction breakpoint address address. + */ +register BRKADDR0 { + address 0x0E6 + access_mode RW +} + +register BRKADDR1 { + address 0x0E6 + access_mode RW + field BRKDIS 0x80 /* Disable Breakpoint */ +} + +/* + * All Ones + * All reads to this register return the value 0xFF. + */ +register ALLONES { + address 0x0E8 + access_mode RO + allones +} + +/* + * All Zeros + * All reads to this register return the value 0. + */ +register ALLZEROS { + address 0x0EA + access_mode RO + allzeros +} + +/* + * No Destination + * Writes to this register have no effect. + */ +register NONE { + address 0x0EA + access_mode WO + none +} + +/* + * Source Index Indirect + * Reading this register is equivalent to reading (register_base + SINDEX) and + * incrementing SINDEX by 1. + */ +register SINDIR { + address 0x0EC + access_mode RO +} + +/* + * Destination Index Indirect + * Writing this register is equivalent to writing to (register_base + DINDEX) + * and incrementing DINDEX by 1. + */ +register DINDIR { + address 0x0ED + access_mode WO +} + +/* + * Function One + * 2's complement to bit value conversion. Write the 2's complement value + * (0-7 only) to the top nibble and retrieve the bit indexed by that value + * on the next read of this register. + * Example: + * Write 0x60 + * Read 0x40 + */ +register FUNCTION1 { + address 0x0F0 + access_mode RW +} + +/* + * Stack + * Window into the stack. Each stack location is 10 bits wide reported + * low byte followed by high byte. There are 8 stack locations. + */ +register STACK { + address 0x0F2 + access_mode RW +} + +/* + * Interrupt Vector 1 Address + * Interrupt branch address for SCS SEQ_INT1 mode 0 and 1 interrupts. + */ +register INTVEC1_ADDR { + address 0x0F4 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Current Address + * Address of the SEQRAM instruction currently executing instruction. + */ +register CURADDR { + address 0x0F4 + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Interrupt Vector 2 Address + * Interrupt branch address for HST_SEQ_INT2 interrupts. + */ +register INTVEC2_ADDR { + address 0x0F6 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Last Address + * Address of the SEQRAM instruction executed prior to the current instruction. + */ +register LASTADDR { + address 0x0F6 + access_mode RW + size 2 + modes M_SCSI +} + +register AHD_PCI_CONFIG_BASE { + address 0x100 + access_mode RW + size 256 + modes M_CFG +} + +/* ---------------------- Scratch RAM Offsets ------------------------- */ +scratch_ram { + /* Mode Specific */ + address 0x0A0 + size 8 + modes 0, 1, 2, 3 + REG0 { + size 2 + } + REG1 { + size 2 + } + REG_ISR { + size 2 + } + SG_STATE { + size 1 + field SEGS_AVAIL 0x01 + field LOADING_NEEDED 0x02 + field FETCH_INPROG 0x04 + } + /* + * Track whether the transfer byte count for + * the current data phase is odd. + */ + DATA_COUNT_ODD { + size 1 + } +} + +scratch_ram { + /* Mode Specific */ + address 0x0F8 + size 8 + modes 0, 1, 2, 3 + LONGJMP_ADDR { + size 2 + } + LONGJMP_SCB { + size 2 + } + ACCUM_SAVE { + size 1 + } +} + + +scratch_ram { + address 0x100 + size 128 + modes 0, 1, 2, 3 + /* + * Per "other-id" execution queues. We use an array of + * tail pointers into lists of SCBs sorted by "other-id". + * The execution head pointer threads the head SCBs for + * each list. + */ + WAITING_SCB_TAILS { + size 32 + } + WAITING_TID_HEAD { + size 2 + } + WAITING_TID_TAIL { + size 2 + } + /* + * SCBID of the next SCB in the new SCB queue. + */ + NEXT_QUEUED_SCB_ADDR { + size 4 + } + /* + * head of list of SCBs that have + * completed but have not been + * put into the qoutfifo. + */ + COMPLETE_SCB_HEAD { + size 2 + } + /* + * The list of completed SCBs in + * the active DMA. + */ + COMPLETE_SCB_DMAINPROG_HEAD { + size 2 + } + /* + * head of list of SCBs that have + * completed but need to be uploaded + * to the host prior to being completed. + */ + COMPLETE_DMA_SCB_HEAD { + size 2 + } + /* Counting semaphore to prevent new select-outs */ + QFREEZE_COUNT { + size 2 + } + /* + * Mode to restore on legacy idle loop exit. + */ + SAVED_MODE { + size 1 + } + /* + * Single byte buffer used to designate the type or message + * to send to a target. + */ + MSG_OUT { + size 1 + } + /* Parameters for DMA Logic */ + DMAPARAMS { + size 1 + field PRELOADEN 0x80 + field WIDEODD 0x40 + field SCSIEN 0x20 + field SDMAEN 0x10 + field SDMAENACK 0x10 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 /* Set indicates PCI->SCSI */ + field FIFOFLUSH 0x02 + field FIFORESET 0x01 + } + SEQ_FLAGS { + size 1 + field NOT_IDENTIFIED 0x80 + field NO_CDB_SENT 0x40 + field TARGET_CMD_IS_TAGGED 0x40 + field DPHASE 0x20 + /* Target flags */ + field TARG_CMD_PENDING 0x10 + field CMDPHASE_PENDING 0x08 + field DPHASE_PENDING 0x04 + field SPHASE_PENDING 0x02 + field NO_DISCONNECT 0x01 + } + /* + * Temporary storage for the + * target/channel/lun of a + * reconnecting target + */ + SAVED_SCSIID { + size 1 + } + SAVED_LUN { + size 1 + } + /* + * The last bus phase as seen by the sequencer. + */ + LASTPHASE { + size 1 + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 + field P_BUSFREE 0x01 + enum PHASE_MASK CDO|IOO|MSGO { + P_DATAOUT 0x0, + P_DATAIN IOO, + P_DATAOUT_DT P_DATAOUT|MSGO, + P_DATAIN_DT P_DATAIN|MSGO, + P_COMMAND CDO, + P_MESGOUT CDO|MSGO, + P_STATUS CDO|IOO, + P_MESGIN CDO|IOO|MSGO + } + } + /* + * Value to "or" into the SCBPTR[1] value to + * indicate that an entry in the QINFIFO is valid. + */ + QOUTFIFO_ENTRY_VALID_TAG { + size 1 + } + /* + * Base address of our shared data with the kernel driver in host + * memory. This includes the qoutfifo and target mode + * incoming command queue. + */ + SHARED_DATA_ADDR { + size 4 + } + /* + * Pointer to location in host memory for next + * position in the qoutfifo. + */ + QOUTFIFO_NEXT_ADDR { + size 4 + } + /* + * Kernel and sequencer offsets into the queue of + * incoming target mode command descriptors. The + * queue is full when the KERNEL_TQINPOS == TQINPOS. + */ + KERNEL_TQINPOS { + size 1 + } + TQINPOS { + size 1 + } + ARG_1 { + size 1 + mask SEND_MSG 0x80 + mask SEND_SENSE 0x40 + mask SEND_REJ 0x20 + mask MSGOUT_PHASEMIS 0x10 + mask EXIT_MSG_LOOP 0x08 + mask CONT_MSG_LOOP_WRITE 0x04 + mask CONT_MSG_LOOP_READ 0x03 + mask CONT_MSG_LOOP_TARG 0x02 + alias RETURN_1 + } + ARG_2 { + size 1 + alias RETURN_2 + } + + /* + * Snapshot of MSG_OUT taken after each message is sent. + */ + LAST_MSG { + size 1 + } + + /* + * Sequences the kernel driver has okayed for us. This allows + * the driver to do things like prevent initiator or target + * operations. + */ + SCSISEQ_TEMPLATE { + size 1 + field MANUALCTL 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field MANUALP 0x0C + field ENAUTOATNP 0x02 + field ALTSTIM 0x01 + } + + /* + * The initiator specified tag for this target mode transaction. + */ + INITIATOR_TAG { + size 1 + } + + SEQ_FLAGS2 { + size 1 + field TARGET_MSG_PENDING 0x02 + field SELECTOUT_QFROZEN 0x04 + } + + ALLOCFIFO_SCBPTR { + size 2 + } + + /* + * The maximum amount of time to wait, when interrupt coalessing + * is enabled, before issueing a CMDCMPLT interrupt for a completed + * command. + */ + INT_COALESSING_TIMER { + size 2 + } + + /* + * The maximum number of commands to coaless into a single interrupt. + * Actually the 2's complement of that value to simplify sequencer + * code. + */ + INT_COALESSING_MAXCMDS { + size 1 + } + + /* + * The minimum number of commands still outstanding required + * to continue coalessing (2's compliment of value). + */ + INT_COALESSING_MINCMDS { + size 1 + } + + /* + * Number of commands "in-flight". + */ + CMDS_PENDING { + size 2 + } + + /* + * The count of commands that have been coalessed. + */ + INT_COALESSING_CMDCOUNT { + size 1 + } + + /* + * Since the HS_MAIBOX is self clearing, copy its contents to + * this position in scratch ram every time it changes. + */ + LOCAL_HS_MAILBOX { + size 1 + } + /* + * Target-mode CDB type to CDB length table used + * in non-packetized operation. + */ + CMDSIZE_TABLE { + size 8 + } +} + +/************************* Hardware SCB Definition ****************************/ +scb { + address 0x180 + size 64 + modes 0, 1, 2, 3 + SCB_RESIDUAL_DATACNT { + size 4 + alias SCB_CDB_STORE + } + SCB_RESIDUAL_SGPTR { + size 4 + alias SCB_CDB_PTR + field SG_ADDR_MASK 0xf8 /* In the last byte */ + field SG_OVERRUN_RESID 0x02 /* In the first byte */ + field SG_LIST_NULL 0x01 /* In the first byte */ + } + SCB_SCSI_STATUS { + size 1 + } + SCB_TARGET_PHASES { + size 1 + } + SCB_TARGET_DATA_DIR { + size 1 + } + SCB_TARGET_ITAG { + size 1 + } + SCB_SENSE_BUSADDR { + /* + * Only valid if CDB length is less than 13 bytes or + * we are using a CDB pointer. Otherwise contains + * the last 4 bytes of embedded cdb information. + */ + size 4 + alias SCB_NEXT_COMPLETE + } + SCB_TAG { + size 2 + } + SCB_CDB_LEN { + size 1 + field SCB_CDB_LEN_PTR 0x80 /* CDB in host memory */ + } + SCB_TASK_MANAGEMENT { + size 1 + } + SCB_NEXT { + alias SCB_NEXT_SCB_BUSADDR + size 2 + } + SCB_NEXT2 { + size 2 + } + SCB_DATAPTR { + size 8 + } + SCB_DATACNT { + /* + * The last byte is really the high address bits for + * the data address. + */ + size 4 + field SG_LAST_SEG 0x80 /* In the fourth byte */ + field SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */ + } + SCB_SGPTR { + size 4 + field SG_STATUS_VALID 0x04 /* In the first byte */ + field SG_FULL_RESID 0x02 /* In the first byte */ + field SG_LIST_NULL 0x01 /* In the first byte */ + } + SCB_CONTROL { + size 1 + field TARGET_SCB 0x80 + field DISCENB 0x40 + field TAG_ENB 0x20 + field MK_MESSAGE 0x10 + field STATUS_RCVD 0x08 + field DISCONNECTED 0x04 + field SCB_TAG_TYPE 0x03 + } + SCB_SCSIID { + size 1 + field TID 0xF0 + field OID 0x0F + } + SCB_LUN { + size 1 + field LID 0xff + } + SCB_TASK_ATTRIBUTE { + size 1 + } + SCB_BUSADDR { + size 4 + } + SCB_SPARE { + size 8 + alias SCB_PKT_LUN + } + SCB_DISCONNECTED_LISTS { + size 8 + } +} + +/*********************************** Constants ********************************/ +const MK_MESSAGE_BIT_OFFSET 4 +const TID_SHIFT 4 +const TARGET_CMD_CMPLT 0xfe +const INVALID_ADDR 0x80 +#define SCB_LIST_NULL 0xff +#define QOUTFIFO_ENTRY_VALID_TOGGLE 0x80 + +const CCSGADDR_MAX 0x80 +const CCSCBADDR_MAX 0x80 +const CCSGRAM_MAXSEGS 16 + +/* Selection Timeout Timer Constants */ +const STIMESEL_SHIFT 3 +const STIMESEL_MIN 0x18 +const STIMESEL_BUG_ADJ 0x8 + +/* WDTR Message values */ +const BUS_8_BIT 0x00 +const BUS_16_BIT 0x01 +const BUS_32_BIT 0x02 + +/* Offset maximums */ +const MAX_OFFSET 0xfe +const MAX_OFFSET_PACED 0xfe +const MAX_OFFSET_PACED_BUG 0x7f +/* + * Some 160 devices incorrectly accept 0xfe as a + * sync offset, but will overrun this value. Limit + * to 0x7f for speed lower than U320 which will + * avoid the persistent sync offset overruns. + */ +const MAX_OFFSET_NON_PACED 0x7f +const HOST_MSG 0xff + +/* + * The size of our sense buffers. + * Sense buffer mapping can be handled in either of two ways. + * The first is to allocate a dmamap for each transaction. + * Depending on the architecture, dmamaps can be costly. The + * alternative is to statically map the buffers in much the same + * way we handle our scatter gather lists. The driver implements + * the later. + */ +const AHD_SENSE_BUFSIZE 256 + +/* Target mode command processing constants */ +const CMD_GROUP_CODE_SHIFT 0x05 + +const STATUS_BUSY 0x08 +const STATUS_QUEUE_FULL 0x28 +const STATUS_PKT_SENSE 0xFF +const TARGET_DATA_IN 1 + +const SCB_TRANSFER_SIZE_FULL_LUN 56 +const SCB_TRANSFER_SIZE_1BYTE_LUN 48 +/* PKT_OVERRUN_BUFSIZE must be a multiple of 256 less than 64K */ +const PKT_OVERRUN_BUFSIZE 512 + +/* + * Timer parameters. + */ +const AHD_TIMER_US_PER_TICK 25 +const AHD_TIMER_MAX_TICKS 0xFFFF +const AHD_TIMER_MAX_US (AHD_TIMER_MAX_TICKS * AHD_TIMER_US_PER_TICK) + +/* + * Downloaded (kernel inserted) constants + */ +const SG_PREFETCH_CNT download +const SG_PREFETCH_CNT_LIMIT download +const SG_PREFETCH_ALIGN_MASK download +const SG_PREFETCH_ADDR_MASK download +const SG_SIZEOF download +const PKT_OVERRUN_BUFOFFSET download +const SCB_TRANSFER_SIZE download + +/* + * BIOS SCB offsets + */ +const NVRAM_SCB_OFFSET 0x2C diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_reg.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_reg.h --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_reg.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_reg.h 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,3778 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ + */ +typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); +typedef struct ahd_reg_parse_entry { + char *name; + uint8_t value; + uint8_t mask; +} ahd_reg_parse_entry_t; + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_mode_ptr_print; +#else +#define ahd_mode_ptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MODE_PTR", 0x00, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intstat_print; +#else +#define ahd_intstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTSTAT", 0x01, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintcode_print; +#else +#define ahd_seqintcode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTCODE", 0x02, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrint_print; +#else +#define ahd_clrint_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRINT", 0x03, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_error_print; +#else +#define ahd_error_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ERROR", 0x04, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrerr_print; +#else +#define ahd_clrerr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRERR", 0x04, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hcntrl_print; +#else +#define ahd_hcntrl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HCNTRL", 0x05, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hnscb_qoff_print; +#else +#define ahd_hnscb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HNSCB_QOFF", 0x06, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hescb_qoff_print; +#else +#define ahd_hescb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HESCB_QOFF", 0x08, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hs_mailbox_print; +#else +#define ahd_hs_mailbox_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HS_MAILBOX", 0x0b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrseqintstat_print; +#else +#define ahd_clrseqintstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSEQINTSTAT", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintstat_print; +#else +#define ahd_seqintstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTSTAT", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_swtimer_print; +#else +#define ahd_swtimer_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SWTIMER", 0x0e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_snscb_qoff_print; +#else +#define ahd_snscb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SNSCB_QOFF", 0x10, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sescb_qoff_print; +#else +#define ahd_sescb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SESCB_QOFF", 0x12, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sdscb_qoff_print; +#else +#define ahd_sdscb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SDSCB_QOFF", 0x14, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qoff_ctlsta_print; +#else +#define ahd_qoff_ctlsta_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QOFF_CTLSTA", 0x16, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intctl_print; +#else +#define ahd_intctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTCTL", 0x18, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfcntrl_print; +#else +#define ahd_dfcntrl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFCNTRL", 0x19, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dscommand0_print; +#else +#define ahd_dscommand0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSCOMMAND0", 0x19, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfstatus_print; +#else +#define ahd_dfstatus_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFSTATUS", 0x1a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sg_cache_shadow_print; +#else +#define ahd_sg_cache_shadow_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SG_CACHE_SHADOW", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_arbctl_print; +#else +#define ahd_arbctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ARBCTL", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sg_cache_pre_print; +#else +#define ahd_sg_cache_pre_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SG_CACHE_PRE", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqin_print; +#else +#define ahd_lqin_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQIN", 0x20, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_typeptr_print; +#else +#define ahd_typeptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TYPEPTR", 0x20, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_tagptr_print; +#else +#define ahd_tagptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TAGPTR", 0x21, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lunptr_print; +#else +#define ahd_lunptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LUNPTR", 0x22, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_datalenptr_print; +#else +#define ahd_datalenptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DATALENPTR", 0x23, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_statlenptr_print; +#else +#define ahd_statlenptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "STATLENPTR", 0x24, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdlenptr_print; +#else +#define ahd_cmdlenptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDLENPTR", 0x25, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_attrptr_print; +#else +#define ahd_attrptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ATTRPTR", 0x26, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flagptr_print; +#else +#define ahd_flagptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLAGPTR", 0x27, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdptr_print; +#else +#define ahd_cmdptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDPTR", 0x28, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qnextptr_print; +#else +#define ahd_qnextptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QNEXTPTR", 0x29, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_idptr_print; +#else +#define ahd_idptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "IDPTR", 0x2a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_abrtbyteptr_print; +#else +#define ahd_abrtbyteptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ABRTBYTEPTR", 0x2b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_abrtbitptr_print; +#else +#define ahd_abrtbitptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ABRTBITPTR", 0x2c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmdbytes_print; +#else +#define ahd_maxcmdbytes_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMDBYTES", 0x2d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmd2rcv_print; +#else +#define ahd_maxcmd2rcv_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMD2RCV", 0x2e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shortthresh_print; +#else +#define ahd_shortthresh_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHORTTHRESH", 0x2f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lunlen_print; +#else +#define ahd_lunlen_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LUNLEN", 0x30, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cdblimit_print; +#else +#define ahd_cdblimit_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CDBLIMIT", 0x31, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmd_print; +#else +#define ahd_maxcmd_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMD", 0x32, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmdcnt_print; +#else +#define ahd_maxcmdcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMDCNT", 0x33, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqrsvd01_print; +#else +#define ahd_lqrsvd01_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQRSVD01", 0x34, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqrsvd16_print; +#else +#define ahd_lqrsvd16_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQRSVD16", 0x35, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqrsvd17_print; +#else +#define ahd_lqrsvd17_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQRSVD17", 0x36, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdrsvd0_print; +#else +#define ahd_cmdrsvd0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDRSVD0", 0x37, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqctl0_print; +#else +#define ahd_lqctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQCTL0", 0x38, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqctl1_print; +#else +#define ahd_lqctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQCTL1", 0x38, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsbist0_print; +#else +#define ahd_scsbist0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSBIST0", 0x39, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqctl2_print; +#else +#define ahd_lqctl2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQCTL2", 0x39, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsbist1_print; +#else +#define ahd_scsbist1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSBIST1", 0x3a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiseq0_print; +#else +#define ahd_scsiseq0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISEQ0", 0x3a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiseq1_print; +#else +#define ahd_scsiseq1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISEQ1", 0x3b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sxfrctl0_print; +#else +#define ahd_sxfrctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SXFRCTL0", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_businitid_print; +#else +#define ahd_businitid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BUSINITID", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dlcount_print; +#else +#define ahd_dlcount_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DLCOUNT", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sxfrctl1_print; +#else +#define ahd_sxfrctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SXFRCTL1", 0x3d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_bustargid_print; +#else +#define ahd_bustargid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BUSTARGID", 0x3e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sxfrctl2_print; +#else +#define ahd_sxfrctl2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SXFRCTL2", 0x3e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dffstat_print; +#else +#define ahd_dffstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFFSTAT", 0x3f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsisigo_print; +#else +#define ahd_scsisigo_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISIGO", 0x40, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_multargid_print; +#else +#define ahd_multargid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MULTARGID", 0x40, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsisigi_print; +#else +#define ahd_scsisigi_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISIGI", 0x41, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiphase_print; +#else +#define ahd_scsiphase_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIPHASE", 0x42, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsidat0_img_print; +#else +#define ahd_scsidat0_img_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIDAT0_IMG", 0x43, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsidat_print; +#else +#define ahd_scsidat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIDAT", 0x44, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsibus_print; +#else +#define ahd_scsibus_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIBUS", 0x46, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_targidin_print; +#else +#define ahd_targidin_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TARGIDIN", 0x48, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_selid_print; +#else +#define ahd_selid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SELID", 0x49, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sblkctl_print; +#else +#define ahd_sblkctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SBLKCTL", 0x4a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_optionmode_print; +#else +#define ahd_optionmode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OPTIONMODE", 0x4a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat0_print; +#else +#define ahd_sstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT0", 0x4b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint0_print; +#else +#define ahd_clrsint0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT0", 0x4b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode0_print; +#else +#define ahd_simode0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE0", 0x4b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint1_print; +#else +#define ahd_clrsint1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT1", 0x4c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat1_print; +#else +#define ahd_sstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT1", 0x4c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat2_print; +#else +#define ahd_sstat2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT2", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint2_print; +#else +#define ahd_clrsint2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT2", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode2_print; +#else +#define ahd_simode2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE2", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_perrdiag_print; +#else +#define ahd_perrdiag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PERRDIAG", 0x4e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistate_print; +#else +#define ahd_lqistate_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTATE", 0x4e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_soffcnt_print; +#else +#define ahd_soffcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SOFFCNT", 0x4f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostate_print; +#else +#define ahd_lqostate_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTATE", 0x4f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistat0_print; +#else +#define ahd_lqistat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTAT0", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqiint0_print; +#else +#define ahd_clrlqiint0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQIINT0", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqimode0_print; +#else +#define ahd_lqimode0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQIMODE0", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqimode1_print; +#else +#define ahd_lqimode1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQIMODE1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistat1_print; +#else +#define ahd_lqistat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTAT1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqiint1_print; +#else +#define ahd_clrlqiint1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQIINT1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistat2_print; +#else +#define ahd_lqistat2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTAT2", 0x52, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat3_print; +#else +#define ahd_sstat3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT3", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode3_print; +#else +#define ahd_simode3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE3", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint3_print; +#else +#define ahd_clrsint3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT3", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqomode0_print; +#else +#define ahd_lqomode0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOMODE0", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostat0_print; +#else +#define ahd_lqostat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTAT0", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqoint0_print; +#else +#define ahd_clrlqoint0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQOINT0", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostat1_print; +#else +#define ahd_lqostat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTAT1", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqoint1_print; +#else +#define ahd_clrlqoint1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQOINT1", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqomode1_print; +#else +#define ahd_lqomode1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOMODE1", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostat2_print; +#else +#define ahd_lqostat2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTAT2", 0x56, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_os_space_cnt_print; +#else +#define ahd_os_space_cnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OS_SPACE_CNT", 0x56, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode1_print; +#else +#define ahd_simode1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE1", 0x57, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_gsfifo_print; +#else +#define ahd_gsfifo_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "GSFIFO", 0x58, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dffsxfrctl_print; +#else +#define ahd_dffsxfrctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFFSXFRCTL", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqoscsctl_print; +#else +#define ahd_lqoscsctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSCSCTL", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_nextscb_print; +#else +#define ahd_nextscb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEXTSCB", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrseqintsrc_print; +#else +#define ahd_clrseqintsrc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSEQINTSRC", 0x5b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintsrc_print; +#else +#define ahd_seqintsrc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTSRC", 0x5b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_currscb_print; +#else +#define ahd_currscb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CURRSCB", 0x5c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqimode_print; +#else +#define ahd_seqimode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQIMODE", 0x5c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_mdffstat_print; +#else +#define ahd_mdffstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MDFFSTAT", 0x5d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_crccontrol_print; +#else +#define ahd_crccontrol_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CRCCONTROL", 0x5d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfftag_print; +#else +#define ahd_dfftag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFFTAG", 0x5e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lastscb_print; +#else +#define ahd_lastscb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LASTSCB", 0x5e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsitest_print; +#else +#define ahd_scsitest_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSITEST", 0x5e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_iopdnctl_print; +#else +#define ahd_iopdnctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "IOPDNCTL", 0x5f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shaddr_print; +#else +#define ahd_shaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHADDR", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negoaddr_print; +#else +#define ahd_negoaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGOADDR", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dgrpcrci_print; +#else +#define ahd_dgrpcrci_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DGRPCRCI", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negperiod_print; +#else +#define ahd_negperiod_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGPERIOD", 0x61, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_packcrci_print; +#else +#define ahd_packcrci_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PACKCRCI", 0x62, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negoffset_print; +#else +#define ahd_negoffset_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGOFFSET", 0x62, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negppropts_print; +#else +#define ahd_negppropts_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGPPROPTS", 0x63, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negconopts_print; +#else +#define ahd_negconopts_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGCONOPTS", 0x64, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_annexcol_print; +#else +#define ahd_annexcol_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ANNEXCOL", 0x65, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scschkn_print; +#else +#define ahd_scschkn_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSCHKN", 0x66, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_annexdat_print; +#else +#define ahd_annexdat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ANNEXDAT", 0x66, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_iownid_print; +#else +#define ahd_iownid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "IOWNID", 0x67, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll960ctl0_print; +#else +#define ahd_pll960ctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL960CTL0", 0x68, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shcnt_print; +#else +#define ahd_shcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHCNT", 0x68, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_townid_print; +#else +#define ahd_townid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TOWNID", 0x69, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll960ctl1_print; +#else +#define ahd_pll960ctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL960CTL1", 0x69, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll960cnt0_print; +#else +#define ahd_pll960cnt0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL960CNT0", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_xsig_print; +#else +#define ahd_xsig_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "XSIG", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seloid_print; +#else +#define ahd_seloid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SELOID", 0x6b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll400ctl0_print; +#else +#define ahd_pll400ctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL400CTL0", 0x6c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_fairness_print; +#else +#define ahd_fairness_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FAIRNESS", 0x6c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll400ctl1_print; +#else +#define ahd_pll400ctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL400CTL1", 0x6d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll400cnt0_print; +#else +#define ahd_pll400cnt0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL400CNT0", 0x6e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_unfairness_print; +#else +#define ahd_unfairness_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "UNFAIRNESS", 0x6e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_haddr_print; +#else +#define ahd_haddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HADDR", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_plldelay_print; +#else +#define ahd_plldelay_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLLDELAY", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hodmaadr_print; +#else +#define ahd_hodmaadr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HODMAADR", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hodmacnt_print; +#else +#define ahd_hodmacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HODMACNT", 0x78, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hcnt_print; +#else +#define ahd_hcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HCNT", 0x78, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hodmaen_print; +#else +#define ahd_hodmaen_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HODMAEN", 0x7a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sghaddr_print; +#else +#define ahd_sghaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGHADDR", 0x7c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbhaddr_print; +#else +#define ahd_scbhaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBHADDR", 0x7c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sghcnt_print; +#else +#define ahd_sghcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGHCNT", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbhcnt_print; +#else +#define ahd_scbhcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBHCNT", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dff_thrsh_print; +#else +#define ahd_dff_thrsh_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFF_THRSH", 0x88, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_romaddr_print; +#else +#define ahd_romaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROMADDR", 0x8a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_romcntrl_print; +#else +#define ahd_romcntrl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROMCNTRL", 0x8d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_romdata_print; +#else +#define ahd_romdata_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROMDATA", 0x8e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg0_print; +#else +#define ahd_cmcrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG0", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_roenable_print; +#else +#define ahd_roenable_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROENABLE", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg0_print; +#else +#define ahd_ovlyrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG0", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg0_print; +#else +#define ahd_dchrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG0", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg1_print; +#else +#define ahd_ovlyrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG1", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_nsenable_print; +#else +#define ahd_nsenable_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NSENABLE", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg1_print; +#else +#define ahd_dchrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG1", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg1_print; +#else +#define ahd_cmcrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG1", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg2_print; +#else +#define ahd_dchrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG2", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg2_print; +#else +#define ahd_ovlyrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG2", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg2_print; +#else +#define ahd_cmcrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG2", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ost_print; +#else +#define ahd_ost_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OST", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg3_print; +#else +#define ahd_dchrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG3", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg3_print; +#else +#define ahd_cmcrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG3", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pcixctl_print; +#else +#define ahd_pcixctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PCIXCTL", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg3_print; +#else +#define ahd_ovlyrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG3", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyseqbcnt_print; +#else +#define ahd_ovlyseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYSEQBCNT", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcseqbcnt_print; +#else +#define ahd_cmcseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCSEQBCNT", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchseqbcnt_print; +#else +#define ahd_dchseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHSEQBCNT", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcspltstat0_print; +#else +#define ahd_cmcspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCSPLTSTAT0", 0x96, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyspltstat0_print; +#else +#define ahd_ovlyspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYSPLTSTAT0", 0x96, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchspltstat0_print; +#else +#define ahd_dchspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHSPLTSTAT0", 0x96, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchspltstat1_print; +#else +#define ahd_dchspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHSPLTSTAT1", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcspltstat1_print; +#else +#define ahd_cmcspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCSPLTSTAT1", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyspltstat1_print; +#else +#define ahd_ovlyspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYSPLTSTAT1", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg0_print; +#else +#define ahd_sgrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG0", 0x98, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr0_print; +#else +#define ahd_slvspltoutadr0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR0", 0x98, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg1_print; +#else +#define ahd_sgrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG1", 0x99, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr1_print; +#else +#define ahd_slvspltoutadr1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR1", 0x99, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg2_print; +#else +#define ahd_sgrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG2", 0x9a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr2_print; +#else +#define ahd_slvspltoutadr2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR2", 0x9a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg3_print; +#else +#define ahd_sgrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG3", 0x9b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr3_print; +#else +#define ahd_slvspltoutadr3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR3", 0x9b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgseqbcnt_print; +#else +#define ahd_sgseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGSEQBCNT", 0x9c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutattr0_print; +#else +#define ahd_slvspltoutattr0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTATTR0", 0x9c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutattr1_print; +#else +#define ahd_slvspltoutattr1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTATTR1", 0x9d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutattr2_print; +#else +#define ahd_slvspltoutattr2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTATTR2", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgspltstat0_print; +#else +#define ahd_sgspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGSPLTSTAT0", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sfunct_print; +#else +#define ahd_sfunct_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgspltstat1_print; +#else +#define ahd_sgspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGSPLTSTAT1", 0x9f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_df0pcistat_print; +#else +#define ahd_df0pcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DF0PCISTAT", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_reg0_print; +#else +#define ahd_reg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "REG0", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_df1pcistat_print; +#else +#define ahd_df1pcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DF1PCISTAT", 0xa1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgpcistat_print; +#else +#define ahd_sgpcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGPCISTAT", 0xa2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_reg1_print; +#else +#define ahd_reg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "REG1", 0xa2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcpcistat_print; +#else +#define ahd_cmcpcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCPCISTAT", 0xa3, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlypcistat_print; +#else +#define ahd_ovlypcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYPCISTAT", 0xa4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_reg_isr_print; +#else +#define ahd_reg_isr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "REG_ISR", 0xa4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sg_state_print; +#else +#define ahd_sg_state_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SG_STATE", 0xa6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_msipcistat_print; +#else +#define ahd_msipcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MSIPCISTAT", 0xa6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_targpcistat_print; +#else +#define ahd_targpcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TARGPCISTAT", 0xa7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_data_count_odd_print; +#else +#define ahd_data_count_odd_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DATA_COUNT_ODD", 0xa7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbptr_print; +#else +#define ahd_scbptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBPTR", 0xa8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbacnt_print; +#else +#define ahd_ccscbacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBACNT", 0xab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbautoptr_print; +#else +#define ahd_scbautoptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBAUTOPTR", 0xab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccsgaddr_print; +#else +#define ahd_ccsgaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSGADDR", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbaddr_print; +#else +#define ahd_ccscbaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBADDR", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbadr_bk_print; +#else +#define ahd_ccscbadr_bk_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBADR_BK", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmc_rambist_print; +#else +#define ahd_cmc_rambist_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMC_RAMBIST", 0xad, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccsgctl_print; +#else +#define ahd_ccsgctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSGCTL", 0xad, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbctl_print; +#else +#define ahd_ccscbctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBCTL", 0xad, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccsgram_print; +#else +#define ahd_ccsgram_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSGRAM", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexadr_print; +#else +#define ahd_flexadr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXADR", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbram_print; +#else +#define ahd_ccscbram_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBRAM", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexcnt_print; +#else +#define ahd_flexcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXCNT", 0xb3, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexdmastat_print; +#else +#define ahd_flexdmastat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXDMASTAT", 0xb5, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexdata_print; +#else +#define ahd_flexdata_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXDATA", 0xb6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brddat_print; +#else +#define ahd_brddat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRDDAT", 0xb8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brdctl_print; +#else +#define ahd_brdctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRDCTL", 0xb9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seeadr_print; +#else +#define ahd_seeadr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEEADR", 0xba, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seedat_print; +#else +#define ahd_seedat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEEDAT", 0xbc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seectl_print; +#else +#define ahd_seectl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEECTL", 0xbe, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seestat_print; +#else +#define ahd_seestat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEESTAT", 0xbe, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbcnt_print; +#else +#define ahd_scbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBCNT", 0xbf, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfwaddr_print; +#else +#define ahd_dfwaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFWADDR", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspfltrctl_print; +#else +#define ahd_dspfltrctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPFLTRCTL", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspdatactl_print; +#else +#define ahd_dspdatactl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPDATACTL", 0xc1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfraddr_print; +#else +#define ahd_dfraddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFRADDR", 0xc2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspreqctl_print; +#else +#define ahd_dspreqctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPREQCTL", 0xc2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspackctl_print; +#else +#define ahd_dspackctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPACKCTL", 0xc3, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfdat_print; +#else +#define ahd_dfdat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFDAT", 0xc4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspselect_print; +#else +#define ahd_dspselect_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPSELECT", 0xc4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_wrtbiasctl_print; +#else +#define ahd_wrtbiasctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WRTBIASCTL", 0xc5, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_rcvrbiosctl_print; +#else +#define ahd_rcvrbiosctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "RCVRBIOSCTL", 0xc6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_wrtbiascalc_print; +#else +#define ahd_wrtbiascalc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WRTBIASCALC", 0xc7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfptrs_print; +#else +#define ahd_dfptrs_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFPTRS", 0xc8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_rcvrbiascalc_print; +#else +#define ahd_rcvrbiascalc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "RCVRBIASCALC", 0xc8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfbkptr_print; +#else +#define ahd_dfbkptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFBKPTR", 0xc9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_skewcalc_print; +#else +#define ahd_skewcalc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SKEWCALC", 0xc9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfdbctl_print; +#else +#define ahd_dfdbctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFDBCTL", 0xcb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfscnt_print; +#else +#define ahd_dfscnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFSCNT", 0xcc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfbcnt_print; +#else +#define ahd_dfbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFBCNT", 0xce, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyaddr_print; +#else +#define ahd_ovlyaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYADDR", 0xd4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqctl0_print; +#else +#define ahd_seqctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQCTL0", 0xd6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqctl1_print; +#else +#define ahd_seqctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQCTL1", 0xd7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flags_print; +#else +#define ahd_flags_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLAGS", 0xd8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintctl_print; +#else +#define ahd_seqintctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTCTL", 0xd9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqram_print; +#else +#define ahd_seqram_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQRAM", 0xda, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_prgmcnt_print; +#else +#define ahd_prgmcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PRGMCNT", 0xde, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_accum_print; +#else +#define ahd_accum_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ACCUM", 0xe0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sindex_print; +#else +#define ahd_sindex_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SINDEX", 0xe2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dindex_print; +#else +#define ahd_dindex_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DINDEX", 0xe4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brkaddr1_print; +#else +#define ahd_brkaddr1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRKADDR1", 0xe6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brkaddr0_print; +#else +#define ahd_brkaddr0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRKADDR0", 0xe6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_allones_print; +#else +#define ahd_allones_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ALLONES", 0xe8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_allzeros_print; +#else +#define ahd_allzeros_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ALLZEROS", 0xea, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_none_print; +#else +#define ahd_none_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NONE", 0xea, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sindir_print; +#else +#define ahd_sindir_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SINDIR", 0xec, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dindir_print; +#else +#define ahd_dindir_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DINDIR", 0xed, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_function1_print; +#else +#define ahd_function1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FUNCTION1", 0xf0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_stack_print; +#else +#define ahd_stack_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "STACK", 0xf2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_curaddr_print; +#else +#define ahd_curaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CURADDR", 0xf4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intvec1_addr_print; +#else +#define ahd_intvec1_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTVEC1_ADDR", 0xf4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intvec2_addr_print; +#else +#define ahd_intvec2_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTVEC2_ADDR", 0xf6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lastaddr_print; +#else +#define ahd_lastaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LASTADDR", 0xf6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_longjmp_addr_print; +#else +#define ahd_longjmp_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LONGJMP_ADDR", 0xf8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_longjmp_scb_print; +#else +#define ahd_longjmp_scb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LONGJMP_SCB", 0xfa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_accum_save_print; +#else +#define ahd_accum_save_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ACCUM_SAVE", 0xfc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_waiting_scb_tails_print; +#else +#define ahd_waiting_scb_tails_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", 0x100, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ahd_pci_config_base_print; +#else +#define ahd_ahd_pci_config_base_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", 0x100, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sram_base_print; +#else +#define ahd_sram_base_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SRAM_BASE", 0x100, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_waiting_tid_head_print; +#else +#define ahd_waiting_tid_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WAITING_TID_HEAD", 0x120, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_waiting_tid_tail_print; +#else +#define ahd_waiting_tid_tail_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WAITING_TID_TAIL", 0x122, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_next_queued_scb_addr_print; +#else +#define ahd_next_queued_scb_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", 0x124, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_complete_scb_head_print; +#else +#define ahd_complete_scb_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", 0x128, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_complete_scb_dmainprog_head_print; +#else +#define ahd_complete_scb_dmainprog_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", 0x12a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_complete_dma_scb_head_print; +#else +#define ahd_complete_dma_scb_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", 0x12c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qfreeze_count_print; +#else +#define ahd_qfreeze_count_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QFREEZE_COUNT", 0x12e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_saved_mode_print; +#else +#define ahd_saved_mode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SAVED_MODE", 0x130, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_msg_out_print; +#else +#define ahd_msg_out_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MSG_OUT", 0x131, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dmaparams_print; +#else +#define ahd_dmaparams_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DMAPARAMS", 0x132, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seq_flags_print; +#else +#define ahd_seq_flags_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQ_FLAGS", 0x133, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_saved_scsiid_print; +#else +#define ahd_saved_scsiid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SAVED_SCSIID", 0x134, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_saved_lun_print; +#else +#define ahd_saved_lun_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SAVED_LUN", 0x135, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lastphase_print; +#else +#define ahd_lastphase_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LASTPHASE", 0x136, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qoutfifo_entry_valid_tag_print; +#else +#define ahd_qoutfifo_entry_valid_tag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", 0x137, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shared_data_addr_print; +#else +#define ahd_shared_data_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x138, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qoutfifo_next_addr_print; +#else +#define ahd_qoutfifo_next_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", 0x13c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_kernel_tqinpos_print; +#else +#define ahd_kernel_tqinpos_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "KERNEL_TQINPOS", 0x140, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_tqinpos_print; +#else +#define ahd_tqinpos_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TQINPOS", 0x141, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_arg_1_print; +#else +#define ahd_arg_1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ARG_1", 0x142, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_arg_2_print; +#else +#define ahd_arg_2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ARG_2", 0x143, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_last_msg_print; +#else +#define ahd_last_msg_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LAST_MSG", 0x144, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiseq_template_print; +#else +#define ahd_scsiseq_template_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x145, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_initiator_tag_print; +#else +#define ahd_initiator_tag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INITIATOR_TAG", 0x146, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seq_flags2_print; +#else +#define ahd_seq_flags2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQ_FLAGS2", 0x147, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_allocfifo_scbptr_print; +#else +#define ahd_allocfifo_scbptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", 0x148, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalessing_timer_print; +#else +#define ahd_int_coalessing_timer_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESSING_TIMER", 0x14a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalessing_maxcmds_print; +#else +#define ahd_int_coalessing_maxcmds_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS", 0x14c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalessing_mincmds_print; +#else +#define ahd_int_coalessing_mincmds_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS", 0x14d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmds_pending_print; +#else +#define ahd_cmds_pending_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDS_PENDING", 0x14e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalessing_cmdcount_print; +#else +#define ahd_int_coalessing_cmdcount_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT", 0x150, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_local_hs_mailbox_print; +#else +#define ahd_local_hs_mailbox_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", 0x151, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdsize_table_print; +#else +#define ahd_cmdsize_table_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDSIZE_TABLE", 0x152, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_base_print; +#else +#define ahd_scb_base_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_BASE", 0x180, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_residual_datacnt_print; +#else +#define ahd_scb_residual_datacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", 0x180, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_residual_sgptr_print; +#else +#define ahd_scb_residual_sgptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0x184, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_scsi_status_print; +#else +#define ahd_scb_scsi_status_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", 0x188, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_target_phases_print; +#else +#define ahd_scb_target_phases_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", 0x189, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_target_data_dir_print; +#else +#define ahd_scb_target_data_dir_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0x18a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_target_itag_print; +#else +#define ahd_scb_target_itag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", 0x18b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_sense_busaddr_print; +#else +#define ahd_scb_sense_busaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", 0x18c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_tag_print; +#else +#define ahd_scb_tag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_cdb_len_print; +#else +#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x192, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_task_management_print; +#else +#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x193, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_next_print; +#else +#define ahd_scb_next_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_NEXT", 0x194, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_next2_print; +#else +#define ahd_scb_next2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_NEXT2", 0x196, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_dataptr_print; +#else +#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_datacnt_print; +#else +#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_sgptr_print; +#else +#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_control_print; +#else +#define ahd_scb_control_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_CONTROL", 0x1a8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_scsiid_print; +#else +#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SCSIID", 0x1a9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_lun_print; +#else +#define ahd_scb_lun_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_LUN", 0x1aa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_task_attribute_print; +#else +#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x1ab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_busaddr_print; +#else +#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1ac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_spare_print; +#else +#define ahd_scb_spare_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SPARE", 0x1b0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_disconnected_lists_print; +#else +#define ahd_scb_disconnected_lists_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", 0x1b8, regvalue, cur_col, wrap) +#endif + + +#define MODE_PTR 0x00 +#define DST_MODE 0x70 +#define SRC_MODE 0x07 + +#define INTSTAT 0x01 +#define INT_PEND 0xff +#define HWERRINT 0x80 +#define BRKADRINT 0x40 +#define SWTMINT 0x20 +#define PCIINT 0x10 +#define SCSIINT 0x08 +#define SEQINT 0x04 +#define CMDCMPLT 0x02 +#define SPLTINT 0x01 + +#define SEQINTCODE 0x02 +#define SAW_HWERR 0x19 +#define TRACEPOINT3 0x18 +#define TRACEPOINT2 0x17 +#define TRACEPOINT1 0x16 +#define TRACEPOINT0 0x15 +#define TASKMGMT_CMD_CMPLT_OKAY 0x14 +#define TASKMGMT_FUNC_COMPLETE 0x13 +#define ENTERING_NONPACK 0x12 +#define CFG4OVERRUN 0x11 +#define STATUS_OVERRUN 0x10 +#define CFG4ISTAT_INTR 0x0f +#define INVALID_SEQINT 0x0e +#define ILLEGAL_PHASE 0x0d +#define DUMP_CARD_STATE 0x0c +#define MISSED_BUSFREE 0x0b +#define MKMSG_FAILED 0x0a +#define DATA_OVERRUN 0x09 +#define BAD_STATUS 0x08 +#define HOST_MSG_LOOP 0x07 +#define PDATA_REINIT 0x06 +#define IGN_WIDE_RES 0x05 +#define NO_MATCH 0x04 +#define PROTO_VIOLATION 0x03 +#define SEND_REJECT 0x02 +#define BAD_PHASE 0x01 +#define NO_SEQINT 0x00 + +#define CLRINT 0x03 +#define CLRHWERRINT 0x80 +#define CLRBRKADRINT 0x40 +#define CLRSWTMINT 0x20 +#define CLRPCIINT 0x10 +#define CLRSCSIINT 0x08 +#define CLRSEQINT 0x04 +#define CLRCMDINT 0x02 +#define CLRSPLTINT 0x01 + +#define ERROR 0x04 +#define CIOPARERR 0x80 +#define CIOACCESFAIL 0x40 +#define MPARERR 0x20 +#define DPARERR 0x10 +#define SQPARERR 0x08 +#define ILLOPCODE 0x04 +#define DSCTMOUT 0x02 + +#define CLRERR 0x04 +#define CLRCIOPARERR 0x80 +#define CLRCIOACCESFAIL 0x40 +#define CLRMPARERR 0x20 +#define CLRDPARERR 0x10 +#define CLRSQPARERR 0x08 +#define CLRILLOPCODE 0x04 +#define CLRDSCTMOUT 0x02 + +#define HCNTRL 0x05 +#define SEQ_RESET 0x80 +#define POWRDN 0x40 +#define SWINT 0x10 +#define SWTIMER_START_B 0x08 +#define PAUSE 0x04 +#define INTEN 0x02 +#define CHIPRST 0x01 +#define CHIPRSTACK 0x01 + +#define HNSCB_QOFF 0x06 + +#define HESCB_QOFF 0x08 + +#define HS_MAILBOX 0x0b +#define HOST_TQINPOS 0x80 +#define ENINT_COALESS 0x40 + +#define CLRSEQINTSTAT 0x0c +#define CLRSEQ_SWTMRTO 0x10 +#define CLRSEQ_SEQINT 0x08 +#define CLRSEQ_SCSIINT 0x04 +#define CLRSEQ_PCIINT 0x02 +#define CLRSEQ_SPLTINT 0x01 + +#define SEQINTSTAT 0x0c +#define SEQ_SWTMRTO 0x10 +#define SEQ_SEQINT 0x08 +#define SEQ_SCSIINT 0x04 +#define SEQ_PCIINT 0x02 +#define SEQ_SPLTINT 0x01 + +#define SWTIMER 0x0e + +#define SNSCB_QOFF 0x10 + +#define SESCB_QOFF 0x12 + +#define SDSCB_QOFF 0x14 + +#define QOFF_CTLSTA 0x16 +#define EMPTY_SCB_AVAIL 0x80 +#define NEW_SCB_AVAIL 0x40 +#define SDSCB_ROLLOVR 0x20 +#define HS_MAILBOX_ACT 0x10 +#define SCB_QSIZE 0x0f +#define SCB_QSIZE_16384 0x0c +#define SCB_QSIZE_8192 0x0b +#define SCB_QSIZE_4096 0x0a +#define SCB_QSIZE_2048 0x09 +#define SCB_QSIZE_1024 0x08 +#define SCB_QSIZE_512 0x07 +#define SCB_QSIZE_256 0x06 +#define SCB_QSIZE_128 0x05 +#define SCB_QSIZE_64 0x04 +#define SCB_QSIZE_32 0x03 +#define SCB_QSIZE_16 0x02 +#define SCB_QSIZE_8 0x01 +#define SCB_QSIZE_4 0x00 + +#define INTCTL 0x18 +#define SWTMINTMASK 0x80 +#define SWTMINTEN 0x40 +#define SWTIMER_START 0x20 +#define AUTOCLRCMDINT 0x10 +#define PCIINTEN 0x08 +#define SCSIINTEN 0x04 +#define SEQINTEN 0x02 +#define SPLTINTEN 0x01 + +#define DFCNTRL 0x19 +#define SCSIENWRDIS 0x40 +#define SCSIENACK 0x20 +#define DIRECTIONACK 0x04 +#define FIFOFLUSHACK 0x02 +#define DIRECTIONEN 0x01 + +#define DSCOMMAND0 0x19 +#define CACHETHEN 0x80 +#define DPARCKEN 0x40 +#define MPARCKEN 0x20 +#define EXTREQLCK 0x10 +#define DISABLE_TWATE 0x02 +#define CIOPARCKEN 0x01 + +#define DFSTATUS 0x1a +#define PRELOAD_AVAIL 0x80 +#define PKT_PRELOAD_AVAIL 0x40 +#define MREQPEND 0x10 +#define HDONE 0x08 +#define DFTHRESH 0x04 +#define FIFOFULL 0x02 +#define FIFOEMP 0x01 + +#define SG_CACHE_SHADOW 0x1b +#define ODD_SEG 0x04 +#define LAST_SEG 0x02 +#define LAST_SEG_DONE 0x01 + +#define ARBCTL 0x1b +#define RESET_HARB 0x80 +#define RETRY_SWEN 0x08 +#define USE_TIME 0x07 + +#define SG_CACHE_PRE 0x1b + +#define LQIN 0x20 + +#define TYPEPTR 0x20 + +#define TAGPTR 0x21 + +#define LUNPTR 0x22 + +#define DATALENPTR 0x23 + +#define STATLENPTR 0x24 + +#define CMDLENPTR 0x25 + +#define ATTRPTR 0x26 + +#define FLAGPTR 0x27 + +#define CMDPTR 0x28 + +#define QNEXTPTR 0x29 + +#define IDPTR 0x2a + +#define ABRTBYTEPTR 0x2b + +#define ABRTBITPTR 0x2c + +#define MAXCMDBYTES 0x2d + +#define MAXCMD2RCV 0x2e + +#define SHORTTHRESH 0x2f + +#define LUNLEN 0x30 + +#define CDBLIMIT 0x31 + +#define MAXCMD 0x32 + +#define MAXCMDCNT 0x33 + +#define LQRSVD01 0x34 + +#define LQRSVD16 0x35 + +#define LQRSVD17 0x36 + +#define CMDRSVD0 0x37 + +#define LQCTL0 0x38 +#define LQITARGCLT 0xc0 +#define LQIINITGCLT 0x30 +#define LQ0TARGCLT 0x0c +#define LQ0INITGCLT 0x03 + +#define LQCTL1 0x38 +#define PCI2PCI 0x04 +#define SINGLECMD 0x02 +#define ABORTPENDING 0x01 + +#define SCSBIST0 0x39 +#define GSBISTERR 0x40 +#define GSBISTDONE 0x20 +#define GSBISTRUN 0x10 +#define OSBISTERR 0x04 +#define OSBISTDONE 0x02 +#define OSBISTRUN 0x01 + +#define LQCTL2 0x39 +#define LQIRETRY 0x80 +#define LQICONTINUE 0x40 +#define LQITOIDLE 0x20 +#define LQIPAUSE 0x10 +#define LQORETRY 0x08 +#define LQOCONTINUE 0x04 +#define LQOTOIDLE 0x02 +#define LQOPAUSE 0x01 + +#define SCSBIST1 0x3a +#define NTBISTERR 0x04 +#define NTBISTDONE 0x02 +#define NTBISTRUN 0x01 + +#define SCSISEQ0 0x3a +#define TEMODEO 0x80 +#define ENSELO 0x40 +#define ENARBO 0x20 +#define FORCEBUSFREE 0x10 +#define SCSIRSTO 0x01 + +#define SCSISEQ1 0x3b + +#define SXFRCTL0 0x3c +#define DFON 0x80 +#define DFPEXP 0x40 +#define BIOSCANCELEN 0x10 +#define SPIOEN 0x08 + +#define BUSINITID 0x3c + +#define DLCOUNT 0x3c + +#define SXFRCTL1 0x3d +#define BITBUCKET 0x80 +#define ENSACHK 0x40 +#define ENSPCHK 0x20 +#define STIMESEL 0x18 +#define ENSTIMER 0x04 +#define ACTNEGEN 0x02 +#define STPWEN 0x01 + +#define BUSTARGID 0x3e + +#define SXFRCTL2 0x3e +#define AUTORSTDIS 0x10 +#define CMDDMAEN 0x08 +#define ASU 0x07 + +#define DFFSTAT 0x3f +#define CURRFIFO 0x03 +#define FIFO1FREE 0x20 +#define FIFO0FREE 0x10 +#define CURRFIFO_NONE 0x03 +#define CURRFIFO_1 0x01 +#define CURRFIFO_0 0x00 + +#define SCSISIGO 0x40 +#define CDO 0x80 +#define IOO 0x40 +#define MSGO 0x20 +#define ATNO 0x10 +#define SELO 0x08 +#define BSYO 0x04 +#define REQO 0x02 +#define ACKO 0x01 + +#define MULTARGID 0x40 + +#define SCSISIGI 0x41 +#define ATNI 0x10 +#define SELI 0x08 +#define BSYI 0x04 +#define REQI 0x02 +#define ACKI 0x01 + +#define SCSIPHASE 0x42 +#define STATUS_PHASE 0x20 +#define COMMAND_PHASE 0x10 +#define MSG_IN_PHASE 0x08 +#define MSG_OUT_PHASE 0x04 +#define DATA_PHASE_MASK 0x03 +#define DATA_IN_PHASE 0x02 +#define DATA_OUT_PHASE 0x01 + +#define SCSIDAT0_IMG 0x43 + +#define SCSIDAT 0x44 + +#define SCSIBUS 0x46 + +#define TARGIDIN 0x48 +#define CLKOUT 0x80 +#define TARGID 0x0f + +#define SELID 0x49 +#define SELID_MASK 0xf0 +#define ONEBIT 0x08 + +#define SBLKCTL 0x4a +#define DIAGLEDEN 0x80 +#define DIAGLEDON 0x40 +#define ENAB40 0x08 +#define ENAB20 0x04 +#define SELWIDE 0x02 + +#define OPTIONMODE 0x4a +#define OPTIONMODE_DEFAULTS 0x02 +#define BIOSCANCTL 0x80 +#define AUTOACKEN 0x40 +#define BIASCANCTL 0x20 +#define BUSFREEREV 0x10 +#define ENDGFORMCHK 0x04 +#define AUTO_MSGOUT_DE 0x02 + +#define SSTAT0 0x4b +#define TARGET 0x80 +#define SELDO 0x40 +#define SELDI 0x20 +#define SELINGO 0x10 +#define IOERR 0x08 +#define OVERRUN 0x04 +#define SPIORDY 0x02 +#define ARBDO 0x01 + +#define CLRSINT0 0x4b +#define CLRSELDO 0x40 +#define CLRSELDI 0x20 +#define CLRSELINGO 0x10 +#define CLRIOERR 0x08 +#define CLROVERRUN 0x04 +#define CLRSPIORDY 0x02 +#define CLRARBDO 0x01 + +#define SIMODE0 0x4b +#define ENSELDO 0x40 +#define ENSELDI 0x20 +#define ENSELINGO 0x10 +#define ENIOERR 0x08 +#define ENOVERRUN 0x04 +#define ENSPIORDY 0x02 +#define ENARBDO 0x01 + +#define CLRSINT1 0x4c +#define CLRSELTIMEO 0x80 +#define CLRATNO 0x40 +#define CLRSCSIRSTI 0x20 +#define CLRBUSFREE 0x08 +#define CLRSCSIPERR 0x04 +#define CLRSTRB2FAST 0x02 +#define CLRREQINIT 0x01 + +#define SSTAT1 0x4c +#define SELTO 0x80 +#define ATNTARG 0x40 +#define SCSIRSTI 0x20 +#define PHASEMIS 0x10 +#define BUSFREE 0x08 +#define SCSIPERR 0x04 +#define STRB2FAST 0x02 +#define REQINIT 0x01 + +#define SSTAT2 0x4d +#define BUSFREETIME 0xc0 +#define NONPACKREQ 0x20 +#define EXP_ACTIVE 0x10 +#define BSYX 0x08 +#define WIDE_RES 0x04 +#define SDONE 0x02 +#define DMADONE 0x01 +#define BUSFREE_DFF1 0xc0 +#define BUSFREE_DFF0 0x80 +#define BUSFREE_LQO 0x40 + +#define CLRSINT2 0x4d +#define CLRNONPACKREQ 0x20 +#define CLRWIDE_RES 0x04 +#define CLRSDONE 0x02 +#define CLRDMADONE 0x01 + +#define SIMODE2 0x4d +#define ENWIDE_RES 0x04 +#define ENSDONE 0x02 +#define ENDMADONE 0x01 + +#define PERRDIAG 0x4e +#define HIZERO 0x80 +#define HIPERR 0x40 +#define PREVPHASE 0x20 +#define PARITYERR 0x10 +#define AIPERR 0x08 +#define CRCERR 0x04 +#define DGFORMERR 0x02 +#define DTERR 0x01 + +#define LQISTATE 0x4e + +#define SOFFCNT 0x4f + +#define LQOSTATE 0x4f + +#define LQISTAT0 0x50 +#define LQIATNQAS 0x20 +#define LQICRCT1 0x10 +#define LQICRCT2 0x08 +#define LQIBADLQT 0x04 +#define LQIATNLQ 0x02 +#define LQIATNCMD 0x01 + +#define CLRLQIINT0 0x50 +#define CLRLQIATNQAS 0x20 +#define CLRLQICRCT1 0x10 +#define CLRLQICRCT2 0x08 +#define CLRLQIBADLQT 0x04 +#define CLRLQIATNLQ 0x02 +#define CLRLQIATNCMD 0x01 + +#define LQIMODE0 0x50 +#define ENLQIATNQASK 0x20 +#define ENLQICRCT1 0x10 +#define ENLQICRCT2 0x08 +#define ENLQIBADLQT 0x04 +#define ENLQIATNLQ 0x02 +#define ENLQIATNCMD 0x01 + +#define LQIMODE1 0x51 +#define ENLQIPHASE_LQ 0x80 +#define ENLQIPHASE_NLQ 0x40 +#define ENLIQABORT 0x20 +#define ENLQICRCI_LQ 0x10 +#define ENLQICRCI_NLQ 0x08 +#define ENLQIBADLQI 0x04 +#define ENLQIOVERI_LQ 0x02 +#define ENLQIOVERI_NLQ 0x01 + +#define LQISTAT1 0x51 +#define LQIPHASE_LQ 0x80 +#define LQIPHASE_NLQ 0x40 +#define LQIABORT 0x20 +#define LQICRCI_LQ 0x10 +#define LQICRCI_NLQ 0x08 +#define LQIBADLQI 0x04 +#define LQIOVERI_LQ 0x02 +#define LQIOVERI_NLQ 0x01 + +#define CLRLQIINT1 0x51 +#define CLRLQIPHASE_LQ 0x80 +#define CLRLQIPHASE_NLQ 0x40 +#define CLRLIQABORT 0x20 +#define CLRLQICRCI_LQ 0x10 +#define CLRLQICRCI_NLQ 0x08 +#define CLRLQIBADLQI 0x04 +#define CLRLQIOVERI_LQ 0x02 +#define CLRLQIOVERI_NLQ 0x01 + +#define LQISTAT2 0x52 +#define PACKETIZED 0x80 +#define LQIPHASE_OUTPKT 0x40 +#define LQIWORKONLQ 0x20 +#define LQIWAITFIFO 0x10 +#define LQISTOPPKT 0x08 +#define LQISTOPLQ 0x04 +#define LQISTOPCMD 0x02 +#define LQIGSAVAIL 0x01 + +#define SSTAT3 0x53 +#define NTRAMPERR 0x02 +#define OSRAMPERR 0x01 + +#define SIMODE3 0x53 +#define ENNTRAMPERR 0x02 +#define ENOSRAMPERR 0x01 + +#define CLRSINT3 0x53 +#define CLRNTRAMPERR 0x02 +#define CLROSRAMPERR 0x01 + +#define LQOMODE0 0x54 +#define ENLQOTARGSCBPERR 0x10 +#define ENLQOSTOPT2 0x08 +#define ENLQOATNLQ 0x04 +#define ENLQOATNPKT 0x02 +#define ENLQOTCRC 0x01 + +#define LQOSTAT0 0x54 +#define LQOTARGSCBPERR 0x10 +#define LQOSTOPT2 0x08 +#define LQOATNLQ 0x04 +#define LQOATNPKT 0x02 +#define LQOTCRC 0x01 + +#define CLRLQOINT0 0x54 +#define CLRLQOTARGSCBPERR 0x10 +#define CLRLQOSTOPT2 0x08 +#define CLRLQOATNLQ 0x04 +#define CLRLQOATNPKT 0x02 +#define CLRLQOTCRC 0x01 + +#define LQOSTAT1 0x55 +#define LQOINITSCBPERR 0x10 +#define LQOSTOPI2 0x08 +#define LQOBADQAS 0x04 +#define LQOBUSFREE 0x02 +#define LQOPHACHGINPKT 0x01 + +#define CLRLQOINT1 0x55 +#define CLRLQOINITSCBPERR 0x10 +#define CLRLQOSTOPI2 0x08 +#define CLRLQOBADQAS 0x04 +#define CLRLQOBUSFREE 0x02 +#define CLRLQOPHACHGINPKT 0x01 + +#define LQOMODE1 0x55 +#define ENLQOINITSCBPERR 0x10 +#define ENLQOSTOPI2 0x08 +#define ENLQOBADQAS 0x04 +#define ENLQOBUSFREE 0x02 +#define ENLQOPHACHGINPKT 0x01 + +#define LQOSTAT2 0x56 +#define LQOPKT 0xe0 +#define LQOWAITFIFO 0x10 +#define LQOPHACHGOUTPKT 0x02 +#define LQOSTOP0 0x01 + +#define OS_SPACE_CNT 0x56 + +#define SIMODE1 0x57 +#define ENSELTIMO 0x80 +#define ENATNTARG 0x40 +#define ENSCSIRST 0x20 +#define ENPHASEMIS 0x10 +#define ENBUSFREE 0x08 +#define ENSCSIPERR 0x04 +#define ENSTRB2FAST 0x02 +#define ENREQINIT 0x01 + +#define GSFIFO 0x58 + +#define DFFSXFRCTL 0x5a +#define DFFBITBUCKET 0x08 +#define CLRSHCNT 0x04 +#define CLRCHN 0x02 +#define RSTCHN 0x01 + +#define LQOSCSCTL 0x5a +#define LQOH2A_VERSION 0x80 +#define LQONOCHKOVER 0x01 + +#define NEXTSCB 0x5a + +#define CLRSEQINTSRC 0x5b +#define CLRCTXTDONE 0x40 +#define CLRSAVEPTRS 0x20 +#define CLRCFG4DATA 0x10 +#define CLRCFG4ISTAT 0x08 +#define CLRCFG4TSTAT 0x04 +#define CLRCFG4ICMD 0x02 +#define CLRCFG4TCMD 0x01 + +#define SEQINTSRC 0x5b +#define CTXTDONE 0x40 +#define SAVEPTRS 0x20 +#define CFG4DATA 0x10 +#define CFG4ISTAT 0x08 +#define CFG4TSTAT 0x04 +#define CFG4ICMD 0x02 +#define CFG4TCMD 0x01 + +#define CURRSCB 0x5c + +#define SEQIMODE 0x5c +#define ENCTXTDONE 0x40 +#define ENSAVEPTRS 0x20 +#define ENCFG4DATA 0x10 +#define ENCFG4ISTAT 0x08 +#define ENCFG4TSTAT 0x04 +#define ENCFG4ICMD 0x02 +#define ENCFG4TCMD 0x01 + +#define MDFFSTAT 0x5d +#define SHCNTNEGATIVE 0x40 +#define SHCNTMINUS1 0x20 +#define LASTSDONE 0x10 +#define SHVALID 0x08 +#define DLZERO 0x04 +#define DATAINFIFO 0x02 +#define FIFOFREE 0x01 + +#define CRCCONTROL 0x5d +#define CRCVALCHKEN 0x40 + +#define DFFTAG 0x5e + +#define LASTSCB 0x5e + +#define SCSITEST 0x5e +#define CNTRTEST 0x08 +#define SEL_TXPLL_DEBUG 0x04 + +#define IOPDNCTL 0x5f +#define DISABLE_OE 0x80 +#define PDN_IDIST 0x04 +#define PDN_DIFFSENSE 0x01 + +#define SHADDR 0x60 + +#define NEGOADDR 0x60 + +#define DGRPCRCI 0x60 + +#define NEGPERIOD 0x61 + +#define PACKCRCI 0x62 + +#define NEGOFFSET 0x62 + +#define NEGPPROPTS 0x63 +#define PPROPT_PACE 0x08 +#define PPROPT_QAS 0x04 +#define PPROPT_DT 0x02 +#define PPROPT_IUT 0x01 + +#define NEGCONOPTS 0x64 +#define ENSNAPSHOT 0x40 +#define RTI_WRTDIS 0x20 +#define RTI_OVRDTRN 0x10 +#define ENSLOWCRC 0x08 +#define ENAUTOATNI 0x04 +#define ENAUTOATNO 0x02 +#define WIDEXFER 0x01 + +#define ANNEXCOL 0x65 + +#define SCSCHKN 0x66 +#define STSELSKIDDIS 0x40 +#define CURRFIFODEF 0x20 +#define WIDERESEN 0x10 +#define SDONEMSKDIS 0x08 +#define DFFACTCLR 0x04 +#define SHVALIDSTDIS 0x02 +#define LSTSGCLRDIS 0x01 + +#define ANNEXDAT 0x66 + +#define IOWNID 0x67 + +#define PLL960CTL0 0x68 + +#define SHCNT 0x68 + +#define TOWNID 0x69 + +#define PLL960CTL1 0x69 + +#define PLL960CNT0 0x6a + +#define XSIG 0x6a + +#define SELOID 0x6b + +#define PLL400CTL0 0x6c +#define PLL_VCOSEL 0x80 +#define PLL_PWDN 0x40 +#define PLL_NS 0x30 +#define PLL_ENLUD 0x08 +#define PLL_ENLPF 0x04 +#define PLL_DLPF 0x02 +#define PLL_ENFBM 0x01 + +#define FAIRNESS 0x6c + +#define PLL400CTL1 0x6d +#define PLL_CNTEN 0x80 +#define PLL_CNTCLR 0x40 +#define PLL_RST 0x01 + +#define PLL400CNT0 0x6e + +#define UNFAIRNESS 0x6e + +#define HADDR 0x70 + +#define PLLDELAY 0x70 +#define SPLIT_DROP_REQ 0x80 + +#define HODMAADR 0x70 + +#define HODMACNT 0x78 + +#define HCNT 0x78 + +#define HODMAEN 0x7a + +#define SGHADDR 0x7c + +#define SCBHADDR 0x7c + +#define SGHCNT 0x84 + +#define SCBHCNT 0x84 + +#define DFF_THRSH 0x88 +#define WR_DFTHRSH 0x70 +#define RD_DFTHRSH 0x07 +#define WR_DFTHRSH_MAX 0x70 +#define WR_DFTHRSH_90 0x60 +#define WR_DFTHRSH_85 0x50 +#define WR_DFTHRSH_75 0x40 +#define WR_DFTHRSH_63 0x30 +#define WR_DFTHRSH_50 0x20 +#define WR_DFTHRSH_25 0x10 +#define RD_DFTHRSH_MAX 0x07 +#define RD_DFTHRSH_90 0x06 +#define RD_DFTHRSH_85 0x05 +#define RD_DFTHRSH_75 0x04 +#define RD_DFTHRSH_63 0x03 +#define RD_DFTHRSH_50 0x02 +#define RD_DFTHRSH_25 0x01 +#define WR_DFTHRSH_MIN 0x00 +#define RD_DFTHRSH_MIN 0x00 + +#define ROMADDR 0x8a + +#define ROMCNTRL 0x8d +#define ROMOP 0xe0 +#define ROMSPD 0x18 +#define REPEAT 0x02 +#define RDY 0x01 + +#define ROMDATA 0x8e + +#define CMCRXMSG0 0x90 + +#define ROENABLE 0x90 +#define MSIROEN 0x20 +#define OVLYROEN 0x10 +#define CMCROEN 0x08 +#define SGROEN 0x04 +#define DCH1ROEN 0x02 +#define DCH0ROEN 0x01 + +#define OVLYRXMSG0 0x90 + +#define DCHRXMSG0 0x90 + +#define OVLYRXMSG1 0x91 + +#define NSENABLE 0x91 +#define MSINSEN 0x20 +#define OVLYNSEN 0x10 +#define CMCNSEN 0x08 +#define SGNSEN 0x04 +#define DCH1NSEN 0x02 +#define DCH0NSEN 0x01 + +#define DCHRXMSG1 0x91 + +#define CMCRXMSG1 0x91 + +#define DCHRXMSG2 0x92 + +#define OVLYRXMSG2 0x92 + +#define CMCRXMSG2 0x92 + +#define OST 0x92 + +#define DCHRXMSG3 0x93 + +#define CMCRXMSG3 0x93 + +#define PCIXCTL 0x93 +#define SERRPULSE 0x80 +#define UNEXPSCIEN 0x20 +#define SPLTSMADIS 0x10 +#define SPLTSTADIS 0x08 +#define SRSPDPEEN 0x04 +#define TSCSERREN 0x02 +#define CMPABCDIS 0x01 + +#define OVLYRXMSG3 0x93 + +#define OVLYSEQBCNT 0x94 + +#define CMCSEQBCNT 0x94 + +#define DCHSEQBCNT 0x94 + +#define CMCSPLTSTAT0 0x96 + +#define OVLYSPLTSTAT0 0x96 + +#define DCHSPLTSTAT0 0x96 + +#define DCHSPLTSTAT1 0x97 + +#define CMCSPLTSTAT1 0x97 + +#define OVLYSPLTSTAT1 0x97 + +#define SGRXMSG0 0x98 +#define CDNUM 0xf8 +#define CFNUM 0x07 + +#define SLVSPLTOUTADR0 0x98 +#define LOWER_ADDR 0x7f + +#define SGRXMSG1 0x99 +#define CBNUM 0xff + +#define SLVSPLTOUTADR1 0x99 +#define REQ_DNUM 0xf8 +#define REQ_FNUM 0x07 + +#define SGRXMSG2 0x9a +#define MINDEX 0xff + +#define SLVSPLTOUTADR2 0x9a +#define REQ_BNUM 0xff + +#define SGRXMSG3 0x9b +#define MCLASS 0x0f + +#define SLVSPLTOUTADR3 0x9b +#define TAG_NUM 0x1f +#define RLXORD 0x10 + +#define SGSEQBCNT 0x9c + +#define SLVSPLTOUTATTR0 0x9c +#define LOWER_BCNT 0xff + +#define SLVSPLTOUTATTR1 0x9d +#define CMPLT_DNUM 0xf8 +#define CMPLT_FNUM 0x07 + +#define SLVSPLTOUTATTR2 0x9e +#define CMPLT_BNUM 0xff + +#define SGSPLTSTAT0 0x9e +#define STAETERM 0x80 +#define SCBCERR 0x40 +#define SCADERR 0x20 +#define SCDATBUCKET 0x10 +#define CNTNOTCMPLT 0x08 +#define RXOVRUN 0x04 +#define RXSCEMSG 0x02 +#define RXSPLTRSP 0x01 + +#define SFUNCT 0x9f +#define TEST_GROUP 0xf0 +#define TEST_NUM 0x0f + +#define SGSPLTSTAT1 0x9f +#define RXDATABUCKET 0x01 + +#define DF0PCISTAT 0xa0 + +#define REG0 0xa0 + +#define DF1PCISTAT 0xa1 + +#define SGPCISTAT 0xa2 + +#define REG1 0xa2 + +#define CMCPCISTAT 0xa3 + +#define OVLYPCISTAT 0xa4 +#define SCAAPERR 0x08 +#define RDPERR 0x04 + +#define REG_ISR 0xa4 + +#define SG_STATE 0xa6 +#define FETCH_INPROG 0x04 +#define LOADING_NEEDED 0x02 +#define SEGS_AVAIL 0x01 + +#define MSIPCISTAT 0xa6 +#define RMA 0x20 +#define RTA 0x10 +#define CLRPENDMSI 0x08 +#define DPR 0x01 + +#define TARGPCISTAT 0xa7 +#define DPE 0x80 +#define SSE 0x40 +#define STA 0x08 +#define TWATERR 0x02 + +#define DATA_COUNT_ODD 0xa7 + +#define SCBPTR 0xa8 + +#define CCSCBACNT 0xab + +#define SCBAUTOPTR 0xab +#define AUSCBPTR_EN 0x80 +#define SCBPTR_ADDR 0x38 +#define SCBPTR_OFF 0x07 + +#define CCSGADDR 0xac + +#define CCSCBADDR 0xac + +#define CCSCBADR_BK 0xac + +#define CMC_RAMBIST 0xad +#define SG_ELEMENT_SIZE 0x80 +#define SCBRAMBIST_FAIL 0x40 +#define SG_BIST_FAIL 0x20 +#define SG_BIST_EN 0x10 +#define CMC_BUFFER_BIST_FAIL 0x02 +#define CMC_BUFFER_BIST_EN 0x01 + +#define CCSGCTL 0xad +#define CCSGEN 0x0c +#define CCSGDONE 0x80 +#define SG_CACHE_AVAIL 0x10 +#define CCSGENACK 0x08 +#define SG_FETCH_REQ 0x02 +#define CCSGRESET 0x01 + +#define CCSCBCTL 0xad +#define CCSCBDONE 0x80 +#define ARRDONE 0x40 +#define CCARREN 0x10 +#define CCSCBEN 0x08 +#define CCSCBDIR 0x04 +#define CCSCBRESET 0x01 + +#define CCSGRAM 0xb0 + +#define FLEXADR 0xb0 + +#define CCSCBRAM 0xb0 + +#define FLEXCNT 0xb3 + +#define FLEXDMASTAT 0xb5 +#define FLEXDMAERR 0x02 +#define FLEXDMADONE 0x01 + +#define FLEXDATA 0xb6 + +#define BRDDAT 0xb8 + +#define BRDCTL 0xb9 +#define FLXARBACK 0x80 +#define FLXARBREQ 0x40 +#define BRDADDR 0x38 +#define BRDEN 0x04 +#define BRDRW 0x02 +#define BRDSTB 0x01 + +#define SEEADR 0xba + +#define SEEDAT 0xbc + +#define SEECTL 0xbe +#define SEEOP_EWEN 0x40 +#define SEEOP_WALL 0x40 +#define SEEOP_EWDS 0x40 +#define SEEOPCODE 0x70 +#define SEERST 0x02 +#define SEESTART 0x01 +#define SEEOP_ERASE 0x70 +#define SEEOP_READ 0x60 +#define SEEOP_WRITE 0x50 +#define SEEOP_ERAL 0x40 + +#define SEESTAT 0xbe +#define INIT_DONE 0x80 +#define LDALTID_L 0x08 +#define SEEARBACK 0x04 +#define SEEBUSY 0x02 + +#define SCBCNT 0xbf + +#define DFWADDR 0xc0 + +#define DSPFLTRCTL 0xc0 +#define FLTRDISABLE 0x20 +#define EDGESENSE 0x10 +#define DSPFCNTSEL 0x0f + +#define DSPDATACTL 0xc1 +#define BYPASSENAB 0x80 +#define DESQDIS 0x10 +#define RCVROFFSTDIS 0x04 +#define XMITOFFSTDIS 0x02 + +#define DFRADDR 0xc2 + +#define DSPREQCTL 0xc2 +#define MANREQCTL 0xc0 +#define MANREQDLY 0x3f + +#define DSPACKCTL 0xc3 +#define MANACKCTL 0xc0 +#define MANACKDLY 0x3f + +#define DFDAT 0xc4 + +#define DSPSELECT 0xc4 +#define AUTOINCEN 0x80 +#define DSPSEL 0x1f + +#define WRTBIASCTL 0xc5 +#define AUTOXBCDIS 0x80 +#define XMITMANVAL 0x3f + +#define RCVRBIOSCTL 0xc6 +#define AUTORBCDIS 0x80 +#define RCVRMANVAL 0x3f + +#define WRTBIASCALC 0xc7 + +#define DFPTRS 0xc8 + +#define RCVRBIASCALC 0xc8 + +#define DFBKPTR 0xc9 + +#define SKEWCALC 0xc9 + +#define DFDBCTL 0xcb +#define DFF_CIO_WR_RDY 0x20 +#define DFF_CIO_RD_RDY 0x10 +#define DFF_DIR_ERR 0x08 +#define DFF_RAMBIST_FAIL 0x04 +#define DFF_RAMBIST_DONE 0x02 +#define DFF_RAMBIST_EN 0x01 + +#define DFSCNT 0xcc + +#define DFBCNT 0xce + +#define OVLYADDR 0xd4 + +#define SEQCTL0 0xd6 +#define PERRORDIS 0x80 +#define PAUSEDIS 0x40 +#define FAILDIS 0x20 +#define FASTMODE 0x10 +#define BRKADRINTEN 0x08 +#define STEP 0x04 +#define SEQRESET 0x02 +#define LOADRAM 0x01 + +#define SEQCTL1 0xd7 +#define OVRLAY_DATA_CHK 0x08 +#define RAMBIST_DONE 0x04 +#define RAMBIST_FAIL 0x02 +#define RAMBIST_EN 0x01 + +#define FLAGS 0xd8 +#define ZERO 0x02 +#define CARRY 0x01 + +#define SEQINTCTL 0xd9 +#define INTVEC1DSL 0x80 +#define INT1_CONTEXT 0x20 +#define SCS_SEQ_INT1M1 0x10 +#define SCS_SEQ_INT1M0 0x08 +#define INTMASK2 0x04 +#define INTMASK1 0x02 +#define IRET 0x01 + +#define SEQRAM 0xda + +#define PRGMCNT 0xde + +#define ACCUM 0xe0 + +#define SINDEX 0xe2 + +#define DINDEX 0xe4 + +#define BRKADDR1 0xe6 +#define BRKDIS 0x80 + +#define BRKADDR0 0xe6 + +#define ALLONES 0xe8 + +#define ALLZEROS 0xea + +#define NONE 0xea + +#define SINDIR 0xec + +#define DINDIR 0xed + +#define FUNCTION1 0xf0 + +#define STACK 0xf2 + +#define CURADDR 0xf4 + +#define INTVEC1_ADDR 0xf4 + +#define INTVEC2_ADDR 0xf6 + +#define LASTADDR 0xf6 + +#define LONGJMP_ADDR 0xf8 + +#define LONGJMP_SCB 0xfa + +#define ACCUM_SAVE 0xfc + +#define WAITING_SCB_TAILS 0x100 + +#define AHD_PCI_CONFIG_BASE 0x100 + +#define SRAM_BASE 0x100 + +#define WAITING_TID_HEAD 0x120 + +#define WAITING_TID_TAIL 0x122 + +#define NEXT_QUEUED_SCB_ADDR 0x124 + +#define COMPLETE_SCB_HEAD 0x128 + +#define COMPLETE_SCB_DMAINPROG_HEAD 0x12a + +#define COMPLETE_DMA_SCB_HEAD 0x12c + +#define QFREEZE_COUNT 0x12e + +#define SAVED_MODE 0x130 + +#define MSG_OUT 0x131 + +#define DMAPARAMS 0x132 +#define PRELOADEN 0x80 +#define WIDEODD 0x40 +#define SCSIEN 0x20 +#define SDMAEN 0x10 +#define SDMAENACK 0x10 +#define HDMAENACK 0x08 +#define HDMAEN 0x08 +#define DIRECTION 0x04 +#define FIFOFLUSH 0x02 +#define FIFORESET 0x01 + +#define SEQ_FLAGS 0x133 +#define NOT_IDENTIFIED 0x80 +#define NO_CDB_SENT 0x40 +#define TARGET_CMD_IS_TAGGED 0x40 +#define DPHASE 0x20 +#define TARG_CMD_PENDING 0x10 +#define CMDPHASE_PENDING 0x08 +#define DPHASE_PENDING 0x04 +#define SPHASE_PENDING 0x02 +#define NO_DISCONNECT 0x01 + +#define SAVED_SCSIID 0x134 + +#define SAVED_LUN 0x135 + +#define LASTPHASE 0x136 +#define PHASE_MASK 0xe0 +#define CDI 0x80 +#define IOI 0x40 +#define MSGI 0x20 +#define P_BUSFREE 0x01 +#define P_MESGIN 0xe0 +#define P_STATUS 0xc0 +#define P_MESGOUT 0xa0 +#define P_COMMAND 0x80 +#define P_DATAIN_DT 0x60 +#define P_DATAIN 0x40 +#define P_DATAOUT_DT 0x20 +#define P_DATAOUT 0x00 + +#define QOUTFIFO_ENTRY_VALID_TAG 0x137 + +#define SHARED_DATA_ADDR 0x138 + +#define QOUTFIFO_NEXT_ADDR 0x13c + +#define KERNEL_TQINPOS 0x140 + +#define TQINPOS 0x141 + +#define ARG_1 0x142 +#define RETURN_1 0x142 +#define SEND_MSG 0x80 +#define SEND_SENSE 0x40 +#define SEND_REJ 0x20 +#define MSGOUT_PHASEMIS 0x10 +#define EXIT_MSG_LOOP 0x08 +#define CONT_MSG_LOOP_WRITE 0x04 +#define CONT_MSG_LOOP_READ 0x03 +#define CONT_MSG_LOOP_TARG 0x02 + +#define ARG_2 0x143 +#define RETURN_2 0x143 + +#define LAST_MSG 0x144 + +#define SCSISEQ_TEMPLATE 0x145 +#define MANUALCTL 0x40 +#define ENSELI 0x20 +#define ENRSELI 0x10 +#define MANUALP 0x0c +#define ENAUTOATNP 0x02 +#define ALTSTIM 0x01 + +#define INITIATOR_TAG 0x146 + +#define SEQ_FLAGS2 0x147 +#define SELECTOUT_QFROZEN 0x04 +#define TARGET_MSG_PENDING 0x02 + +#define ALLOCFIFO_SCBPTR 0x148 + +#define INT_COALESSING_TIMER 0x14a + +#define INT_COALESSING_MAXCMDS 0x14c + +#define INT_COALESSING_MINCMDS 0x14d + +#define CMDS_PENDING 0x14e + +#define INT_COALESSING_CMDCOUNT 0x150 + +#define LOCAL_HS_MAILBOX 0x151 + +#define CMDSIZE_TABLE 0x152 + +#define SCB_BASE 0x180 + +#define SCB_RESIDUAL_DATACNT 0x180 +#define SCB_CDB_STORE 0x180 + +#define SCB_RESIDUAL_SGPTR 0x184 +#define SCB_CDB_PTR 0x184 +#define SG_ADDR_MASK 0xf8 +#define SG_OVERRUN_RESID 0x02 + +#define SCB_SCSI_STATUS 0x188 + +#define SCB_TARGET_PHASES 0x189 + +#define SCB_TARGET_DATA_DIR 0x18a + +#define SCB_TARGET_ITAG 0x18b + +#define SCB_SENSE_BUSADDR 0x18c +#define SCB_NEXT_COMPLETE 0x18c + +#define SCB_TAG 0x190 + +#define SCB_CDB_LEN 0x192 +#define SCB_CDB_LEN_PTR 0x80 + +#define SCB_TASK_MANAGEMENT 0x193 + +#define SCB_NEXT 0x194 +#define SCB_NEXT_SCB_BUSADDR 0x194 + +#define SCB_NEXT2 0x196 + +#define SCB_DATAPTR 0x198 + +#define SCB_DATACNT 0x1a0 +#define SG_LAST_SEG 0x80 +#define SG_HIGH_ADDR_BITS 0x7f + +#define SCB_SGPTR 0x1a4 +#define SG_STATUS_VALID 0x04 +#define SG_FULL_RESID 0x02 +#define SG_LIST_NULL 0x01 + +#define SCB_CONTROL 0x1a8 +#define TARGET_SCB 0x80 +#define DISCENB 0x40 +#define TAG_ENB 0x20 +#define MK_MESSAGE 0x10 +#define STATUS_RCVD 0x08 +#define DISCONNECTED 0x04 +#define SCB_TAG_TYPE 0x03 + +#define SCB_SCSIID 0x1a9 +#define TID 0xf0 +#define OID 0x0f + +#define SCB_LUN 0x1aa +#define LID 0xff + +#define SCB_TASK_ATTRIBUTE 0x1ab + +#define SCB_BUSADDR 0x1ac + +#define SCB_SPARE 0x1b0 +#define SCB_PKT_LUN 0x1b0 + +#define SCB_DISCONNECTED_LISTS 0x1b8 + + +#define AHD_TIMER_US_PER_TICK 0x19 +#define SCB_TRANSFER_SIZE_FULL_LUN 0x38 +#define STATUS_QUEUE_FULL 0x28 +#define STATUS_BUSY 0x08 +#define MAX_OFFSET_NON_PACED 0x7f +#define MAX_OFFSET_PACED 0xfe +#define BUS_32_BIT 0x02 +#define CCSGADDR_MAX 0x80 +#define TID_SHIFT 0x04 +#define MK_MESSAGE_BIT_OFFSET 0x04 +#define WRTBIASCTL_HP_DEFAULT 0x00 +#define SEEOP_EWDS_ADDR 0x00 +#define AHD_AMPLITUDE_SHIFT 0x00 +#define AHD_AMPLITUDE_MASK 0x07 +#define AHD_ANNEXCOL_AMPLITUDE 0x06 +#define AHD_SLEWRATE_DEF_REVA 0x01 +#define AHD_SLEWRATE_SHIFT 0x03 +#define AHD_SLEWRATE_MASK 0x78 +#define AHD_PRECOMP_CUTBACK_29 0x06 +#define AHD_NUM_PER_DEV_ANNEXCOLS 0x04 +#define B_CURRFIFO_0 0x02 +#define NVRAM_SCB_OFFSET 0x2c +#define AHD_TIMER_MAX_US 0x18ffe7 +#define AHD_TIMER_MAX_TICKS 0xffff +#define STATUS_PKT_SENSE 0xff +#define CMD_GROUP_CODE_SHIFT 0x05 +#define AHD_SENSE_BUFSIZE 0x100 +#define MAX_OFFSET_PACED_BUG 0x7f +#define BUS_8_BIT 0x00 +#define STIMESEL_BUG_ADJ 0x08 +#define STIMESEL_MIN 0x18 +#define STIMESEL_SHIFT 0x03 +#define CCSGRAM_MAXSEGS 0x10 +#define INVALID_ADDR 0x80 +#define TARGET_CMD_CMPLT 0xfe +#define SEEOP_WRAL_ADDR 0x40 +#define SEEOP_ERAL_ADDR 0x80 +#define AHD_AMPLITUDE_DEF 0x07 +#define AHD_SLEWRATE_DEF_REVB 0x08 +#define AHD_PRECOMP_CUTBACK_37 0x07 +#define AHD_PRECOMP_CUTBACK_17 0x04 +#define AHD_PRECOMP_SHIFT 0x00 +#define AHD_PRECOMP_MASK 0x07 +#define AHD_ANNEXCOL_PRECOMP_SLEW 0x04 +#define SRC_MODE_SHIFT 0x00 +#define PKT_OVERRUN_BUFSIZE 0x200 +#define SCB_TRANSFER_SIZE_1BYTE_LUN 0x30 +#define TARGET_DATA_IN 0x01 +#define HOST_MSG 0xff +#define MAX_OFFSET 0xfe +#define BUS_16_BIT 0x01 +#define CCSCBADDR_MAX 0x80 +#define NUMDSPS 0x14 +#define SEEOP_EWEN_ADDR 0xc0 +#define AHD_ANNEXCOL_PER_DEV0 0x04 +#define DST_MODE_SHIFT 0x04 + + +/* Downloaded Constant Definitions */ +#define SCB_TRANSFER_SIZE 0x06 +#define PKT_OVERRUN_BUFOFFSET 0x05 +#define SG_SIZEOF 0x04 +#define SG_PREFETCH_ADDR_MASK 0x03 +#define SG_PREFETCH_ALIGN_MASK 0x02 +#define SG_PREFETCH_CNT_LIMIT 0x01 +#define SG_PREFETCH_CNT 0x00 +#define DOWNLOAD_CONST_COUNT 0x07 + + +/* Exported Labels */ +#define LABEL_seq_isr 0x263 +#define LABEL_timer_isr 0x25f diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_reg_print.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_reg_print.c --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_reg_print.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_reg_print.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,3632 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ + */ + +#include "aic79xx_osm.h" + +static ahd_reg_parse_entry_t MODE_PTR_parse_table[] = { + { "SRC_MODE", 0x07, 0x07 }, + { "DST_MODE", 0x70, 0x70 } +}; + +int +ahd_mode_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(MODE_PTR_parse_table, 2, "MODE_PTR", + 0x00, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t INTSTAT_parse_table[] = { + { "SPLTINT", 0x01, 0x01 }, + { "CMDCMPLT", 0x02, 0x02 }, + { "SEQINT", 0x04, 0x04 }, + { "SCSIINT", 0x08, 0x08 }, + { "PCIINT", 0x10, 0x10 }, + { "SWTMINT", 0x20, 0x20 }, + { "BRKADRINT", 0x40, 0x40 }, + { "HWERRINT", 0x80, 0x80 }, + { "INT_PEND", 0xff, 0xff } +}; + +int +ahd_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(INTSTAT_parse_table, 9, "INTSTAT", + 0x01, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = { + { "NO_SEQINT", 0x00, 0xff }, + { "BAD_PHASE", 0x01, 0xff }, + { "SEND_REJECT", 0x02, 0xff }, + { "PROTO_VIOLATION", 0x03, 0xff }, + { "NO_MATCH", 0x04, 0xff }, + { "IGN_WIDE_RES", 0x05, 0xff }, + { "PDATA_REINIT", 0x06, 0xff }, + { "HOST_MSG_LOOP", 0x07, 0xff }, + { "BAD_STATUS", 0x08, 0xff }, + { "DATA_OVERRUN", 0x09, 0xff }, + { "MKMSG_FAILED", 0x0a, 0xff }, + { "MISSED_BUSFREE", 0x0b, 0xff }, + { "DUMP_CARD_STATE", 0x0c, 0xff }, + { "ILLEGAL_PHASE", 0x0d, 0xff }, + { "INVALID_SEQINT", 0x0e, 0xff }, + { "CFG4ISTAT_INTR", 0x0f, 0xff }, + { "STATUS_OVERRUN", 0x10, 0xff }, + { "CFG4OVERRUN", 0x11, 0xff }, + { "ENTERING_NONPACK", 0x12, 0xff }, + { "TASKMGMT_FUNC_COMPLETE",0x13, 0xff }, + { "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff }, + { "TRACEPOINT0", 0x15, 0xff }, + { "TRACEPOINT1", 0x16, 0xff }, + { "TRACEPOINT2", 0x17, 0xff }, + { "TRACEPOINT3", 0x18, 0xff }, + { "SAW_HWERR", 0x19, 0xff } +}; + +int +ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTCODE_parse_table, 26, "SEQINTCODE", + 0x02, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRINT_parse_table[] = { + { "CLRSPLTINT", 0x01, 0x01 }, + { "CLRCMDINT", 0x02, 0x02 }, + { "CLRSEQINT", 0x04, 0x04 }, + { "CLRSCSIINT", 0x08, 0x08 }, + { "CLRPCIINT", 0x10, 0x10 }, + { "CLRSWTMINT", 0x20, 0x20 }, + { "CLRBRKADRINT", 0x40, 0x40 }, + { "CLRHWERRINT", 0x80, 0x80 } +}; + +int +ahd_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRINT_parse_table, 8, "CLRINT", + 0x03, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ERROR_parse_table[] = { + { "DSCTMOUT", 0x02, 0x02 }, + { "ILLOPCODE", 0x04, 0x04 }, + { "SQPARERR", 0x08, 0x08 }, + { "DPARERR", 0x10, 0x10 }, + { "MPARERR", 0x20, 0x20 }, + { "CIOACCESFAIL", 0x40, 0x40 }, + { "CIOPARERR", 0x80, 0x80 } +}; + +int +ahd_error_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ERROR_parse_table, 7, "ERROR", + 0x04, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRERR_parse_table[] = { + { "CLRDSCTMOUT", 0x02, 0x02 }, + { "CLRILLOPCODE", 0x04, 0x04 }, + { "CLRSQPARERR", 0x08, 0x08 }, + { "CLRDPARERR", 0x10, 0x10 }, + { "CLRMPARERR", 0x20, 0x20 }, + { "CLRCIOACCESFAIL", 0x40, 0x40 }, + { "CLRCIOPARERR", 0x80, 0x80 } +}; + +int +ahd_clrerr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRERR_parse_table, 7, "CLRERR", + 0x04, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t HCNTRL_parse_table[] = { + { "CHIPRST", 0x01, 0x01 }, + { "CHIPRSTACK", 0x01, 0x01 }, + { "INTEN", 0x02, 0x02 }, + { "PAUSE", 0x04, 0x04 }, + { "SWTIMER_START_B", 0x08, 0x08 }, + { "SWINT", 0x10, 0x10 }, + { "POWRDN", 0x40, 0x40 }, + { "SEQ_RESET", 0x80, 0x80 } +}; + +int +ahd_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(HCNTRL_parse_table, 8, "HCNTRL", + 0x05, regvalue, cur_col, wrap)); +} + +int +ahd_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HNSCB_QOFF", + 0x06, regvalue, cur_col, wrap)); +} + +int +ahd_hescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HESCB_QOFF", + 0x08, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = { + { "ENINT_COALESS", 0x40, 0x40 }, + { "HOST_TQINPOS", 0x80, 0x80 } +}; + +int +ahd_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(HS_MAILBOX_parse_table, 2, "HS_MAILBOX", + 0x0b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = { + { "CLRSEQ_SPLTINT", 0x01, 0x01 }, + { "CLRSEQ_PCIINT", 0x02, 0x02 }, + { "CLRSEQ_SCSIINT", 0x04, 0x04 }, + { "CLRSEQ_SEQINT", 0x08, 0x08 }, + { "CLRSEQ_SWTMRTO", 0x10, 0x10 } +}; + +int +ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT", + 0x0c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTSTAT_parse_table[] = { + { "SEQ_SPLTINT", 0x01, 0x01 }, + { "SEQ_PCIINT", 0x02, 0x02 }, + { "SEQ_SCSIINT", 0x04, 0x04 }, + { "SEQ_SEQINT", 0x08, 0x08 }, + { "SEQ_SWTMRTO", 0x10, 0x10 } +}; + +int +ahd_seqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTSTAT_parse_table, 5, "SEQINTSTAT", + 0x0c, regvalue, cur_col, wrap)); +} + +int +ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SWTIMER", + 0x0e, regvalue, cur_col, wrap)); +} + +int +ahd_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SNSCB_QOFF", + 0x10, regvalue, cur_col, wrap)); +} + +int +ahd_sescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SESCB_QOFF", + 0x12, regvalue, cur_col, wrap)); +} + +int +ahd_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SDSCB_QOFF", + 0x14, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = { + { "SCB_QSIZE_4", 0x00, 0x0f }, + { "SCB_QSIZE_8", 0x01, 0x0f }, + { "SCB_QSIZE_16", 0x02, 0x0f }, + { "SCB_QSIZE_32", 0x03, 0x0f }, + { "SCB_QSIZE_64", 0x04, 0x0f }, + { "SCB_QSIZE_128", 0x05, 0x0f }, + { "SCB_QSIZE_256", 0x06, 0x0f }, + { "SCB_QSIZE_512", 0x07, 0x0f }, + { "SCB_QSIZE_1024", 0x08, 0x0f }, + { "SCB_QSIZE_2048", 0x09, 0x0f }, + { "SCB_QSIZE_4096", 0x0a, 0x0f }, + { "SCB_QSIZE_8192", 0x0b, 0x0f }, + { "SCB_QSIZE_16384", 0x0c, 0x0f }, + { "SCB_QSIZE", 0x0f, 0x0f }, + { "HS_MAILBOX_ACT", 0x10, 0x10 }, + { "SDSCB_ROLLOVR", 0x20, 0x20 }, + { "NEW_SCB_AVAIL", 0x40, 0x40 }, + { "EMPTY_SCB_AVAIL", 0x80, 0x80 } +}; + +int +ahd_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(QOFF_CTLSTA_parse_table, 18, "QOFF_CTLSTA", + 0x16, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t INTCTL_parse_table[] = { + { "SPLTINTEN", 0x01, 0x01 }, + { "SEQINTEN", 0x02, 0x02 }, + { "SCSIINTEN", 0x04, 0x04 }, + { "PCIINTEN", 0x08, 0x08 }, + { "AUTOCLRCMDINT", 0x10, 0x10 }, + { "SWTIMER_START", 0x20, 0x20 }, + { "SWTMINTEN", 0x40, 0x40 }, + { "SWTMINTMASK", 0x80, 0x80 } +}; + +int +ahd_intctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(INTCTL_parse_table, 8, "INTCTL", + 0x18, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFCNTRL_parse_table[] = { + { "DIRECTIONEN", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "FIFOFLUSHACK", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "DIRECTIONACK", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SCSIEN", 0x20, 0x20 }, + { "SCSIENACK", 0x20, 0x20 }, + { "SCSIENWRDIS", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahd_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFCNTRL_parse_table, 11, "DFCNTRL", + 0x19, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSCOMMAND0_parse_table[] = { + { "CIOPARCKEN", 0x01, 0x01 }, + { "DISABLE_TWATE", 0x02, 0x02 }, + { "EXTREQLCK", 0x10, 0x10 }, + { "MPARCKEN", 0x20, 0x20 }, + { "DPARCKEN", 0x40, 0x40 }, + { "CACHETHEN", 0x80, 0x80 } +}; + +int +ahd_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSCOMMAND0_parse_table, 6, "DSCOMMAND0", + 0x19, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFSTATUS_parse_table[] = { + { "FIFOEMP", 0x01, 0x01 }, + { "FIFOFULL", 0x02, 0x02 }, + { "DFTHRESH", 0x04, 0x04 }, + { "HDONE", 0x08, 0x08 }, + { "MREQPEND", 0x10, 0x10 }, + { "PKT_PRELOAD_AVAIL", 0x40, 0x40 }, + { "PRELOAD_AVAIL", 0x80, 0x80 } +}; + +int +ahd_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFSTATUS_parse_table, 7, "DFSTATUS", + 0x1a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = { + { "LAST_SEG_DONE", 0x01, 0x01 }, + { "LAST_SEG", 0x02, 0x02 }, + { "ODD_SEG", 0x04, 0x04 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahd_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ARBCTL_parse_table[] = { + { "USE_TIME", 0x07, 0x07 }, + { "RETRY_SWEN", 0x08, 0x08 }, + { "RESET_HARB", 0x80, 0x80 } +}; + +int +ahd_arbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ARBCTL_parse_table, 3, "ARBCTL", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = { + { "LAST_SEG", 0x02, 0x02 }, + { "ODD_SEG", 0x04, 0x04 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahd_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE", + 0x1b, regvalue, cur_col, wrap)); +} + +int +ahd_lqin_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQIN", + 0x20, regvalue, cur_col, wrap)); +} + +int +ahd_typeptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TYPEPTR", + 0x20, regvalue, cur_col, wrap)); +} + +int +ahd_tagptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TAGPTR", + 0x21, regvalue, cur_col, wrap)); +} + +int +ahd_lunptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LUNPTR", + 0x22, regvalue, cur_col, wrap)); +} + +int +ahd_datalenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DATALENPTR", + 0x23, regvalue, cur_col, wrap)); +} + +int +ahd_statlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "STATLENPTR", + 0x24, regvalue, cur_col, wrap)); +} + +int +ahd_cmdlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDLENPTR", + 0x25, regvalue, cur_col, wrap)); +} + +int +ahd_attrptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ATTRPTR", + 0x26, regvalue, cur_col, wrap)); +} + +int +ahd_flagptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLAGPTR", + 0x27, regvalue, cur_col, wrap)); +} + +int +ahd_cmdptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDPTR", + 0x28, regvalue, cur_col, wrap)); +} + +int +ahd_qnextptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QNEXTPTR", + 0x29, regvalue, cur_col, wrap)); +} + +int +ahd_idptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "IDPTR", + 0x2a, regvalue, cur_col, wrap)); +} + +int +ahd_abrtbyteptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ABRTBYTEPTR", + 0x2b, regvalue, cur_col, wrap)); +} + +int +ahd_abrtbitptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ABRTBITPTR", + 0x2c, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmdbytes_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMDBYTES", + 0x2d, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmd2rcv_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMD2RCV", + 0x2e, regvalue, cur_col, wrap)); +} + +int +ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHORTTHRESH", + 0x2f, regvalue, cur_col, wrap)); +} + +int +ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LUNLEN", + 0x30, regvalue, cur_col, wrap)); +} + +int +ahd_cdblimit_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CDBLIMIT", + 0x31, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMD", + 0x32, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmdcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMDCNT", + 0x33, regvalue, cur_col, wrap)); +} + +int +ahd_lqrsvd01_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQRSVD01", + 0x34, regvalue, cur_col, wrap)); +} + +int +ahd_lqrsvd16_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQRSVD16", + 0x35, regvalue, cur_col, wrap)); +} + +int +ahd_lqrsvd17_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQRSVD17", + 0x36, regvalue, cur_col, wrap)); +} + +int +ahd_cmdrsvd0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDRSVD0", + 0x37, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQCTL0_parse_table[] = { + { "LQ0INITGCLT", 0x03, 0x03 }, + { "LQ0TARGCLT", 0x0c, 0x0c }, + { "LQIINITGCLT", 0x30, 0x30 }, + { "LQITARGCLT", 0xc0, 0xc0 } +}; + +int +ahd_lqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQCTL0_parse_table, 4, "LQCTL0", + 0x38, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQCTL1_parse_table[] = { + { "ABORTPENDING", 0x01, 0x01 }, + { "SINGLECMD", 0x02, 0x02 }, + { "PCI2PCI", 0x04, 0x04 } +}; + +int +ahd_lqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQCTL1_parse_table, 3, "LQCTL1", + 0x38, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSBIST0_parse_table[] = { + { "OSBISTRUN", 0x01, 0x01 }, + { "OSBISTDONE", 0x02, 0x02 }, + { "OSBISTERR", 0x04, 0x04 }, + { "GSBISTRUN", 0x10, 0x10 }, + { "GSBISTDONE", 0x20, 0x20 }, + { "GSBISTERR", 0x40, 0x40 } +}; + +int +ahd_scsbist0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSBIST0_parse_table, 6, "SCSBIST0", + 0x39, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQCTL2_parse_table[] = { + { "LQOPAUSE", 0x01, 0x01 }, + { "LQOTOIDLE", 0x02, 0x02 }, + { "LQOCONTINUE", 0x04, 0x04 }, + { "LQORETRY", 0x08, 0x08 }, + { "LQIPAUSE", 0x10, 0x10 }, + { "LQITOIDLE", 0x20, 0x20 }, + { "LQICONTINUE", 0x40, 0x40 }, + { "LQIRETRY", 0x80, 0x80 } +}; + +int +ahd_lqctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQCTL2_parse_table, 8, "LQCTL2", + 0x39, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSBIST1_parse_table[] = { + { "NTBISTRUN", 0x01, 0x01 }, + { "NTBISTDONE", 0x02, 0x02 }, + { "NTBISTERR", 0x04, 0x04 } +}; + +int +ahd_scsbist1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSBIST1_parse_table, 3, "SCSBIST1", + 0x3a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISEQ0_parse_table[] = { + { "SCSIRSTO", 0x01, 0x01 }, + { "FORCEBUSFREE", 0x10, 0x10 }, + { "ENARBO", 0x20, 0x20 }, + { "ENSELO", 0x40, 0x40 }, + { "TEMODEO", 0x80, 0x80 } +}; + +int +ahd_scsiseq0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISEQ0_parse_table, 5, "SCSISEQ0", + 0x3a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISEQ1_parse_table[] = { + { "ALTSTIM", 0x01, 0x01 }, + { "ENAUTOATNP", 0x02, 0x02 }, + { "MANUALP", 0x0c, 0x0c }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "MANUALCTL", 0x40, 0x40 } +}; + +int +ahd_scsiseq1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISEQ1_parse_table, 6, "SCSISEQ1", + 0x3b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SXFRCTL0_parse_table[] = { + { "SPIOEN", 0x08, 0x08 }, + { "BIOSCANCELEN", 0x10, 0x10 }, + { "DFPEXP", 0x40, 0x40 }, + { "DFON", 0x80, 0x80 } +}; + +int +ahd_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SXFRCTL0_parse_table, 4, "SXFRCTL0", + 0x3c, regvalue, cur_col, wrap)); +} + +int +ahd_businitid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BUSINITID", + 0x3c, regvalue, cur_col, wrap)); +} + +int +ahd_dlcount_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DLCOUNT", + 0x3c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SXFRCTL1_parse_table[] = { + { "STPWEN", 0x01, 0x01 }, + { "ACTNEGEN", 0x02, 0x02 }, + { "ENSTIMER", 0x04, 0x04 }, + { "STIMESEL", 0x18, 0x18 }, + { "ENSPCHK", 0x20, 0x20 }, + { "ENSACHK", 0x40, 0x40 }, + { "BITBUCKET", 0x80, 0x80 } +}; + +int +ahd_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1", + 0x3d, regvalue, cur_col, wrap)); +} + +int +ahd_bustargid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BUSTARGID", + 0x3e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SXFRCTL2_parse_table[] = { + { "ASU", 0x07, 0x07 }, + { "CMDDMAEN", 0x08, 0x08 }, + { "AUTORSTDIS", 0x10, 0x10 } +}; + +int +ahd_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2", + 0x3e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFFSTAT_parse_table[] = { + { "CURRFIFO_0", 0x00, 0x03 }, + { "CURRFIFO_1", 0x01, 0x03 }, + { "CURRFIFO_NONE", 0x03, 0x03 }, + { "FIFO0FREE", 0x10, 0x10 }, + { "FIFO1FREE", 0x20, 0x20 }, + { "CURRFIFO", 0x03, 0x03 } +}; + +int +ahd_dffstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFFSTAT_parse_table, 6, "DFFSTAT", + 0x3f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISIGO_parse_table[] = { + { "P_DATAOUT", 0x00, 0xe0 }, + { "P_DATAOUT_DT", 0x20, 0xe0 }, + { "P_DATAIN", 0x40, 0xe0 }, + { "P_DATAIN_DT", 0x60, 0xe0 }, + { "P_COMMAND", 0x80, 0xe0 }, + { "P_MESGOUT", 0xa0, 0xe0 }, + { "P_STATUS", 0xc0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 }, + { "ACKO", 0x01, 0x01 }, + { "REQO", 0x02, 0x02 }, + { "BSYO", 0x04, 0x04 }, + { "SELO", 0x08, 0x08 }, + { "ATNO", 0x10, 0x10 }, + { "MSGO", 0x20, 0x20 }, + { "IOO", 0x40, 0x40 }, + { "CDO", 0x80, 0x80 }, + { "PHASE_MASK", 0xe0, 0xe0 } +}; + +int +ahd_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISIGO_parse_table, 17, "SCSISIGO", + 0x40, regvalue, cur_col, wrap)); +} + +int +ahd_multargid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MULTARGID", + 0x40, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISIGI_parse_table[] = { + { "P_DATAOUT", 0x00, 0xe0 }, + { "P_DATAOUT_DT", 0x20, 0xe0 }, + { "P_DATAIN", 0x40, 0xe0 }, + { "P_DATAIN_DT", 0x60, 0xe0 }, + { "P_COMMAND", 0x80, 0xe0 }, + { "P_MESGOUT", 0xa0, 0xe0 }, + { "P_STATUS", 0xc0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 }, + { "ACKI", 0x01, 0x01 }, + { "REQI", 0x02, 0x02 }, + { "BSYI", 0x04, 0x04 }, + { "SELI", 0x08, 0x08 }, + { "ATNI", 0x10, 0x10 }, + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "PHASE_MASK", 0xe0, 0xe0 } +}; + +int +ahd_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISIGI_parse_table, 17, "SCSISIGI", + 0x41, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSIPHASE_parse_table[] = { + { "DATA_OUT_PHASE", 0x01, 0x03 }, + { "DATA_IN_PHASE", 0x02, 0x03 }, + { "DATA_PHASE_MASK", 0x03, 0x03 }, + { "MSG_OUT_PHASE", 0x04, 0x04 }, + { "MSG_IN_PHASE", 0x08, 0x08 }, + { "COMMAND_PHASE", 0x10, 0x10 }, + { "STATUS_PHASE", 0x20, 0x20 } +}; + +int +ahd_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE", + 0x42, regvalue, cur_col, wrap)); +} + +int +ahd_scsidat0_img_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCSIDAT0_IMG", + 0x43, regvalue, cur_col, wrap)); +} + +int +ahd_scsidat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCSIDAT", + 0x44, regvalue, cur_col, wrap)); +} + +int +ahd_scsibus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCSIBUS", + 0x46, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t TARGIDIN_parse_table[] = { + { "TARGID", 0x0f, 0x0f }, + { "CLKOUT", 0x80, 0x80 } +}; + +int +ahd_targidin_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(TARGIDIN_parse_table, 2, "TARGIDIN", + 0x48, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SELID_parse_table[] = { + { "ONEBIT", 0x08, 0x08 }, + { "SELID_MASK", 0xf0, 0xf0 } +}; + +int +ahd_selid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SELID_parse_table, 2, "SELID", + 0x49, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SBLKCTL_parse_table[] = { + { "SELWIDE", 0x02, 0x02 }, + { "ENAB20", 0x04, 0x04 }, + { "ENAB40", 0x08, 0x08 }, + { "DIAGLEDON", 0x40, 0x40 }, + { "DIAGLEDEN", 0x80, 0x80 } +}; + +int +ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL", + 0x4a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = { + { "AUTO_MSGOUT_DE", 0x02, 0x02 }, + { "ENDGFORMCHK", 0x04, 0x04 }, + { "BUSFREEREV", 0x10, 0x10 }, + { "BIASCANCTL", 0x20, 0x20 }, + { "AUTOACKEN", 0x40, 0x40 }, + { "BIOSCANCTL", 0x80, 0x80 }, + { "OPTIONMODE_DEFAULTS",0x02, 0x02 } +}; + +int +ahd_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OPTIONMODE_parse_table, 7, "OPTIONMODE", + 0x4a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT0_parse_table[] = { + { "ARBDO", 0x01, 0x01 }, + { "SPIORDY", 0x02, 0x02 }, + { "OVERRUN", 0x04, 0x04 }, + { "IOERR", 0x08, 0x08 }, + { "SELINGO", 0x10, 0x10 }, + { "SELDI", 0x20, 0x20 }, + { "SELDO", 0x40, 0x40 }, + { "TARGET", 0x80, 0x80 } +}; + +int +ahd_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT0_parse_table, 8, "SSTAT0", + 0x4b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT0_parse_table[] = { + { "CLRARBDO", 0x01, 0x01 }, + { "CLRSPIORDY", 0x02, 0x02 }, + { "CLROVERRUN", 0x04, 0x04 }, + { "CLRIOERR", 0x08, 0x08 }, + { "CLRSELINGO", 0x10, 0x10 }, + { "CLRSELDI", 0x20, 0x20 }, + { "CLRSELDO", 0x40, 0x40 } +}; + +int +ahd_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT0_parse_table, 7, "CLRSINT0", + 0x4b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE0_parse_table[] = { + { "ENARBDO", 0x01, 0x01 }, + { "ENSPIORDY", 0x02, 0x02 }, + { "ENOVERRUN", 0x04, 0x04 }, + { "ENIOERR", 0x08, 0x08 }, + { "ENSELINGO", 0x10, 0x10 }, + { "ENSELDI", 0x20, 0x20 }, + { "ENSELDO", 0x40, 0x40 } +}; + +int +ahd_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE0_parse_table, 7, "SIMODE0", + 0x4b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT1_parse_table[] = { + { "CLRREQINIT", 0x01, 0x01 }, + { "CLRSTRB2FAST", 0x02, 0x02 }, + { "CLRSCSIPERR", 0x04, 0x04 }, + { "CLRBUSFREE", 0x08, 0x08 }, + { "CLRSCSIRSTI", 0x20, 0x20 }, + { "CLRATNO", 0x40, 0x40 }, + { "CLRSELTIMEO", 0x80, 0x80 } +}; + +int +ahd_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT1_parse_table, 7, "CLRSINT1", + 0x4c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT1_parse_table[] = { + { "REQINIT", 0x01, 0x01 }, + { "STRB2FAST", 0x02, 0x02 }, + { "SCSIPERR", 0x04, 0x04 }, + { "BUSFREE", 0x08, 0x08 }, + { "PHASEMIS", 0x10, 0x10 }, + { "SCSIRSTI", 0x20, 0x20 }, + { "ATNTARG", 0x40, 0x40 }, + { "SELTO", 0x80, 0x80 } +}; + +int +ahd_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT1_parse_table, 8, "SSTAT1", + 0x4c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT2_parse_table[] = { + { "BUSFREE_LQO", 0x40, 0xc0 }, + { "BUSFREE_DFF0", 0x80, 0xc0 }, + { "BUSFREE_DFF1", 0xc0, 0xc0 }, + { "DMADONE", 0x01, 0x01 }, + { "SDONE", 0x02, 0x02 }, + { "WIDE_RES", 0x04, 0x04 }, + { "BSYX", 0x08, 0x08 }, + { "EXP_ACTIVE", 0x10, 0x10 }, + { "NONPACKREQ", 0x20, 0x20 }, + { "BUSFREETIME", 0xc0, 0xc0 } +}; + +int +ahd_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT2_parse_table, 10, "SSTAT2", + 0x4d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT2_parse_table[] = { + { "CLRDMADONE", 0x01, 0x01 }, + { "CLRSDONE", 0x02, 0x02 }, + { "CLRWIDE_RES", 0x04, 0x04 }, + { "CLRNONPACKREQ", 0x20, 0x20 } +}; + +int +ahd_clrsint2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT2_parse_table, 4, "CLRSINT2", + 0x4d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE2_parse_table[] = { + { "ENDMADONE", 0x01, 0x01 }, + { "ENSDONE", 0x02, 0x02 }, + { "ENWIDE_RES", 0x04, 0x04 } +}; + +int +ahd_simode2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE2_parse_table, 3, "SIMODE2", + 0x4d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PERRDIAG_parse_table[] = { + { "DTERR", 0x01, 0x01 }, + { "DGFORMERR", 0x02, 0x02 }, + { "CRCERR", 0x04, 0x04 }, + { "AIPERR", 0x08, 0x08 }, + { "PARITYERR", 0x10, 0x10 }, + { "PREVPHASE", 0x20, 0x20 }, + { "HIPERR", 0x40, 0x40 }, + { "HIZERO", 0x80, 0x80 } +}; + +int +ahd_perrdiag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PERRDIAG_parse_table, 8, "PERRDIAG", + 0x4e, regvalue, cur_col, wrap)); +} + +int +ahd_lqistate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQISTATE", + 0x4e, regvalue, cur_col, wrap)); +} + +int +ahd_soffcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SOFFCNT", + 0x4f, regvalue, cur_col, wrap)); +} + +int +ahd_lqostate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQOSTATE", + 0x4f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQISTAT0_parse_table[] = { + { "LQIATNCMD", 0x01, 0x01 }, + { "LQIATNLQ", 0x02, 0x02 }, + { "LQIBADLQT", 0x04, 0x04 }, + { "LQICRCT2", 0x08, 0x08 }, + { "LQICRCT1", 0x10, 0x10 }, + { "LQIATNQAS", 0x20, 0x20 } +}; + +int +ahd_lqistat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQISTAT0_parse_table, 6, "LQISTAT0", + 0x50, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQIINT0_parse_table[] = { + { "CLRLQIATNCMD", 0x01, 0x01 }, + { "CLRLQIATNLQ", 0x02, 0x02 }, + { "CLRLQIBADLQT", 0x04, 0x04 }, + { "CLRLQICRCT2", 0x08, 0x08 }, + { "CLRLQICRCT1", 0x10, 0x10 }, + { "CLRLQIATNQAS", 0x20, 0x20 } +}; + +int +ahd_clrlqiint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQIINT0_parse_table, 6, "CLRLQIINT0", + 0x50, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQIMODE0_parse_table[] = { + { "ENLQIATNCMD", 0x01, 0x01 }, + { "ENLQIATNLQ", 0x02, 0x02 }, + { "ENLQIBADLQT", 0x04, 0x04 }, + { "ENLQICRCT2", 0x08, 0x08 }, + { "ENLQICRCT1", 0x10, 0x10 }, + { "ENLQIATNQASK", 0x20, 0x20 } +}; + +int +ahd_lqimode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQIMODE0_parse_table, 6, "LQIMODE0", + 0x50, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQIMODE1_parse_table[] = { + { "ENLQIOVERI_NLQ", 0x01, 0x01 }, + { "ENLQIOVERI_LQ", 0x02, 0x02 }, + { "ENLQIBADLQI", 0x04, 0x04 }, + { "ENLQICRCI_NLQ", 0x08, 0x08 }, + { "ENLQICRCI_LQ", 0x10, 0x10 }, + { "ENLIQABORT", 0x20, 0x20 }, + { "ENLQIPHASE_NLQ", 0x40, 0x40 }, + { "ENLQIPHASE_LQ", 0x80, 0x80 } +}; + +int +ahd_lqimode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQIMODE1_parse_table, 8, "LQIMODE1", + 0x51, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQISTAT1_parse_table[] = { + { "LQIOVERI_NLQ", 0x01, 0x01 }, + { "LQIOVERI_LQ", 0x02, 0x02 }, + { "LQIBADLQI", 0x04, 0x04 }, + { "LQICRCI_NLQ", 0x08, 0x08 }, + { "LQICRCI_LQ", 0x10, 0x10 }, + { "LQIABORT", 0x20, 0x20 }, + { "LQIPHASE_NLQ", 0x40, 0x40 }, + { "LQIPHASE_LQ", 0x80, 0x80 } +}; + +int +ahd_lqistat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQISTAT1_parse_table, 8, "LQISTAT1", + 0x51, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQIINT1_parse_table[] = { + { "CLRLQIOVERI_NLQ", 0x01, 0x01 }, + { "CLRLQIOVERI_LQ", 0x02, 0x02 }, + { "CLRLQIBADLQI", 0x04, 0x04 }, + { "CLRLQICRCI_NLQ", 0x08, 0x08 }, + { "CLRLQICRCI_LQ", 0x10, 0x10 }, + { "CLRLIQABORT", 0x20, 0x20 }, + { "CLRLQIPHASE_NLQ", 0x40, 0x40 }, + { "CLRLQIPHASE_LQ", 0x80, 0x80 } +}; + +int +ahd_clrlqiint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQIINT1_parse_table, 8, "CLRLQIINT1", + 0x51, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQISTAT2_parse_table[] = { + { "LQIGSAVAIL", 0x01, 0x01 }, + { "LQISTOPCMD", 0x02, 0x02 }, + { "LQISTOPLQ", 0x04, 0x04 }, + { "LQISTOPPKT", 0x08, 0x08 }, + { "LQIWAITFIFO", 0x10, 0x10 }, + { "LQIWORKONLQ", 0x20, 0x20 }, + { "LQIPHASE_OUTPKT", 0x40, 0x40 }, + { "PACKETIZED", 0x80, 0x80 } +}; + +int +ahd_lqistat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQISTAT2_parse_table, 8, "LQISTAT2", + 0x52, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT3_parse_table[] = { + { "OSRAMPERR", 0x01, 0x01 }, + { "NTRAMPERR", 0x02, 0x02 } +}; + +int +ahd_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT3_parse_table, 2, "SSTAT3", + 0x53, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE3_parse_table[] = { + { "ENOSRAMPERR", 0x01, 0x01 }, + { "ENNTRAMPERR", 0x02, 0x02 } +}; + +int +ahd_simode3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE3_parse_table, 2, "SIMODE3", + 0x53, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT3_parse_table[] = { + { "CLROSRAMPERR", 0x01, 0x01 }, + { "CLRNTRAMPERR", 0x02, 0x02 } +}; + +int +ahd_clrsint3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT3_parse_table, 2, "CLRSINT3", + 0x53, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOMODE0_parse_table[] = { + { "ENLQOTCRC", 0x01, 0x01 }, + { "ENLQOATNPKT", 0x02, 0x02 }, + { "ENLQOATNLQ", 0x04, 0x04 }, + { "ENLQOSTOPT2", 0x08, 0x08 }, + { "ENLQOTARGSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0", + 0x54, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = { + { "LQOTCRC", 0x01, 0x01 }, + { "LQOATNPKT", 0x02, 0x02 }, + { "LQOATNLQ", 0x04, 0x04 }, + { "LQOSTOPT2", 0x08, 0x08 }, + { "LQOTARGSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqostat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSTAT0_parse_table, 5, "LQOSTAT0", + 0x54, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQOINT0_parse_table[] = { + { "CLRLQOTCRC", 0x01, 0x01 }, + { "CLRLQOATNPKT", 0x02, 0x02 }, + { "CLRLQOATNLQ", 0x04, 0x04 }, + { "CLRLQOSTOPT2", 0x08, 0x08 }, + { "CLRLQOTARGSCBPERR", 0x10, 0x10 } +}; + +int +ahd_clrlqoint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQOINT0_parse_table, 5, "CLRLQOINT0", + 0x54, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = { + { "LQOPHACHGINPKT", 0x01, 0x01 }, + { "LQOBUSFREE", 0x02, 0x02 }, + { "LQOBADQAS", 0x04, 0x04 }, + { "LQOSTOPI2", 0x08, 0x08 }, + { "LQOINITSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqostat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSTAT1_parse_table, 5, "LQOSTAT1", + 0x55, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQOINT1_parse_table[] = { + { "CLRLQOPHACHGINPKT", 0x01, 0x01 }, + { "CLRLQOBUSFREE", 0x02, 0x02 }, + { "CLRLQOBADQAS", 0x04, 0x04 }, + { "CLRLQOSTOPI2", 0x08, 0x08 }, + { "CLRLQOINITSCBPERR", 0x10, 0x10 } +}; + +int +ahd_clrlqoint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQOINT1_parse_table, 5, "CLRLQOINT1", + 0x55, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOMODE1_parse_table[] = { + { "ENLQOPHACHGINPKT", 0x01, 0x01 }, + { "ENLQOBUSFREE", 0x02, 0x02 }, + { "ENLQOBADQAS", 0x04, 0x04 }, + { "ENLQOSTOPI2", 0x08, 0x08 }, + { "ENLQOINITSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1", + 0x55, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = { + { "LQOSTOP0", 0x01, 0x01 }, + { "LQOPHACHGOUTPKT", 0x02, 0x02 }, + { "LQOWAITFIFO", 0x10, 0x10 }, + { "LQOPKT", 0xe0, 0xe0 } +}; + +int +ahd_lqostat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSTAT2_parse_table, 4, "LQOSTAT2", + 0x56, regvalue, cur_col, wrap)); +} + +int +ahd_os_space_cnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OS_SPACE_CNT", + 0x56, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE1_parse_table[] = { + { "ENREQINIT", 0x01, 0x01 }, + { "ENSTRB2FAST", 0x02, 0x02 }, + { "ENSCSIPERR", 0x04, 0x04 }, + { "ENBUSFREE", 0x08, 0x08 }, + { "ENPHASEMIS", 0x10, 0x10 }, + { "ENSCSIRST", 0x20, 0x20 }, + { "ENATNTARG", 0x40, 0x40 }, + { "ENSELTIMO", 0x80, 0x80 } +}; + +int +ahd_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE1_parse_table, 8, "SIMODE1", + 0x57, regvalue, cur_col, wrap)); +} + +int +ahd_gsfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "GSFIFO", + 0x58, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFFSXFRCTL_parse_table[] = { + { "RSTCHN", 0x01, 0x01 }, + { "CLRCHN", 0x02, 0x02 }, + { "CLRSHCNT", 0x04, 0x04 }, + { "DFFBITBUCKET", 0x08, 0x08 } +}; + +int +ahd_dffsxfrctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFFSXFRCTL_parse_table, 4, "DFFSXFRCTL", + 0x5a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSCSCTL_parse_table[] = { + { "LQONOCHKOVER", 0x01, 0x01 }, + { "LQOH2A_VERSION", 0x80, 0x80 } +}; + +int +ahd_lqoscsctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSCSCTL_parse_table, 2, "LQOSCSCTL", + 0x5a, regvalue, cur_col, wrap)); +} + +int +ahd_nextscb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEXTSCB", + 0x5a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSEQINTSRC_parse_table[] = { + { "CLRCFG4TCMD", 0x01, 0x01 }, + { "CLRCFG4ICMD", 0x02, 0x02 }, + { "CLRCFG4TSTAT", 0x04, 0x04 }, + { "CLRCFG4ISTAT", 0x08, 0x08 }, + { "CLRCFG4DATA", 0x10, 0x10 }, + { "CLRSAVEPTRS", 0x20, 0x20 }, + { "CLRCTXTDONE", 0x40, 0x40 } +}; + +int +ahd_clrseqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSEQINTSRC_parse_table, 7, "CLRSEQINTSRC", + 0x5b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTSRC_parse_table[] = { + { "CFG4TCMD", 0x01, 0x01 }, + { "CFG4ICMD", 0x02, 0x02 }, + { "CFG4TSTAT", 0x04, 0x04 }, + { "CFG4ISTAT", 0x08, 0x08 }, + { "CFG4DATA", 0x10, 0x10 }, + { "SAVEPTRS", 0x20, 0x20 }, + { "CTXTDONE", 0x40, 0x40 } +}; + +int +ahd_seqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTSRC_parse_table, 7, "SEQINTSRC", + 0x5b, regvalue, cur_col, wrap)); +} + +int +ahd_currscb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CURRSCB", + 0x5c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQIMODE_parse_table[] = { + { "ENCFG4TCMD", 0x01, 0x01 }, + { "ENCFG4ICMD", 0x02, 0x02 }, + { "ENCFG4TSTAT", 0x04, 0x04 }, + { "ENCFG4ISTAT", 0x08, 0x08 }, + { "ENCFG4DATA", 0x10, 0x10 }, + { "ENSAVEPTRS", 0x20, 0x20 }, + { "ENCTXTDONE", 0x40, 0x40 } +}; + +int +ahd_seqimode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQIMODE_parse_table, 7, "SEQIMODE", + 0x5c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t MDFFSTAT_parse_table[] = { + { "FIFOFREE", 0x01, 0x01 }, + { "DATAINFIFO", 0x02, 0x02 }, + { "DLZERO", 0x04, 0x04 }, + { "SHVALID", 0x08, 0x08 }, + { "LASTSDONE", 0x10, 0x10 }, + { "SHCNTMINUS1", 0x20, 0x20 }, + { "SHCNTNEGATIVE", 0x40, 0x40 } +}; + +int +ahd_mdffstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(MDFFSTAT_parse_table, 7, "MDFFSTAT", + 0x5d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CRCCONTROL_parse_table[] = { + { "CRCVALCHKEN", 0x40, 0x40 } +}; + +int +ahd_crccontrol_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CRCCONTROL_parse_table, 1, "CRCCONTROL", + 0x5d, regvalue, cur_col, wrap)); +} + +int +ahd_dfftag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFFTAG", + 0x5e, regvalue, cur_col, wrap)); +} + +int +ahd_lastscb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LASTSCB", + 0x5e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSITEST_parse_table[] = { + { "SEL_TXPLL_DEBUG", 0x04, 0x04 }, + { "CNTRTEST", 0x08, 0x08 } +}; + +int +ahd_scsitest_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSITEST_parse_table, 2, "SCSITEST", + 0x5e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t IOPDNCTL_parse_table[] = { + { "PDN_DIFFSENSE", 0x01, 0x01 }, + { "PDN_IDIST", 0x04, 0x04 }, + { "DISABLE_OE", 0x80, 0x80 } +}; + +int +ahd_iopdnctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(IOPDNCTL_parse_table, 3, "IOPDNCTL", + 0x5f, regvalue, cur_col, wrap)); +} + +int +ahd_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHADDR", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahd_negoaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEGOADDR", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahd_dgrpcrci_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DGRPCRCI", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahd_negperiod_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEGPERIOD", + 0x61, regvalue, cur_col, wrap)); +} + +int +ahd_packcrci_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PACKCRCI", + 0x62, regvalue, cur_col, wrap)); +} + +int +ahd_negoffset_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEGOFFSET", + 0x62, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t NEGPPROPTS_parse_table[] = { + { "PPROPT_IUT", 0x01, 0x01 }, + { "PPROPT_DT", 0x02, 0x02 }, + { "PPROPT_QAS", 0x04, 0x04 }, + { "PPROPT_PACE", 0x08, 0x08 } +}; + +int +ahd_negppropts_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NEGPPROPTS_parse_table, 4, "NEGPPROPTS", + 0x63, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t NEGCONOPTS_parse_table[] = { + { "WIDEXFER", 0x01, 0x01 }, + { "ENAUTOATNO", 0x02, 0x02 }, + { "ENAUTOATNI", 0x04, 0x04 }, + { "ENSLOWCRC", 0x08, 0x08 }, + { "RTI_OVRDTRN", 0x10, 0x10 }, + { "RTI_WRTDIS", 0x20, 0x20 }, + { "ENSNAPSHOT", 0x40, 0x40 } +}; + +int +ahd_negconopts_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NEGCONOPTS_parse_table, 7, "NEGCONOPTS", + 0x64, regvalue, cur_col, wrap)); +} + +int +ahd_annexcol_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ANNEXCOL", + 0x65, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSCHKN_parse_table[] = { + { "LSTSGCLRDIS", 0x01, 0x01 }, + { "SHVALIDSTDIS", 0x02, 0x02 }, + { "DFFACTCLR", 0x04, 0x04 }, + { "SDONEMSKDIS", 0x08, 0x08 }, + { "WIDERESEN", 0x10, 0x10 }, + { "CURRFIFODEF", 0x20, 0x20 }, + { "STSELSKIDDIS", 0x40, 0x40 } +}; + +int +ahd_scschkn_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSCHKN_parse_table, 7, "SCSCHKN", + 0x66, regvalue, cur_col, wrap)); +} + +int +ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ANNEXDAT", + 0x66, regvalue, cur_col, wrap)); +} + +int +ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "IOWNID", + 0x67, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL960CTL0_parse_table[] = { + { "PLL_ENFBM", 0x01, 0x01 }, + { "PLL_DLPF", 0x02, 0x02 }, + { "PLL_ENLPF", 0x04, 0x04 }, + { "PLL_ENLUD", 0x08, 0x08 }, + { "PLL_NS", 0x30, 0x30 }, + { "PLL_PWDN", 0x40, 0x40 }, + { "PLL_VCOSEL", 0x80, 0x80 } +}; + +int +ahd_pll960ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL960CTL0_parse_table, 7, "PLL960CTL0", + 0x68, regvalue, cur_col, wrap)); +} + +int +ahd_shcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHCNT", + 0x68, regvalue, cur_col, wrap)); +} + +int +ahd_townid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TOWNID", + 0x69, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL960CTL1_parse_table[] = { + { "PLL_RST", 0x01, 0x01 }, + { "PLL_CNTCLR", 0x40, 0x40 }, + { "PLL_CNTEN", 0x80, 0x80 } +}; + +int +ahd_pll960ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL960CTL1_parse_table, 3, "PLL960CTL1", + 0x69, regvalue, cur_col, wrap)); +} + +int +ahd_pll960cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PLL960CNT0", + 0x6a, regvalue, cur_col, wrap)); +} + +int +ahd_xsig_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "XSIG", + 0x6a, regvalue, cur_col, wrap)); +} + +int +ahd_seloid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SELOID", + 0x6b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL400CTL0_parse_table[] = { + { "PLL_ENFBM", 0x01, 0x01 }, + { "PLL_DLPF", 0x02, 0x02 }, + { "PLL_ENLPF", 0x04, 0x04 }, + { "PLL_ENLUD", 0x08, 0x08 }, + { "PLL_NS", 0x30, 0x30 }, + { "PLL_PWDN", 0x40, 0x40 }, + { "PLL_VCOSEL", 0x80, 0x80 } +}; + +int +ahd_pll400ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL400CTL0_parse_table, 7, "PLL400CTL0", + 0x6c, regvalue, cur_col, wrap)); +} + +int +ahd_fairness_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FAIRNESS", + 0x6c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL400CTL1_parse_table[] = { + { "PLL_RST", 0x01, 0x01 }, + { "PLL_CNTCLR", 0x40, 0x40 }, + { "PLL_CNTEN", 0x80, 0x80 } +}; + +int +ahd_pll400ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL400CTL1_parse_table, 3, "PLL400CTL1", + 0x6d, regvalue, cur_col, wrap)); +} + +int +ahd_pll400cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PLL400CNT0", + 0x6e, regvalue, cur_col, wrap)); +} + +int +ahd_unfairness_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "UNFAIRNESS", + 0x6e, regvalue, cur_col, wrap)); +} + +int +ahd_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HADDR", + 0x70, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLLDELAY_parse_table[] = { + { "SPLIT_DROP_REQ", 0x80, 0x80 } +}; + +int +ahd_plldelay_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLLDELAY_parse_table, 1, "PLLDELAY", + 0x70, regvalue, cur_col, wrap)); +} + +int +ahd_hodmaadr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HODMAADR", + 0x70, regvalue, cur_col, wrap)); +} + +int +ahd_hodmacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HODMACNT", + 0x78, regvalue, cur_col, wrap)); +} + +int +ahd_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HCNT", + 0x78, regvalue, cur_col, wrap)); +} + +int +ahd_hodmaen_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HODMAEN", + 0x7a, regvalue, cur_col, wrap)); +} + +int +ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SGHADDR", + 0x7c, regvalue, cur_col, wrap)); +} + +int +ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBHADDR", + 0x7c, regvalue, cur_col, wrap)); +} + +int +ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SGHCNT", + 0x84, regvalue, cur_col, wrap)); +} + +int +ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBHCNT", + 0x84, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = { + { "WR_DFTHRSH_MIN", 0x00, 0x70 }, + { "RD_DFTHRSH_MIN", 0x00, 0x07 }, + { "RD_DFTHRSH_25", 0x01, 0x07 }, + { "RD_DFTHRSH_50", 0x02, 0x07 }, + { "RD_DFTHRSH_63", 0x03, 0x07 }, + { "RD_DFTHRSH_75", 0x04, 0x07 }, + { "RD_DFTHRSH_85", 0x05, 0x07 }, + { "RD_DFTHRSH_90", 0x06, 0x07 }, + { "RD_DFTHRSH_MAX", 0x07, 0x07 }, + { "WR_DFTHRSH_25", 0x10, 0x70 }, + { "WR_DFTHRSH_50", 0x20, 0x70 }, + { "WR_DFTHRSH_63", 0x30, 0x70 }, + { "WR_DFTHRSH_75", 0x40, 0x70 }, + { "WR_DFTHRSH_85", 0x50, 0x70 }, + { "WR_DFTHRSH_90", 0x60, 0x70 }, + { "WR_DFTHRSH_MAX", 0x70, 0x70 }, + { "RD_DFTHRSH", 0x07, 0x07 }, + { "WR_DFTHRSH", 0x70, 0x70 } +}; + +int +ahd_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH", + 0x88, regvalue, cur_col, wrap)); +} + +int +ahd_romaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ROMADDR", + 0x8a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ROMCNTRL_parse_table[] = { + { "RDY", 0x01, 0x01 }, + { "REPEAT", 0x02, 0x02 }, + { "ROMSPD", 0x18, 0x18 }, + { "ROMOP", 0xe0, 0xe0 } +}; + +int +ahd_romcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ROMCNTRL_parse_table, 4, "ROMCNTRL", + 0x8d, regvalue, cur_col, wrap)); +} + +int +ahd_romdata_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ROMDATA", + 0x8e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_cmcrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG0_parse_table, 2, "CMCRXMSG0", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ROENABLE_parse_table[] = { + { "DCH0ROEN", 0x01, 0x01 }, + { "DCH1ROEN", 0x02, 0x02 }, + { "SGROEN", 0x04, 0x04 }, + { "CMCROEN", 0x08, 0x08 }, + { "OVLYROEN", 0x10, 0x10 }, + { "MSIROEN", 0x20, 0x20 } +}; + +int +ahd_roenable_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ROENABLE_parse_table, 6, "ROENABLE", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_ovlyrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG0_parse_table, 2, "OVLYRXMSG0", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_dchrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG0_parse_table, 2, "DCHRXMSG0", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_ovlyrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG1_parse_table, 1, "OVLYRXMSG1", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t NSENABLE_parse_table[] = { + { "DCH0NSEN", 0x01, 0x01 }, + { "DCH1NSEN", 0x02, 0x02 }, + { "SGNSEN", 0x04, 0x04 }, + { "CMCNSEN", 0x08, 0x08 }, + { "OVLYNSEN", 0x10, 0x10 }, + { "MSINSEN", 0x20, 0x20 } +}; + +int +ahd_nsenable_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NSENABLE_parse_table, 6, "NSENABLE", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_dchrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG1_parse_table, 1, "DCHRXMSG1", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_cmcrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG1_parse_table, 1, "CMCRXMSG1", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_dchrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG2_parse_table, 1, "DCHRXMSG2", + 0x92, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_ovlyrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG2_parse_table, 1, "OVLYRXMSG2", + 0x92, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_cmcrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG2_parse_table, 1, "CMCRXMSG2", + 0x92, regvalue, cur_col, wrap)); +} + +int +ahd_ost_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OST", + 0x92, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_dchrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG3_parse_table, 1, "DCHRXMSG3", + 0x93, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_cmcrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG3_parse_table, 1, "CMCRXMSG3", + 0x93, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PCIXCTL_parse_table[] = { + { "CMPABCDIS", 0x01, 0x01 }, + { "TSCSERREN", 0x02, 0x02 }, + { "SRSPDPEEN", 0x04, 0x04 }, + { "SPLTSTADIS", 0x08, 0x08 }, + { "SPLTSMADIS", 0x10, 0x10 }, + { "UNEXPSCIEN", 0x20, 0x20 }, + { "SERRPULSE", 0x80, 0x80 } +}; + +int +ahd_pcixctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PCIXCTL_parse_table, 7, "PCIXCTL", + 0x93, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_ovlyrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG3_parse_table, 1, "OVLYRXMSG3", + 0x93, regvalue, cur_col, wrap)); +} + +int +ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OVLYSEQBCNT", + 0x94, regvalue, cur_col, wrap)); +} + +int +ahd_cmcseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMCSEQBCNT", + 0x94, regvalue, cur_col, wrap)); +} + +int +ahd_dchseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DCHSEQBCNT", + 0x94, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_cmcspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCSPLTSTAT0_parse_table, 8, "CMCSPLTSTAT0", + 0x96, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_ovlyspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0", + 0x96, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_dchspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHSPLTSTAT0_parse_table, 8, "DCHSPLTSTAT0", + 0x96, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1", + 0x97, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_cmcspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCSPLTSTAT1_parse_table, 1, "CMCSPLTSTAT1", + 0x97, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_ovlyspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYSPLTSTAT1_parse_table, 1, "OVLYSPLTSTAT1", + 0x97, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_sgrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG0_parse_table, 2, "SGRXMSG0", + 0x98, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR0_parse_table[] = { + { "LOWER_ADDR", 0x7f, 0x7f } +}; + +int +ahd_slvspltoutadr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR0_parse_table, 1, "SLVSPLTOUTADR0", + 0x98, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_sgrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG1_parse_table, 1, "SGRXMSG1", + 0x99, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR1_parse_table[] = { + { "REQ_FNUM", 0x07, 0x07 }, + { "REQ_DNUM", 0xf8, 0xf8 } +}; + +int +ahd_slvspltoutadr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR1_parse_table, 2, "SLVSPLTOUTADR1", + 0x99, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_sgrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG2_parse_table, 1, "SGRXMSG2", + 0x9a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR2_parse_table[] = { + { "REQ_BNUM", 0xff, 0xff } +}; + +int +ahd_slvspltoutadr2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR2_parse_table, 1, "SLVSPLTOUTADR2", + 0x9a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_sgrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG3_parse_table, 1, "SGRXMSG3", + 0x9b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR3_parse_table[] = { + { "RLXORD", 0x10, 0x10 }, + { "TAG_NUM", 0x1f, 0x1f } +}; + +int +ahd_slvspltoutadr3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR3_parse_table, 2, "SLVSPLTOUTADR3", + 0x9b, regvalue, cur_col, wrap)); +} + +int +ahd_sgseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SGSEQBCNT", + 0x9c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTATTR0_parse_table[] = { + { "LOWER_BCNT", 0xff, 0xff } +}; + +int +ahd_slvspltoutattr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTATTR0_parse_table, 1, "SLVSPLTOUTATTR0", + 0x9c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTATTR1_parse_table[] = { + { "CMPLT_FNUM", 0x07, 0x07 }, + { "CMPLT_DNUM", 0xf8, 0xf8 } +}; + +int +ahd_slvspltoutattr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTATTR1_parse_table, 2, "SLVSPLTOUTATTR1", + 0x9d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTATTR2_parse_table[] = { + { "CMPLT_BNUM", 0xff, 0xff } +}; + +int +ahd_slvspltoutattr2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTATTR2_parse_table, 1, "SLVSPLTOUTATTR2", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_sgspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGSPLTSTAT0_parse_table, 8, "SGSPLTSTAT0", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SFUNCT_parse_table[] = { + { "TEST_NUM", 0x0f, 0x0f }, + { "TEST_GROUP", 0xf0, 0xf0 } +}; + +int +ahd_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SFUNCT_parse_table, 2, "SFUNCT", + 0x9f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1", + 0x9f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_df0pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DF0PCISTAT_parse_table, 8, "DF0PCISTAT", + 0xa0, regvalue, cur_col, wrap)); +} + +int +ahd_reg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "REG0", + 0xa0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DF1PCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_df1pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DF1PCISTAT_parse_table, 8, "DF1PCISTAT", + 0xa1, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_sgpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGPCISTAT_parse_table, 7, "SGPCISTAT", + 0xa2, regvalue, cur_col, wrap)); +} + +int +ahd_reg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "REG1", + 0xa2, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_cmcpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCPCISTAT_parse_table, 8, "CMCPCISTAT", + 0xa3, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_ovlypcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYPCISTAT_parse_table, 7, "OVLYPCISTAT", + 0xa4, regvalue, cur_col, wrap)); +} + +int +ahd_reg_isr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "REG_ISR", + 0xa4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SG_STATE_parse_table[] = { + { "SEGS_AVAIL", 0x01, 0x01 }, + { "LOADING_NEEDED", 0x02, 0x02 }, + { "FETCH_INPROG", 0x04, 0x04 } +}; + +int +ahd_sg_state_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SG_STATE_parse_table, 3, "SG_STATE", + 0xa6, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t MSIPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "CLRPENDMSI", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 } +}; + +int +ahd_msipcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(MSIPCISTAT_parse_table, 6, "MSIPCISTAT", + 0xa6, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t TARGPCISTAT_parse_table[] = { + { "TWATERR", 0x02, 0x02 }, + { "STA", 0x08, 0x08 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_targpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(TARGPCISTAT_parse_table, 4, "TARGPCISTAT", + 0xa7, regvalue, cur_col, wrap)); +} + +int +ahd_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DATA_COUNT_ODD", + 0xa7, regvalue, cur_col, wrap)); +} + +int +ahd_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBPTR", + 0xa8, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBACNT", + 0xab, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCBAUTOPTR_parse_table[] = { + { "SCBPTR_OFF", 0x07, 0x07 }, + { "SCBPTR_ADDR", 0x38, 0x38 }, + { "AUSCBPTR_EN", 0x80, 0x80 } +}; + +int +ahd_scbautoptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCBAUTOPTR_parse_table, 3, "SCBAUTOPTR", + 0xab, regvalue, cur_col, wrap)); +} + +int +ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSGADDR", + 0xac, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBADDR", + 0xac, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbadr_bk_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBADR_BK", + 0xac, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMC_RAMBIST_parse_table[] = { + { "CMC_BUFFER_BIST_EN", 0x01, 0x01 }, + { "CMC_BUFFER_BIST_FAIL",0x02, 0x02 }, + { "SG_BIST_EN", 0x10, 0x10 }, + { "SG_BIST_FAIL", 0x20, 0x20 }, + { "SCBRAMBIST_FAIL", 0x40, 0x40 }, + { "SG_ELEMENT_SIZE", 0x80, 0x80 } +}; + +int +ahd_cmc_rambist_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMC_RAMBIST_parse_table, 6, "CMC_RAMBIST", + 0xad, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CCSGCTL_parse_table[] = { + { "CCSGRESET", 0x01, 0x01 }, + { "SG_FETCH_REQ", 0x02, 0x02 }, + { "CCSGENACK", 0x08, 0x08 }, + { "SG_CACHE_AVAIL", 0x10, 0x10 }, + { "CCSGDONE", 0x80, 0x80 }, + { "CCSGEN", 0x0c, 0x0c } +}; + +int +ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL", + 0xad, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = { + { "CCSCBRESET", 0x01, 0x01 }, + { "CCSCBDIR", 0x04, 0x04 }, + { "CCSCBEN", 0x08, 0x08 }, + { "CCARREN", 0x10, 0x10 }, + { "ARRDONE", 0x40, 0x40 }, + { "CCSCBDONE", 0x80, 0x80 } +}; + +int +ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL", + 0xad, regvalue, cur_col, wrap)); +} + +int +ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSGRAM", + 0xb0, regvalue, cur_col, wrap)); +} + +int +ahd_flexadr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLEXADR", + 0xb0, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBRAM", + 0xb0, regvalue, cur_col, wrap)); +} + +int +ahd_flexcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLEXCNT", + 0xb3, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t FLEXDMASTAT_parse_table[] = { + { "FLEXDMADONE", 0x01, 0x01 }, + { "FLEXDMAERR", 0x02, 0x02 } +}; + +int +ahd_flexdmastat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(FLEXDMASTAT_parse_table, 2, "FLEXDMASTAT", + 0xb5, regvalue, cur_col, wrap)); +} + +int +ahd_flexdata_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLEXDATA", + 0xb6, regvalue, cur_col, wrap)); +} + +int +ahd_brddat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BRDDAT", + 0xb8, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t BRDCTL_parse_table[] = { + { "BRDSTB", 0x01, 0x01 }, + { "BRDRW", 0x02, 0x02 }, + { "BRDEN", 0x04, 0x04 }, + { "BRDADDR", 0x38, 0x38 }, + { "FLXARBREQ", 0x40, 0x40 }, + { "FLXARBACK", 0x80, 0x80 } +}; + +int +ahd_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(BRDCTL_parse_table, 6, "BRDCTL", + 0xb9, regvalue, cur_col, wrap)); +} + +int +ahd_seeadr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SEEADR", + 0xba, regvalue, cur_col, wrap)); +} + +int +ahd_seedat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SEEDAT", + 0xbc, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEECTL_parse_table[] = { + { "SEEOP_ERAL", 0x40, 0x70 }, + { "SEEOP_WRITE", 0x50, 0x70 }, + { "SEEOP_READ", 0x60, 0x70 }, + { "SEEOP_ERASE", 0x70, 0x70 }, + { "SEESTART", 0x01, 0x01 }, + { "SEERST", 0x02, 0x02 }, + { "SEEOPCODE", 0x70, 0x70 }, + { "SEEOP_EWEN", 0x40, 0x40 }, + { "SEEOP_WALL", 0x40, 0x40 }, + { "SEEOP_EWDS", 0x40, 0x40 } +}; + +int +ahd_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEECTL_parse_table, 10, "SEECTL", + 0xbe, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEESTAT_parse_table[] = { + { "SEESTART", 0x01, 0x01 }, + { "SEEBUSY", 0x02, 0x02 }, + { "SEEARBACK", 0x04, 0x04 }, + { "LDALTID_L", 0x08, 0x08 }, + { "SEEOPCODE", 0x70, 0x70 }, + { "INIT_DONE", 0x80, 0x80 } +}; + +int +ahd_seestat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEESTAT_parse_table, 6, "SEESTAT", + 0xbe, regvalue, cur_col, wrap)); +} + +int +ahd_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBCNT", + 0xbf, regvalue, cur_col, wrap)); +} + +int +ahd_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFWADDR", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPFLTRCTL_parse_table[] = { + { "DSPFCNTSEL", 0x0f, 0x0f }, + { "EDGESENSE", 0x10, 0x10 }, + { "FLTRDISABLE", 0x20, 0x20 } +}; + +int +ahd_dspfltrctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPFLTRCTL_parse_table, 3, "DSPFLTRCTL", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPDATACTL_parse_table[] = { + { "XMITOFFSTDIS", 0x02, 0x02 }, + { "RCVROFFSTDIS", 0x04, 0x04 }, + { "DESQDIS", 0x10, 0x10 }, + { "BYPASSENAB", 0x80, 0x80 } +}; + +int +ahd_dspdatactl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPDATACTL_parse_table, 4, "DSPDATACTL", + 0xc1, regvalue, cur_col, wrap)); +} + +int +ahd_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFRADDR", + 0xc2, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPREQCTL_parse_table[] = { + { "MANREQDLY", 0x3f, 0x3f }, + { "MANREQCTL", 0xc0, 0xc0 } +}; + +int +ahd_dspreqctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPREQCTL_parse_table, 2, "DSPREQCTL", + 0xc2, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPACKCTL_parse_table[] = { + { "MANACKDLY", 0x3f, 0x3f }, + { "MANACKCTL", 0xc0, 0xc0 } +}; + +int +ahd_dspackctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPACKCTL_parse_table, 2, "DSPACKCTL", + 0xc3, regvalue, cur_col, wrap)); +} + +int +ahd_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFDAT", + 0xc4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPSELECT_parse_table[] = { + { "DSPSEL", 0x1f, 0x1f }, + { "AUTOINCEN", 0x80, 0x80 } +}; + +int +ahd_dspselect_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPSELECT_parse_table, 2, "DSPSELECT", + 0xc4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t WRTBIASCTL_parse_table[] = { + { "XMITMANVAL", 0x3f, 0x3f }, + { "AUTOXBCDIS", 0x80, 0x80 } +}; + +int +ahd_wrtbiasctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(WRTBIASCTL_parse_table, 2, "WRTBIASCTL", + 0xc5, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t RCVRBIOSCTL_parse_table[] = { + { "RCVRMANVAL", 0x3f, 0x3f }, + { "AUTORBCDIS", 0x80, 0x80 } +}; + +int +ahd_rcvrbiosctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(RCVRBIOSCTL_parse_table, 2, "RCVRBIOSCTL", + 0xc6, regvalue, cur_col, wrap)); +} + +int +ahd_wrtbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WRTBIASCALC", + 0xc7, regvalue, cur_col, wrap)); +} + +int +ahd_dfptrs_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFPTRS", + 0xc8, regvalue, cur_col, wrap)); +} + +int +ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "RCVRBIASCALC", + 0xc8, regvalue, cur_col, wrap)); +} + +int +ahd_dfbkptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFBKPTR", + 0xc9, regvalue, cur_col, wrap)); +} + +int +ahd_skewcalc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SKEWCALC", + 0xc9, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFDBCTL_parse_table[] = { + { "DFF_RAMBIST_EN", 0x01, 0x01 }, + { "DFF_RAMBIST_DONE", 0x02, 0x02 }, + { "DFF_RAMBIST_FAIL", 0x04, 0x04 }, + { "DFF_DIR_ERR", 0x08, 0x08 }, + { "DFF_CIO_RD_RDY", 0x10, 0x10 }, + { "DFF_CIO_WR_RDY", 0x20, 0x20 } +}; + +int +ahd_dfdbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFDBCTL_parse_table, 6, "DFDBCTL", + 0xcb, regvalue, cur_col, wrap)); +} + +int +ahd_dfscnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFSCNT", + 0xcc, regvalue, cur_col, wrap)); +} + +int +ahd_dfbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFBCNT", + 0xce, regvalue, cur_col, wrap)); +} + +int +ahd_ovlyaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OVLYADDR", + 0xd4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQCTL0_parse_table[] = { + { "LOADRAM", 0x01, 0x01 }, + { "SEQRESET", 0x02, 0x02 }, + { "STEP", 0x04, 0x04 }, + { "BRKADRINTEN", 0x08, 0x08 }, + { "FASTMODE", 0x10, 0x10 }, + { "FAILDIS", 0x20, 0x20 }, + { "PAUSEDIS", 0x40, 0x40 }, + { "PERRORDIS", 0x80, 0x80 } +}; + +int +ahd_seqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQCTL0_parse_table, 8, "SEQCTL0", + 0xd6, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQCTL1_parse_table[] = { + { "RAMBIST_EN", 0x01, 0x01 }, + { "RAMBIST_FAIL", 0x02, 0x02 }, + { "RAMBIST_DONE", 0x04, 0x04 }, + { "OVRLAY_DATA_CHK", 0x08, 0x08 } +}; + +int +ahd_seqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQCTL1_parse_table, 4, "SEQCTL1", + 0xd7, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t FLAGS_parse_table[] = { + { "CARRY", 0x01, 0x01 }, + { "ZERO", 0x02, 0x02 } +}; + +int +ahd_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(FLAGS_parse_table, 2, "FLAGS", + 0xd8, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTCTL_parse_table[] = { + { "IRET", 0x01, 0x01 }, + { "INTMASK1", 0x02, 0x02 }, + { "INTMASK2", 0x04, 0x04 }, + { "SCS_SEQ_INT1M0", 0x08, 0x08 }, + { "SCS_SEQ_INT1M1", 0x10, 0x10 }, + { "INT1_CONTEXT", 0x20, 0x20 }, + { "INTVEC1DSL", 0x80, 0x80 } +}; + +int +ahd_seqintctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTCTL_parse_table, 7, "SEQINTCTL", + 0xd9, regvalue, cur_col, wrap)); +} + +int +ahd_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SEQRAM", + 0xda, regvalue, cur_col, wrap)); +} + +int +ahd_prgmcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PRGMCNT", + 0xde, regvalue, cur_col, wrap)); +} + +int +ahd_accum_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ACCUM", + 0xe0, regvalue, cur_col, wrap)); +} + +int +ahd_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SINDEX", + 0xe2, regvalue, cur_col, wrap)); +} + +int +ahd_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DINDEX", + 0xe4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t BRKADDR1_parse_table[] = { + { "BRKDIS", 0x80, 0x80 } +}; + +int +ahd_brkaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(BRKADDR1_parse_table, 1, "BRKADDR1", + 0xe6, regvalue, cur_col, wrap)); +} + +int +ahd_brkaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BRKADDR0", + 0xe6, regvalue, cur_col, wrap)); +} + +int +ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ALLONES", + 0xe8, regvalue, cur_col, wrap)); +} + +int +ahd_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ALLZEROS", + 0xea, regvalue, cur_col, wrap)); +} + +int +ahd_none_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NONE", + 0xea, regvalue, cur_col, wrap)); +} + +int +ahd_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SINDIR", + 0xec, regvalue, cur_col, wrap)); +} + +int +ahd_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DINDIR", + 0xed, regvalue, cur_col, wrap)); +} + +int +ahd_function1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FUNCTION1", + 0xf0, regvalue, cur_col, wrap)); +} + +int +ahd_stack_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "STACK", + 0xf2, regvalue, cur_col, wrap)); +} + +int +ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CURADDR", + 0xf4, regvalue, cur_col, wrap)); +} + +int +ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INTVEC1_ADDR", + 0xf4, regvalue, cur_col, wrap)); +} + +int +ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INTVEC2_ADDR", + 0xf6, regvalue, cur_col, wrap)); +} + +int +ahd_lastaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LASTADDR", + 0xf6, regvalue, cur_col, wrap)); +} + +int +ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LONGJMP_ADDR", + 0xf8, regvalue, cur_col, wrap)); +} + +int +ahd_longjmp_scb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LONGJMP_SCB", + 0xfa, regvalue, cur_col, wrap)); +} + +int +ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ACCUM_SAVE", + 0xfc, regvalue, cur_col, wrap)); +} + +int +ahd_waiting_scb_tails_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", + 0x100, regvalue, cur_col, wrap)); +} + +int +ahd_ahd_pci_config_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", + 0x100, regvalue, cur_col, wrap)); +} + +int +ahd_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SRAM_BASE", + 0x100, regvalue, cur_col, wrap)); +} + +int +ahd_waiting_tid_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WAITING_TID_HEAD", + 0x120, regvalue, cur_col, wrap)); +} + +int +ahd_waiting_tid_tail_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WAITING_TID_TAIL", + 0x122, regvalue, cur_col, wrap)); +} + +int +ahd_next_queued_scb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", + 0x124, regvalue, cur_col, wrap)); +} + +int +ahd_complete_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", + 0x128, regvalue, cur_col, wrap)); +} + +int +ahd_complete_scb_dmainprog_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", + 0x12a, regvalue, cur_col, wrap)); +} + +int +ahd_complete_dma_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", + 0x12c, regvalue, cur_col, wrap)); +} + +int +ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QFREEZE_COUNT", + 0x12e, regvalue, cur_col, wrap)); +} + +int +ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SAVED_MODE", + 0x130, regvalue, cur_col, wrap)); +} + +int +ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MSG_OUT", + 0x131, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = { + { "FIFORESET", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SDMAEN", 0x10, 0x10 }, + { "SDMAENACK", 0x10, 0x10 }, + { "SCSIEN", 0x20, 0x20 }, + { "WIDEODD", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS", + 0x132, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = { + { "NO_DISCONNECT", 0x01, 0x01 }, + { "SPHASE_PENDING", 0x02, 0x02 }, + { "DPHASE_PENDING", 0x04, 0x04 }, + { "CMDPHASE_PENDING", 0x08, 0x08 }, + { "TARG_CMD_PENDING", 0x10, 0x10 }, + { "DPHASE", 0x20, 0x20 }, + { "NO_CDB_SENT", 0x40, 0x40 }, + { "TARGET_CMD_IS_TAGGED",0x40, 0x40 }, + { "NOT_IDENTIFIED", 0x80, 0x80 } +}; + +int +ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS", + 0x133, regvalue, cur_col, wrap)); +} + +int +ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SAVED_SCSIID", + 0x134, regvalue, cur_col, wrap)); +} + +int +ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SAVED_LUN", + 0x135, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LASTPHASE_parse_table[] = { + { "P_DATAOUT", 0x00, 0xe0 }, + { "P_DATAOUT_DT", 0x20, 0xe0 }, + { "P_DATAIN", 0x40, 0xe0 }, + { "P_DATAIN_DT", 0x60, 0xe0 }, + { "P_COMMAND", 0x80, 0xe0 }, + { "P_MESGOUT", 0xa0, 0xe0 }, + { "P_STATUS", 0xc0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 }, + { "P_BUSFREE", 0x01, 0x01 }, + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "PHASE_MASK", 0xe0, 0xe0 } +}; + +int +ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE", + 0x136, regvalue, cur_col, wrap)); +} + +int +ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", + 0x137, regvalue, cur_col, wrap)); +} + +int +ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", + 0x138, regvalue, cur_col, wrap)); +} + +int +ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", + 0x13c, regvalue, cur_col, wrap)); +} + +int +ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS", + 0x140, regvalue, cur_col, wrap)); +} + +int +ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TQINPOS", + 0x141, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ARG_1_parse_table[] = { + { "CONT_MSG_LOOP_TARG", 0x02, 0x02 }, + { "CONT_MSG_LOOP_READ", 0x03, 0x03 }, + { "CONT_MSG_LOOP_WRITE",0x04, 0x04 }, + { "EXIT_MSG_LOOP", 0x08, 0x08 }, + { "MSGOUT_PHASEMIS", 0x10, 0x10 }, + { "SEND_REJ", 0x20, 0x20 }, + { "SEND_SENSE", 0x40, 0x40 }, + { "SEND_MSG", 0x80, 0x80 } +}; + +int +ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1", + 0x142, regvalue, cur_col, wrap)); +} + +int +ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ARG_2", + 0x143, regvalue, cur_col, wrap)); +} + +int +ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LAST_MSG", + 0x144, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = { + { "ALTSTIM", 0x01, 0x01 }, + { "ENAUTOATNP", 0x02, 0x02 }, + { "MANUALP", 0x0c, 0x0c }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "MANUALCTL", 0x40, 0x40 } +}; + +int +ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE", + 0x145, regvalue, cur_col, wrap)); +} + +int +ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INITIATOR_TAG", + 0x146, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { + { "TARGET_MSG_PENDING", 0x02, 0x02 }, + { "SELECTOUT_QFROZEN", 0x04, 0x04 } +}; + +int +ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2", + 0x147, regvalue, cur_col, wrap)); +} + +int +ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", + 0x148, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalessing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESSING_TIMER", + 0x14a, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalessing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS", + 0x14c, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalessing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS", + 0x14d, regvalue, cur_col, wrap)); +} + +int +ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDS_PENDING", + 0x14e, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalessing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT", + 0x150, regvalue, cur_col, wrap)); +} + +int +ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", + 0x151, regvalue, cur_col, wrap)); +} + +int +ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE", + 0x152, regvalue, cur_col, wrap)); +} + +int +ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_BASE", + 0x180, regvalue, cur_col, wrap)); +} + +int +ahd_scb_residual_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", + 0x180, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_RESIDUAL_SGPTR_parse_table[] = { + { "SG_LIST_NULL", 0x01, 0x01 }, + { "SG_OVERRUN_RESID", 0x02, 0x02 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahd_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_RESIDUAL_SGPTR_parse_table, 3, "SCB_RESIDUAL_SGPTR", + 0x184, regvalue, cur_col, wrap)); +} + +int +ahd_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", + 0x188, regvalue, cur_col, wrap)); +} + +int +ahd_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", + 0x189, regvalue, cur_col, wrap)); +} + +int +ahd_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", + 0x18a, regvalue, cur_col, wrap)); +} + +int +ahd_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", + 0x18b, regvalue, cur_col, wrap)); +} + +int +ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", + 0x18c, regvalue, cur_col, wrap)); +} + +int +ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TAG", + 0x190, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = { + { "SCB_CDB_LEN_PTR", 0x80, 0x80 } +}; + +int +ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN", + 0x192, regvalue, cur_col, wrap)); +} + +int +ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", + 0x193, regvalue, cur_col, wrap)); +} + +int +ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_NEXT", + 0x194, regvalue, cur_col, wrap)); +} + +int +ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_NEXT2", + 0x196, regvalue, cur_col, wrap)); +} + +int +ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_DATAPTR", + 0x198, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = { + { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f }, + { "SG_LAST_SEG", 0x80, 0x80 } +}; + +int +ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT", + 0x1a0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = { + { "SG_LIST_NULL", 0x01, 0x01 }, + { "SG_FULL_RESID", 0x02, 0x02 }, + { "SG_STATUS_VALID", 0x04, 0x04 } +}; + +int +ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR", + 0x1a4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = { + { "SCB_TAG_TYPE", 0x03, 0x03 }, + { "DISCONNECTED", 0x04, 0x04 }, + { "STATUS_RCVD", 0x08, 0x08 }, + { "MK_MESSAGE", 0x10, 0x10 }, + { "TAG_ENB", 0x20, 0x20 }, + { "DISCENB", 0x40, 0x40 }, + { "TARGET_SCB", 0x80, 0x80 } +}; + +int +ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL", + 0x1a8, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = { + { "OID", 0x0f, 0x0f }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID", + 0x1a9, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = { + { "LID", 0xff, 0xff } +}; + +int +ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN", + 0x1aa, regvalue, cur_col, wrap)); +} + +int +ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", + 0x1ab, regvalue, cur_col, wrap)); +} + +int +ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_BUSADDR", + 0x1ac, regvalue, cur_col, wrap)); +} + +int +ahd_scb_spare_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_SPARE", + 0x1b0, regvalue, cur_col, wrap)); +} + +int +ahd_scb_disconnected_lists_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", + 0x1b8, regvalue, cur_col, wrap)); +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx.seq linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx.seq --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx.seq 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx.seq 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,1889 @@ +/* + * Adaptec U320 device driver firmware for Linux and FreeBSD. + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $" +PATCH_ARG_LIST = "struct ahd_softc *ahd" +PREFIX = "ahd_" + +#include "aic79xx.reg" +#include "scsi_message.h" + +restart: +if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + test SEQINTCODE, 0xFF jz idle_loop; + SET_SEQINTCODE(NO_SEQINT) +} + +idle_loop: + + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + /* + * Convert ERROR status into a sequencer + * interrupt to handle the case of an + * interrupt collision on the hardware + * setting of HWERR. + */ + test ERROR, 0xFF jz no_error_set; + SET_SEQINTCODE(SAW_HWERR) +no_error_set: + } + SET_MODE(M_SCSI, M_SCSI) + test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus; + test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus; + cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus; + /* + * ENSELO is cleared by a SELDO, so we must test for SELDO + * one last time. + */ +BEGIN_CRITICAL; + test SSTAT0, SELDO jnz select_out; +END_CRITICAL; + call start_selection; +idle_loop_checkbus: +BEGIN_CRITICAL; + test SSTAT0, SELDO jnz select_out; +END_CRITICAL; + test SSTAT0, SELDI jnz select_in; + test SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq; + test SCSISIGO, ATNO jz idle_loop_check_nonpackreq; + call unexpected_nonpkt_phase_find_ctxt; +idle_loop_check_nonpackreq: + test SSTAT2, NONPACKREQ jz . + 2; + call unexpected_nonpkt_phase_find_ctxt; + call idle_loop_gsfifo_in_scsi_mode; + call idle_loop_service_fifos; + call idle_loop_cchan; + jmp idle_loop; + +BEGIN_CRITICAL; +idle_loop_gsfifo: + SET_MODE(M_SCSI, M_SCSI) +idle_loop_gsfifo_in_scsi_mode: + test LQISTAT2, LQIGSAVAIL jz return; + /* + * We have received good status for this transaction. There may + * still be data in our FIFOs draining to the host. Setup + * monitoring of the draining process or complete the SCB. + */ +good_status_IU_done: + bmov SCBPTR, GSFIFO, 2; + clr SCB_SCSI_STATUS; + /* + * If a command completed before an attempted task management + * function completed, notify the host after disabling any + * pending select-outs. + */ + test SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally; + test SSTAT0, SELDO|SELINGO jnz . + 2; + and SCSISEQ0, ~ENSELO; + SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) +gsfifo_complete_normally: + or SCB_CONTROL, STATUS_RCVD; + + /* + * Since this status did not consume a FIFO, we have to + * be a bit more dilligent in how we check for FIFOs pertaining + * to this transaction. There are three states that a FIFO still + * transferring data may be in. + * + * 1) Configured and draining to the host, with a pending CLRCHN. + * 2) Configured and draining to the host, no pending CLRCHN. + * 3) Pending cfg4data, fifo not empty. + * + * Cases 1 and 2 can be detected by noticing that a longjmp is + * active for the FIFO and LONGJMP_SCB matches our SCB. In this + * case, we allow the routine servicing the FIFO to complete the SCB. + * + * Case 3 implies either a pending or yet to occur save data + * pointers for this same context in the other FIFO. So, if + * we detect case 2, we will properly defer the post of the SCB + * and achieve the desired result. The pending cfg4data will + * notice that status has been received and complete the SCB. + */ + test SCB_SGPTR, SG_LIST_NULL jz good_status_check_fifos; + /* + * All segments have been loaded (or no data transfer), so + * it is safe to complete the command. Since this was a + * cheap command to check for completion, loop to see if + * more entries can be removed from the GSFIFO. + */ + call complete; +END_CRITICAL; + jmp idle_loop_gsfifo_in_scsi_mode; +BEGIN_CRITICAL; +good_status_check_fifos: + clc; + bmov ARG_1, SCBPTR, 2; + SET_MODE(M_DFF0, M_DFF0) + call check_fifo; + jc return; + SET_MODE(M_DFF1, M_DFF1) + call check_fifo; + jc return; + SET_MODE(M_SCSI, M_SCSI) + jmp queue_scb_completion; +END_CRITICAL; + +idle_loop_service_fifos: + SET_MODE(M_DFF0, M_DFF0) + test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo; + call longjmp; +idle_loop_next_fifo: + SET_MODE(M_DFF1, M_DFF1) + test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp; + ret; + +idle_loop_cchan: + SET_MODE(M_CCHAN, M_CCHAN) + test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty; + mov LOCAL_HS_MAILBOX, HS_MAILBOX; + or QOFF_CTLSTA, HS_MAILBOX_ACT; +hs_mailbox_empty: +BEGIN_CRITICAL; + test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle; + test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog; + test CCSCBCTL, CCSCBDONE jz return; +END_CRITICAL; + /* FALLTHROUGH */ +scbdma_tohost_done: + test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone; + /* + * A complete SCB upload requires no intervention. + * The SCB is already on the COMPLETE_SCB list + * and its completion notification will now be + * handled just like any other SCB. + */ + and CCSCBCTL, ~(CCARREN|CCSCBEN) ret; +fill_qoutfifo_dmadone: + and CCSCBCTL, ~(CCARREN|CCSCBEN); + call qoutfifo_updated; + mvi COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL; + bmov QOUTFIFO_NEXT_ADDR, SCBHADDR, 4; + test QOFF_CTLSTA, SDSCB_ROLLOVR jz return; + bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4; + xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret; + +qoutfifo_updated: + /* + * If there are more commands waiting to be dma'ed + * to the host, always coaless. Otherwise honor the + * host's wishes. + */ + cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count; + cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count; + test LOCAL_HS_MAILBOX, ENINT_COALESS jz issue_cmdcmplt; + + /* + * If we have relatively few commands outstanding, don't + * bother waiting for another command to complete. + */ + test CMDS_PENDING[1], 0xFF jnz coaless_by_count; + /* Add -1 so that jnc means <= not just < */ + add A, -1, INT_COALESSING_MINCMDS; + add NONE, A, CMDS_PENDING; + jnc issue_cmdcmplt; + + /* + * If coalessing, only coaless up to the limit + * provided by the host driver. + */ +coaless_by_count: + mov A, INT_COALESSING_MAXCMDS; + add NONE, A, INT_COALESSING_CMDCOUNT; + jc issue_cmdcmplt; + /* + * If the timer is not currently active, + * fire it up. + */ + test INTCTL, SWTMINTMASK jz return; + bmov SWTIMER, INT_COALESSING_TIMER, 2; + mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; + or INTCTL, SWTMINTEN|SWTIMER_START; + and INTCTL, ~SWTMINTMASK ret; + +issue_cmdcmplt: + mvi INTSTAT, CMDCMPLT; + clr INT_COALESSING_CMDCOUNT; + or INTCTL, SWTMINTMASK ret; + +BEGIN_CRITICAL; +fetch_new_scb_inprog: + test CCSCBCTL, ARRDONE jz return; +fetch_new_scb_done: + and CCSCBCTL, ~(CCARREN|CCSCBEN); + bmov REG0, SCBPTR, 2; + clr A; + add CMDS_PENDING, 1; + adc CMDS_PENDING[1], A; + /* Update the next SCB address to download. */ + bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4; + mvi SCB_NEXT[1], SCB_LIST_NULL; + mvi SCB_NEXT2[1], SCB_LIST_NULL; + /* Increment our position in the QINFIFO. */ + mov NONE, SNSCB_QOFF; + /* + * SCBs that want to send messages are always + * queued independently. This ensures that they + * are at the head of the SCB list to select out + * to a target and we will see the MK_MESSAGE flag. + */ + test SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb; + shr SINDEX, 3, SCB_SCSIID; + and SINDEX, ~0x1; + mvi SINDEX[1], (WAITING_SCB_TAILS >> 8); + bmov DINDEX, SINDEX, 2; + bmov SCBPTR, SINDIR, 2; + bmov DINDIR, REG0, 2; + cmp SCBPTR[1], SCB_LIST_NULL je first_new_target_scb; + bmov SCB_NEXT, REG0, 2 ret; +first_new_target_scb: + cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb; + bmov SCBPTR, WAITING_TID_TAIL, 2; + bmov SCB_NEXT2, REG0, 2; + bmov WAITING_TID_TAIL, REG0, 2 ret; +first_new_scb: + bmov WAITING_TID_HEAD, REG0, 2; + bmov WAITING_TID_TAIL, REG0, 2 ret; +END_CRITICAL; + +scbdma_idle: + /* + * Give precedence to downloading new SCBs to execute + * unless select-outs are currently frozen. + */ + test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2; +BEGIN_CRITICAL; + test QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb; + cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb; + cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return; + /* FALLTHROUGH */ +fill_qoutfifo: + /* + * Keep track of the SCBs we are dmaing just + * in case the DMA fails or is aborted. + */ + mov A, QOUTFIFO_ENTRY_VALID_TAG; + bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2; + mvi CCSCBCTL, CCSCBRESET; + bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4; + bmov SCBPTR, COMPLETE_SCB_HEAD, 2; +fill_qoutfifo_loop: + mov CCSCBRAM, SCBPTR; + or CCSCBRAM, A, SCBPTR[1]; + mov NONE, SDSCB_QOFF; + inc INT_COALESSING_CMDCOUNT; + add CMDS_PENDING, -1; + adc CMDS_PENDING[1], -1; + cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done; + cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done; + test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done; + bmov SCBPTR, SCB_NEXT_COMPLETE, 2; + jmp fill_qoutfifo_loop; +fill_qoutfifo_done: + mov SCBHCNT, CCSCBADDR; + mvi CCSCBCTL, CCSCBEN|CCSCBRESET; + bmov COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2; + mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret; + +fetch_new_scb: + bmov SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4; + mvi CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb; +dma_complete_scb: + bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2; + bmov SCBHADDR, SCB_BUSADDR, 4; + mvi CCARREN|CCSCBEN|CCSCBRESET call dma_scb; + /* + * Now that we've started the DMA, push us onto + * the normal completion queue to have our SCBID + * posted to the kernel. + */ + bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; + bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; + bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; +END_CRITICAL; + +/* + * Either post or fetch an SCB from host memory. The caller + * is responsible for polling for transfer completion. + * + * Prerequisits: Mode == M_CCHAN + * SINDEX contains CCSCBCTL flags + * SCBHADDR set to Host SCB address + * SCBPTR set to SCB src location on "push" operations + */ +SET_SRC_MODE M_CCHAN; +SET_DST_MODE M_CCHAN; +dma_scb: + mvi SCBHCNT, SCB_TRANSFER_SIZE; + mov CCSCBCTL, SINDEX ret; + +BEGIN_CRITICAL; +setjmp_setscb: + bmov LONGJMP_SCB, SCBPTR, 2; +setjmp: + bmov LONGJMP_ADDR, STACK, 2 ret; +setjmp_inline: + bmov LONGJMP_ADDR, STACK, 2; +longjmp: + bmov STACK, LONGJMP_ADDR, 2 ret; +END_CRITICAL; + +/*************************** Chip Bug Work Arounds ****************************/ +/* + * Must disable interrupts when setting the mode pointer + * register as an interrupt occurring mid update will + * fail to store the new mode value for restoration on + * an iret. + */ +if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { +set_mode_work_around: + mvi SEQINTCTL, INTVEC1DSL; + mov MODE_PTR, SINDEX; + clr SEQINTCTL ret; + +toggle_dff_mode_work_around: + mvi SEQINTCTL, INTVEC1DSL; + xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); + clr SEQINTCTL ret; +} + + +if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { +set_seqint_work_around: + mov SEQINTCODE, SINDEX; + mvi SEQINTCODE, NO_SEQINT ret; +} + +/************************ Packetized LongJmp Routines *************************/ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +start_selection: +BEGIN_CRITICAL; + if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { + /* + * Razor #494 + * Rev A hardware fails to update LAST/CURR/NEXTSCB + * correctly after a packetized selection in several + * situations: + * + * 1) If only one command existed in the queue, the + * LAST/CURR/NEXTSCB are unchanged. + * + * 2) In a non QAS, protocol allowed phase change, + * the queue is shifted 1 too far. LASTSCB is + * the last SCB that was correctly processed. + * + * 3) In the QAS case, if the full list of commands + * was successfully sent, NEXTSCB is NULL and neither + * CURRSCB nor LASTSCB can be trusted. We must + * manually walk the list counting MAXCMDCNT elements + * to find the last SCB that was sent correctly. + * + * To simplify the workaround for this bug in SELDO + * handling, we initialize LASTSCB prior to enabling + * selection so we can rely on it even for case #1 above. + */ + bmov LASTSCB, WAITING_TID_HEAD, 2; + } + bmov CURRSCB, WAITING_TID_HEAD, 2; + bmov SCBPTR, WAITING_TID_HEAD, 2; + shr SELOID, 4, SCB_SCSIID; + /* + * If we want to send a message to the device, ensure + * we are selecting with atn irregardless of our packetized + * agreement. Since SPI4 only allows target reset or PPR + * messages if this is a packetized connection, the change + * to our negotiation table entry for this selection will + * be cleared when the message is acted on. + */ + test SCB_CONTROL, MK_MESSAGE jz . + 3; + mov NEGOADDR, SELOID; + or NEGCONOPTS, ENAUTOATNO; + or SCSISEQ0, ENSELO ret; +END_CRITICAL; + +/* + * Allocate a FIFO for a non-packetized transaction. + * In RevA hardware, both FIFOs must be free before we + * can allocate a FIFO for a non-packetized transaction. + */ +allocate_fifo_loop: + /* + * Do whatever work is required to free a FIFO. + */ + call idle_loop_service_fifos; + SET_MODE(M_SCSI, M_SCSI) +allocate_fifo: + if ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0) { + and A, FIFO0FREE|FIFO1FREE, DFFSTAT; + cmp A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop; + } else { + test DFFSTAT, FIFO1FREE jnz allocate_fifo1; + test DFFSTAT, FIFO0FREE jz allocate_fifo_loop; + mvi DFFSTAT, B_CURRFIFO_0; + SET_MODE(M_DFF0, M_DFF0) + bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; + } +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +allocate_fifo1: + mvi DFFSTAT, CURRFIFO_1; + SET_MODE(M_DFF1, M_DFF1) + bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; + +/* + * We have been reselected as an initiator + * or selected as a target. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +select_in: + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + /* + * This exposes a window whereby a + * busfree just after a selection will + * be missed, but there is no other safe + * way to enable busfree detection if + * the busfreerev function is broken. + */ + mvi CLRSINT1,CLRBUSFREE; + or SIMODE1, ENBUSFREE; + } + or SXFRCTL0, SPIOEN; + and SAVED_SCSIID, SELID_MASK, SELID; + and A, OID, IOWNID; + or SAVED_SCSIID, A; + mvi CLRSINT0, CLRSELDI; + jmp ITloop; + +/* + * We have successfully selected out. + * + * Clear SELDO. + * Dequeue all SCBs sent from the waiting queue + * Requeue all SCBs *not* sent to the tail of the waiting queue + * Take Razor #494 into account for above. + * + * In Packetized Mode: + * Return to the idle loop. Our interrupt handler will take + * care of any incoming L_Qs. + * + * In Non-Packetize Mode: + * Continue to our normal state machine. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +select_out: +BEGIN_CRITICAL; + /* Clear out all SCBs that have been successfully sent. */ + if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { + /* + * For packetized, the LQO manager clears ENSELO on + * the assertion of SELDO. If we are non-packetized, + * LASTSCB and CURRSCB are acuate. + */ + test SCSISEQ0, ENSELO jnz use_lastscb; + + /* + * The update is correct for LQOSTAT1 errors. All + * but LQOBUSFREE are handled by kernel interrupts. + * If we see LQOBUSFREE, return to the idle loop. + * Once we are out of the select_out critical section, + * the kernel will cleanup the LQOBUSFREE and we will + * eventually restart the selection if appropriate. + */ + test LQOSTAT1, LQOBUSFREE jnz idle_loop; + + /* + * On a phase change oustside of packet boundaries, + * LASTSCB points to the currently active SCB context + * on the bus. + */ + test LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb; + + /* + * If the hardware has traversed the whole list, NEXTSCB + * will be NULL, CURRSCB and LASTSCB cannot be trusted, + * but MAXCMDCNT is accurate. If we stop part way through + * the list or only had one command to issue, NEXTSCB[1] is + * not NULL and LASTSCB is the last command to go out. + */ + cmp NEXTSCB[1], SCB_LIST_NULL jne use_lastscb; + + /* + * Brute force walk. + */ + bmov SCBPTR, WAITING_TID_HEAD, 2; + mvi SEQINTCTL, INTVEC1DSL; + mvi MODE_PTR, MK_MODE(M_CFG, M_CFG); + mov A, MAXCMDCNT; + mvi MODE_PTR, MK_MODE(M_SCSI, M_SCSI); + clr SEQINTCTL; +find_lastscb_loop: + dec A; + test A, 0xFF jz found_last_sent_scb; + bmov SCBPTR, SCB_NEXT, 2; + jmp find_lastscb_loop; +use_lastscb: + bmov SCBPTR, LASTSCB, 2; +found_last_sent_scb: + bmov CURRSCB, SCBPTR, 2; +curscb_ww_done: + } else { + /* + * Untested - Verify with Rev B. + */ + bmov SCBPTR, CURRSCB, 2; + } + + /* + * Requeue any SCBs not sent, to the tail of the waiting Q. + */ + cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done; + + /* + * We know that neither the per-TID list nor the list of + * TIDs is empty. Use this knowledge to our advantage. + */ + bmov REG0, SCB_NEXT, 2; + bmov SCBPTR, WAITING_TID_TAIL, 2; + bmov SCB_NEXT2, REG0, 2; + bmov WAITING_TID_TAIL, REG0, 2; + jmp select_out_inc_tid_q; + +select_out_list_done: + /* + * The whole list made it. Just clear our TID's tail pointer + * unless we were queued independently due to our need to + * send a message. + */ + test SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q; + shr DINDEX, 3, SCB_SCSIID; + or DINDEX, 1; /* Want only the second byte */ + mvi DINDEX[1], ((WAITING_SCB_TAILS) >> 8); + mvi DINDIR, SCB_LIST_NULL; +select_out_inc_tid_q: + bmov SCBPTR, WAITING_TID_HEAD, 2; + bmov WAITING_TID_HEAD, SCB_NEXT2, 2; + cmp WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2; + mvi WAITING_TID_TAIL[1], SCB_LIST_NULL; + bmov SCBPTR, CURRSCB, 2; + mvi CLRSINT0, CLRSELDO; + test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase; + test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase; + + /* + * If this is a packetized connection, return to our + * idle_loop and let our interrupt handler deal with + * any connection setup/teardown issues. The only + * exceptions are the case of MK_MESSAGE and task management + * SCBs. + */ + if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) { + /* + * In the A, the LQO manager transitions to LQOSTOP0 even if + * we have selected out with ATN asserted and the target + * REQs in a non-packet phase. + */ + test SCB_CONTROL, MK_MESSAGE jz select_out_no_message; + test SCSISIGO, ATNO jnz select_out_non_packetized; +select_out_no_message: + } + test LQOSTAT2, LQOSTOP0 jz select_out_non_packetized; + test SCB_TASK_MANAGEMENT, 0xFF jz idle_loop; + SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE) + jmp idle_loop; + +select_out_non_packetized: + /* Non packetized request. */ + and SCSISEQ0, ~ENSELO; + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + /* + * This exposes a window whereby a + * busfree just after a selection will + * be missed, but there is no other safe + * way to enable busfree detection if + * the busfreerev function is broken. + */ + mvi CLRSINT1,CLRBUSFREE; + or SIMODE1, ENBUSFREE; + } + mov SAVED_SCSIID, SCB_SCSIID; + mov SAVED_LUN, SCB_LUN; + mvi SEQ_FLAGS, NO_CDB_SENT; +END_CRITICAL; + or SXFRCTL0, SPIOEN; + + /* + * As soon as we get a successful selection, the target + * should go into the message out phase since we have ATN + * asserted. + */ + mvi MSG_OUT, MSG_IDENTIFYFLAG; + + /* + * Main loop for information transfer phases. Wait for the + * target to assert REQ before checking MSG, C/D and I/O for + * the bus phase. + */ +mesgin_phasemis: +ITloop: + call phase_lock; + + mov A, LASTPHASE; + + test A, ~P_DATAIN_DT jz p_data; + cmp A,P_COMMAND je p_command; + cmp A,P_MESGOUT je p_mesgout; + cmp A,P_STATUS je p_status; + cmp A,P_MESGIN je p_mesgin; + + SET_SEQINTCODE(BAD_PHASE) + jmp ITloop; /* Try reading the bus again. */ + +/* + * Command phase. Set up the DMA registers and let 'er rip. + */ +p_command: + test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; + SET_SEQINTCODE(PROTO_VIOLATION) +p_command_okay: + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) + jnz p_command_allocate_fifo; + /* + * Command retry. Free our current FIFO and + * re-allocate a FIFO so transfer state is + * reset. + */ +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; + SET_MODE(M_SCSI, M_SCSI) +p_command_allocate_fifo: + bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; + call allocate_fifo; +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + add NONE, -17, SCB_CDB_LEN; + jnc p_command_embedded; +p_command_from_host: + bmov HADDR[0], SCB_CDB_PTR, 11; + mvi SG_CACHE_PRE, LAST_SEG; + mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); + jmp p_command_xfer; +p_command_embedded: + bmov SHCNT[0], SCB_CDB_LEN, 1; + bmov DFDAT, SCB_CDB_STORE, 16; + mvi DFCNTRL, SCSIEN; +p_command_xfer: + and SEQ_FLAGS, ~NO_CDB_SENT; + test DFCNTRL, SCSIEN jnz .; + /* + * DMA Channel automatically disabled. + * Don't allow a data phase if the command + * was not fully transferred. + */ + test SSTAT2, SDONE jnz ITloop; + or SEQ_FLAGS, NO_CDB_SENT; + jmp ITloop; + + +/* + * Status phase. Wait for the data byte to appear, then read it + * and store it into the SCB. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +p_status: + test SEQ_FLAGS,NOT_IDENTIFIED jnz mesgin_proto_violation; +p_status_okay: + mov SCB_SCSI_STATUS, SCSIDAT; + or SCB_CONTROL, STATUS_RCVD; + jmp ITloop; + +/* + * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full + * indentify message sequence and send it to the target. The host may + * override this behavior by setting the MK_MESSAGE bit in the SCB + * control byte. This will cause us to interrupt the host and allow + * it to handle the message phase completely on its own. If the bit + * associated with this target is set, we will also interrupt the host, + * thereby allowing it to send a message on the next selection regardless + * of the transaction being sent. + * + * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. + * This is done to allow the host to send messages outside of an identify + * sequence while protecting the seqencer from testing the MK_MESSAGE bit + * on an SCB that might not be for the current nexus. (For example, a + * BDR message in responce to a bad reselection would leave us pointed to + * an SCB that doesn't have anything to do with the current target). + * + * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, + * bus device reset). + * + * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, + * in case the target decides to put us in this phase for some strange + * reason. + */ +p_mesgout_retry: + /* Turn on ATN for the retry */ + mvi SCSISIGO, ATNO; +p_mesgout: + mov SINDEX, MSG_OUT; + cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; + test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; +p_mesgout_identify: + or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; + test SCB_CONTROL, DISCENB jnz . + 2; + and SINDEX, ~DISCENB; +/* + * Send a tag message if TAG_ENB is set in the SCB control block. + * Use SCB_NONPACKET_TAG as the tag value. + */ +p_mesgout_tag: + test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; + mov SCSIDAT, SINDEX; /* Send the identify message */ + call phase_lock; + cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; + and SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; + call phase_lock; + cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; + mov SCBPTR jmp p_mesgout_onebyte; +/* + * Interrupt the driver, and allow it to handle this message + * phase and any required retries. + */ +p_mesgout_from_host: + cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; + jmp host_message_loop; + +p_mesgout_onebyte: + mvi CLRSINT1, CLRATNO; + mov SCSIDAT, SINDEX; + +/* + * If the next bus phase after ATN drops is message out, it means + * that the target is requesting that the last message(s) be resent. + */ + call phase_lock; + cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; + +p_mesgout_done: + mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ + mov LAST_MSG, MSG_OUT; + mvi MSG_OUT, MSG_NOOP; /* No message left */ + jmp ITloop; + +/* + * Message in phase. Bytes are read using Automatic PIO mode. + */ +p_mesgin: + /* read the 1st message byte */ + mvi ACCUM call inb_first; + + test A,MSG_IDENTIFYFLAG jnz mesgin_identify; + cmp A,MSG_DISCONNECT je mesgin_disconnect; + cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; + cmp ALLZEROS,A je mesgin_complete; + cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; + cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue; + cmp A,MSG_NOOP je mesgin_done; + +/* + * Pushed message loop to allow the kernel to + * run it's own message state engine. To avoid an + * extra nop instruction after signaling the kernel, + * we perform the phase_lock before checking to see + * if we should exit the loop and skip the phase_lock + * in the ITloop. Performing back to back phase_locks + * shouldn't hurt, but why do it twice... + */ +host_message_loop: + call phase_lock; /* Benign the first time through. */ + SET_SEQINTCODE(HOST_MSG_LOOP) + cmp RETURN_1, EXIT_MSG_LOOP je ITloop; + cmp RETURN_1, CONT_MSG_LOOP_WRITE jne . + 3; + mov SCSIDAT, RETURN_2; + jmp host_message_loop; + /* Must be CONT_MSG_LOOP_READ */ + mov NONE, SCSIDAT; /* ACK Byte */ + jmp host_message_loop; + +mesgin_ign_wide_residue: + mov SAVED_MODE, MODE_PTR; + SET_MODE(M_SCSI, M_SCSI) + shr NEGOADDR, 4, SAVED_SCSIID; + mov A, NEGCONOPTS; + RESTORE_MODE(SAVED_MODE) + test A, WIDEXFER jz mesgin_reject; + /* Pull the residue byte */ + mvi REG0 call inb_next; + cmp REG0, 0x01 jne mesgin_reject; + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; + test DATA_COUNT_ODD, 0x1 jz mesgin_done; + jmp mesgin_done; + +mesgin_proto_violation: + SET_SEQINTCODE(PROTO_VIOLATION) + jmp mesgin_done; +mesgin_reject: + mvi MSG_MESSAGE_REJECT call mk_mesg; +mesgin_done: + mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ + jmp ITloop; + +#define INDEX_DISC_LIST(scsiid, lun) \ + and A, 0xC0, scsiid; \ + or SCBPTR, A, lun; \ + clr SCBPTR[1]; \ + and SINDEX, 0x30, scsiid; \ + shr SINDEX, 3; /* Multiply by 2 */ \ + add SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF); \ + mvi SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF) + +mesgin_identify: + /* + * Determine whether a target is using tagged or non-tagged + * transactions by first looking at the transaction stored in + * the per-device, disconnected array. If there is no untagged + * transaction for this target, this must be a tagged transaction. + */ + and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; + INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); + bmov DINDEX, SINDEX, 2; + bmov REG0, SINDIR, 2; + cmp REG0[1], SCB_LIST_NULL je snoop_tag; + /* Untagged. Clear the busy table entry and setup the SCB. */ + bmov DINDIR, ALLONES, 2; + bmov SCBPTR, REG0, 2; + jmp setup_SCB; + +/* + * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. + * If we get one, we use the tag returned to find the proper + * SCB. After receiving the tag, look for the SCB at SCB locations tag and + * tag + 256. + */ +snoop_tag: + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x80; + } + mov NONE, SCSIDAT; /* ACK Identify MSG */ + call phase_lock; + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x1; + } + cmp LASTPHASE, P_MESGIN jne not_found_ITloop; + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x2; + } + cmp SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found; +get_tag: + clr SCBPTR[1]; + mvi SCBPTR call inb_next; /* tag value */ +verify_scb: + test SCB_CONTROL,DISCONNECTED jz verify_other_scb; + mov A, SAVED_SCSIID; + cmp SCB_SCSIID, A jne verify_other_scb; + mov A, SAVED_LUN; + cmp SCB_LUN, A je setup_SCB_disconnected; +verify_other_scb: + xor SCBPTR[1], 1; + test SCBPTR[1], 0xFF jnz verify_scb; + jmp not_found; + +/* + * Ensure that the SCB the tag points to is for + * an SCB transaction to the reconnecting target. + */ +setup_SCB: + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x10; + } + test SCB_CONTROL,DISCONNECTED jz not_found; +setup_SCB_disconnected: + and SCB_CONTROL,~DISCONNECTED; + clr SEQ_FLAGS; /* make note of IDENTIFY */ + test SCB_SGPTR, SG_LIST_NULL jnz . + 3; + bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; + call allocate_fifo; + /* See if the host wants to send a message upon reconnection */ + test SCB_CONTROL, MK_MESSAGE jz mesgin_done; + mvi HOST_MSG call mk_mesg; + jmp mesgin_done; + +not_found: + SET_SEQINTCODE(NO_MATCH) + jmp mesgin_done; + +not_found_ITloop: + SET_SEQINTCODE(NO_MATCH) + jmp ITloop; + +/* + * We received a "command complete" message. Put the SCB on the complete + * queue and trigger a completion interrupt via the idle loop. Before doing + * so, check to see if there + * is a residual or the status byte is something other than STATUS_GOOD (0). + * In either of these conditions, we upload the SCB back to the host so it can + * process this information. In the case of a non zero status byte, we + * additionally interrupt the kernel driver synchronously, allowing it to + * decide if sense should be retrieved. If the kernel driver wishes to request + * sense, it will fill the kernel SCB with a request sense command, requeue + * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting + * RETURN_1 to SEND_SENSE. + */ +mesgin_complete: + + /* + * If ATN is raised, we still want to give the target a message. + * Perhaps there was a parity error on this last message byte. + * Either way, the target should take us to message out phase + * and then attempt to complete the command again. We should use a + * critical section here to guard against a timeout triggering + * for this command and setting ATN while we are still processing + * the completion. + test SCSISIGI, ATNI jnz mesgin_done; + */ + + /* + * If we are identified and have successfully sent the CDB, + * any status will do. Optimize this fast path. + */ + test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; + + /* + * If the target never sent an identify message but instead went + * to mesgin to give an invalid message, let the host abort us. + */ + test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; + + /* + * If we recevied good status but never successfully sent the + * cdb, abort the command. + */ + test SCB_SCSI_STATUS,0xff jnz complete_accepted; + test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; +complete_accepted: + + /* + * See if we attempted to deliver a message but the target ingnored us. + */ + test SCB_CONTROL, MK_MESSAGE jz complete_nomsg; + SET_SEQINTCODE(MKMSG_FAILED) +complete_nomsg: + call queue_scb_completion; + jmp await_busfree; + +freeze_queue: + /* Cancel any pending select-out. */ + test SSTAT0, SELDO|SELINGO jnz . + 2; + and SCSISEQ0, ~ENSELO; + mov ACCUM_SAVE, A; + clr A; + add QFREEZE_COUNT, 1; + adc QFREEZE_COUNT[1], A; + or SEQ_FLAGS2, SELECTOUT_QFROZEN; + mov A, ACCUM_SAVE ret; + +queue_arg1_scb_completion: + SET_MODE(M_SCSI, M_SCSI) + bmov SCBPTR, ARG_1, 2; +queue_scb_completion: + if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0) { + /* + * Set MK_MESSAGE to trigger an abort should this SCB + * be referenced by a target even though it is not currently + * active. + */ + or SCB_CONTROL, MK_MESSAGE; + } + test SCB_SCSI_STATUS,0xff jnz bad_status; + /* + * Check for residuals + */ + test SCB_SGPTR, SG_LIST_NULL jnz complete; /* No xfer */ + test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ + test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; +complete: + bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; + bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; +bad_status: + cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb; + call freeze_queue; +upload_scb: + bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2; + bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2; + or SCB_SGPTR, SG_STATUS_VALID ret; + +/* + * Is it a disconnect message? Set a flag in the SCB to remind us + * and await the bus going free. If this is an untagged transaction + * store the SCB id for it in our untagged target table for lookup on + * a reselction. + */ +mesgin_disconnect: + /* + * If ATN is raised, we still want to give the target a message. + * Perhaps there was a parity error on this last message byte + * or we want to abort this command. Either way, the target + * should take us to message out phase and then attempt to + * disconnect again. + * XXX - Wait for more testing. + test SCSISIGI, ATNI jnz mesgin_done; + */ + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT + jnz mesgin_proto_violation; + or SCB_CONTROL,DISCONNECTED; + test SCB_CONTROL, TAG_ENB jnz await_busfree; +queue_disc_scb: + bmov REG0, SCBPTR, 2; + INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); + bmov DINDEX, SINDEX, 2; + bmov DINDIR, REG0, 2; + bmov SCBPTR, REG0, 2; + /* FALLTHROUGH */ +await_busfree: + and SIMODE1, ~ENBUSFREE; + if ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0) { + /* + * In the BUSFREEREV_BUG case, the + * busfree status was cleared at the + * beginning of the connection. + */ + mvi CLRSINT1,CLRBUSFREE; + } + mov NONE, SCSIDAT; /* Ack the last byte */ + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) + jnz await_busfree_not_m_dff; +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +await_busfree_clrchn: + mvi DFFSXFRCTL, CLRCHN; +await_busfree_not_m_dff: + call clear_target_state; + test SSTAT1,REQINIT|BUSFREE jz .; + test SSTAT1, BUSFREE jnz idle_loop; + SET_SEQINTCODE(MISSED_BUSFREE) + + +/* + * Save data pointers message: + * Copying RAM values back to SCB, for Save Data Pointers message, but + * only if we've actually been into a data phase to change them. This + * protects against bogus data in scratch ram and the residual counts + * since they are only initialized when we go into data_in or data_out. + * Ack the message as soon as possible. + */ +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +mesgin_sdptrs: + mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ + test SEQ_FLAGS, DPHASE jz ITloop; + call save_pointers; + jmp ITloop; + +save_pointers: + /* + * If we are asked to save our position at the end of the + * transfer, just mark us at the end rather than perform a + * full save. + */ + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz save_pointers_full; + or SCB_SGPTR, SG_LIST_NULL ret; + +save_pointers_full: + /* + * The SCB_DATAPTR becomes the current SHADDR. + * All other information comes directly from our residual + * state. + */ + bmov SCB_DATAPTR, SHADDR, 8; + bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret; + +/* + * Restore pointers message? Data pointers are recopied from the + * SCB anytime we enter a data phase for the first time, so all + * we need to do is clear the DPHASE flag and let the data phase + * code do the rest. We also reset/reallocate the FIFO to make + * sure we have a clean start for the next data or command phase. + */ +mesgin_rdptrs: + and SEQ_FLAGS, ~DPHASE; + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo; + mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; + SET_MODE(M_SCSI, M_SCSI) +msgin_rdptrs_get_fifo: + call allocate_fifo; + jmp mesgin_done; + +clear_target_state: + mvi LASTPHASE, P_BUSFREE; + /* clear target specific flags */ + mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; + +phase_lock: + test SCSIPHASE, 0xFF jz .; + test SSTAT1, SCSIPERR jnz phase_lock; +phase_lock_latch_phase: + and LASTPHASE, PHASE_MASK, SCSISIGI ret; + +/* + * Functions to read data in Automatic PIO mode. + * + * An ACK is not sent on input from the target until SCSIDATL is read from. + * So we wait until SCSIDATL is latched (the usual way), then read the data + * byte directly off the bus using SCSIBUSL. When we have pulled the ATN + * line, or we just want to acknowledge the byte, then we do a dummy read + * from SCISDATL. The SCSI spec guarantees that the target will hold the + * data byte on the bus until we send our ACK. + * + * The assumption here is that these are called in a particular sequence, + * and that REQ is already set when inb_first is called. inb_{first,next} + * use the same calling convention as inb. + */ +inb_next: + mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ +inb_next_wait: + /* + * If there is a parity error, wait for the kernel to + * see the interrupt and prepare our message response + * before continuing. + */ + test SCSIPHASE, 0xFF jz .; + test SSTAT1, SCSIPERR jnz inb_next_wait; +inb_next_check_phase: + and LASTPHASE, PHASE_MASK, SCSISIGI; + cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; +inb_first: + clr DINDEX[1]; + mov DINDEX,SINDEX; + mov DINDIR,SCSIBUS ret; /*read byte directly from bus*/ +inb_last: + mov NONE,SCSIDAT ret; /*dummy read from latch to ACK*/ + +mk_mesg: + mvi SCSISIGO, ATNO; + mov MSG_OUT,SINDEX ret; + +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +disable_ccsgen: + test SG_STATE, FETCH_INPROG jz disable_ccsgen_fetch_done; + clr CCSGCTL; +disable_ccsgen_fetch_done: + clr SG_STATE ret; + +service_fifo: + /* + * Do we have any prefetch left??? + */ + test SG_STATE, SEGS_AVAIL jnz idle_sg_avail; + + /* + * Can this FIFO have access to the S/G cache yet? + */ + test CCSGCTL, SG_CACHE_AVAIL jz return; + + /* Did we just finish fetching segs? */ + test CCSGCTL, CCSGDONE jnz idle_sgfetch_complete; + + /* Are we actively fetching segments? */ + test CCSGCTL, CCSGENACK jnz return; + + /* + * We fetch a "cacheline aligned" and sized amount of data + * so we don't end up referencing a non-existant page. + * Cacheline aligned is in quotes because the kernel will + * set the prefetch amount to a reasonable level if the + * cacheline size is unknown. + */ + bmov SGHADDR, SCB_RESIDUAL_SGPTR, 4; + mvi SGHCNT, SG_PREFETCH_CNT; + if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) { + /* + * Need two instruction between "touches" of SGHADDR. + */ + nop; + } + and SGHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR; + mvi CCSGCTL, CCSGEN|SG_CACHE_AVAIL|CCSGRESET; + or SG_STATE, FETCH_INPROG ret; +idle_sgfetch_complete: + /* + * Guard against SG_CACHE_AVAIL activating during sg fetch + * request in the other FIFO. + */ + test SG_STATE, FETCH_INPROG jz return; + clr CCSGCTL; + and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR; + mvi SG_STATE, SEGS_AVAIL|LOADING_NEEDED; +idle_sg_avail: + /* Does the hardware have space for another SG entry? */ + test DFSTATUS, PRELOAD_AVAIL jz return; + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + bmov HADDR, CCSGRAM, 8; + } else { + bmov HADDR, CCSGRAM, 4; + } + bmov HCNT, CCSGRAM, 3; + test HCNT[0], 0x1 jz . + 2; + xor DATA_COUNT_ODD, 0x1; + bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; + if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { + and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3]; + } + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + /* Skip 4 bytes of pad. */ + add CCSGADDR, 4; + } +sg_advance: + clr A; /* add sizeof(struct scatter) */ + add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF; + adc SCB_RESIDUAL_SGPTR[1],A; + adc SCB_RESIDUAL_SGPTR[2],A; + adc SCB_RESIDUAL_SGPTR[3],A; + mov SINDEX, SCB_RESIDUAL_SGPTR[0]; + test DATA_COUNT_ODD, 0x1 jz . + 2; + or SINDEX, ODD_SEG; + test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3; + or SINDEX, LAST_SEG; + clr SG_STATE; + mov SG_CACHE_PRE, SINDEX; + /* + * Load the segment. Or in HDMAEN here too + * just in case HDMAENACK has not come true + * by the time this segment is loaded. If + * HDMAENACK is not true, this or will disable + * HDMAEN mid-transfer. We do not want to simply + * mvi our original settings as SCSIEN automatically + * de-asserts and we don't want to accidentally + * re-enable it. + */ + if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) { + /* + * Use SCSIENWRDIS so that SCSIEN is never + * modified by this operation. + */ + or DFCNTRL, PRELOADEN|SCSIENWRDIS|HDMAEN; + } else { + or DFCNTRL, PRELOADEN|HDMAEN; + } + /* + * Do we have another segment in the cache? + */ + add NONE, SG_PREFETCH_CNT_LIMIT, CCSGADDR; + jnc return; + and SG_STATE, ~SEGS_AVAIL ret; + +/* + * Initialize the DMA address and counter from the SCB. + */ +load_first_seg: + bmov HADDR, SCB_DATAPTR, 11; + and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0]; + and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0]; + test SCB_DATACNT[3], SG_LAST_SEG jz . + 2; + or REG_ISR, LAST_SEG; + test DATA_COUNT_ODD, 0x1 jz . + 2; + or REG_ISR, ODD_SEG; + mov SG_CACHE_PRE, REG_ISR; + mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); + /* + * Since we've are entering a data phase, we will + * rely on the SCB_RESID* fields. Initialize the + * residual and clear the full residual flag. + */ + and SCB_SGPTR[0], ~SG_FULL_RESID; + bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5; + /* If we need more S/G elements, tell the idle loop */ + test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz . + 2; + mvi SG_STATE, LOADING_NEEDED ret; + clr SG_STATE ret; + +p_data_handle_xfer: + call setjmp_setscb; + test SG_STATE, LOADING_NEEDED jnz service_fifo; +p_data_clear_handler: + or LONGJMP_ADDR[1], INVALID_ADDR ret; + +p_data: + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; + SET_SEQINTCODE(PROTO_VIOLATION) +p_data_allowed: + + test SEQ_FLAGS, DPHASE jz data_phase_initialize; + + /* + * If we re-enter the data phase after going through another + * phase, our transfer location has almost certainly been + * corrupted by the interveining, non-data, transfers. Ask + * the host driver to fix us up based on the transfer residual + * unless we already know that we should be bitbucketing. + */ + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; + SET_SEQINTCODE(PDATA_REINIT) + jmp data_phase_inbounds; + +p_data_bitbucket: + /* + * Turn on `Bit Bucket' mode, wait until the target takes + * us to another phase, and then notify the host. + */ + mov SAVED_MODE, MODE_PTR; + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) + jnz bitbucket_not_m_dff; + /* + * Ensure that any FIFO contents are cleared out and the + * FIFO free'd prior to starting the BITBUCKET. BITBUCKET + * doesn't discard data already in the FIFO. + */ + mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; + SET_MODE(M_SCSI, M_SCSI) +bitbucket_not_m_dff: + or SXFRCTL1,BITBUCKET; + /* Wait for non-data phase. */ + test SCSIPHASE, ~DATA_PHASE_MASK jz .; + and SXFRCTL1, ~BITBUCKET; + RESTORE_MODE(SAVED_MODE) +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + SET_SEQINTCODE(DATA_OVERRUN) + jmp ITloop; + +data_phase_initialize: + test SCB_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; + call load_first_seg; +data_phase_inbounds: + /* We have seen a data phase at least once. */ + or SEQ_FLAGS, DPHASE; + mov SAVED_MODE, MODE_PTR; + test SG_STATE, LOADING_NEEDED jz data_group_dma_loop; + call p_data_handle_xfer; +data_group_dma_loop: + /* + * The transfer is complete if either the last segment + * completes or the target changes phase. Both conditions + * will clear SCSIEN. + */ + call idle_loop_service_fifos; + call idle_loop_cchan; + call idle_loop_gsfifo; + RESTORE_MODE(SAVED_MODE) + test DFCNTRL, SCSIEN jnz data_group_dma_loop; + +data_group_dmafinish: + /* + * The transfer has terminated either due to a phase + * change, and/or the completion of the last segment. + * We have two goals here. Do as much other work + * as possible while the data fifo drains on a read + * and respond as quickly as possible to the standard + * messages (save data pointers/disconnect and command + * complete) that usually follow a data phase. + */ + call calc_residual; + + /* + * Go ahead and shut down the DMA engine now. + */ + test DFCNTRL, DIRECTION jnz data_phase_finish; +data_group_fifoflush: + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + /* + * We have enabled the auto-ack feature. This means + * that the controller may have already transferred + * some overrun bytes into the data FIFO and acked them + * on the bus. The only way to detect this situation is + * to wait for LAST_SEG_DONE to come true on a completed + * transfer and then test to see if the data FIFO is + * non-empty. We know there is more data yet to transfer + * if SG_LIST_NULL is not yet set, thus there cannot be + * an overrun. + */ + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish; + test SG_CACHE_SHADOW, LAST_SEG_DONE jz .; + test DFSTATUS, FIFOEMP jnz data_phase_finish; + /* Overrun */ + jmp p_data; +data_phase_finish: + /* + * If the target has left us in data phase, loop through + * the dma code again. We will only loop if there is a + * data overrun. + */ + if ((ahd->flags & AHD_TARGETROLE) != 0) { + test SSTAT0, TARGET jnz data_phase_done; + } + if ((ahd->flags & AHD_INITIATORROLE) != 0) { + test SSTAT1, REQINIT jz .; + test SCSIPHASE, DATA_PHASE_MASK jnz p_data; + } + +data_phase_done: + /* Kill off any pending prefetch */ + call disable_ccsgen; + or LONGJMP_ADDR[1], INVALID_ADDR; + + if ((ahd->flags & AHD_TARGETROLE) != 0) { + test SEQ_FLAGS, DPHASE_PENDING jz ITloop; + /* + and SEQ_FLAGS, ~DPHASE_PENDING; + * For data-in phases, wait for any pending acks from the + * initiator before changing phase. We only need to + * send Ignore Wide Residue messages for data-in phases. + test DFCNTRL, DIRECTION jz target_ITloop; + test SSTAT1, REQINIT jnz .; + test DATA_COUNT_ODD, 0x1 jz target_ITloop; + SET_MODE(M_SCSI, M_SCSI) + test NEGCONOPTS, WIDEXFER jz target_ITloop; + */ + /* + * Issue an Ignore Wide Residue Message. + mvi P_MESGIN|BSYO call change_phase; + mvi MSG_IGN_WIDE_RESIDUE call target_outb; + mvi 1 call target_outb; + jmp target_ITloop; + */ + } else { + jmp ITloop; + } + +/* + * We assume that, even though data may still be + * transferring to the host, that the SCSI side of + * the DMA engine is now in a static state. This + * allows us to update our notion of where we are + * in this transfer. + * + * If, by chance, we stopped before being able + * to fetch additional segments for this transfer, + * yet the last S/G was completely exhausted, + * call our idle loop until it is able to load + * another segment. This will allow us to immediately + * pickup on the next segment on the next data phase. + * + * If we happened to stop on the last segment, then + * our residual information is still correct from + * the idle loop and there is no need to perform + * any fixups. + */ +calc_residual: + test SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg; + /* Record if we've consumed all S/G entries */ + test MDFFSTAT, SHVALID jz . + 2; + bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; + or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret; +residual_before_last_seg: + test MDFFSTAT, SHVALID jnz sgptr_fixup; + /* + * Can never happen from an interrupt as the packetized + * hardware will only interrupt us once SHVALID or + * LAST_SEG_DONE. + */ + call idle_loop_service_fifos; + RESTORE_MODE(SAVED_MODE) + jmp calc_residual; + +sgptr_fixup: + /* + * Fixup the residual next S/G pointer. The S/G preload + * feature of the chip allows us to load two elements + * in addition to the currently active element. We + * store the bottom byte of the next S/G pointer in + * the SG_CACHE_PTR register so we can restore the + * correct value when the DMA completes. If the next + * sg ptr value has advanced to the point where higher + * bytes in the address have been affected, fix them + * too. + */ + test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done; + test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done; + add SCB_RESIDUAL_SGPTR[1], -1; + adc SCB_RESIDUAL_SGPTR[2], -1; + adc SCB_RESIDUAL_SGPTR[3], -1; +sgptr_fixup_done: + and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; + clr DATA_COUNT_ODD; + test SG_CACHE_SHADOW, ODD_SEG jz . + 2; + or DATA_COUNT_ODD, 0x1; + clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ + bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; + +export timer_isr: + call issue_cmdcmplt; + mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { + /* + * In H2A4, the mode pointer is not saved + * for intvec2, but is restored on iret. + * This can lead to the restoration of a + * bogus mode ptr. Manually clear the + * intmask bits and do a normal return + * to compensate. + */ + and SEQINTCTL, ~(INTMASK2|INTMASK1) ret; + } else { + or SEQINTCTL, IRET ret; + } + +export seq_isr: + nop; /* Jumps in the first ISR instruction fail on Rev A. */ + test SEQINTSRC, CFG4DATA jnz cfg4data_intr; + test SEQINTSRC, CFG4ISTAT jnz cfg4istat_intr; + test SEQINTSRC, SAVEPTRS jnz saveptr_intr; + test SEQINTSRC, CFG4ICMD jnz cfg4icmd_intr; + SET_SEQINTCODE(INVALID_SEQINT) + +/* + * There are two types of save pointers interrupts: + * The first is a snapshot save pointers where the current FIFO is not + * active and contains a snapshot of the current poniter information. + * This happens between packets in a stream for a single L_Q. Since we + * are not performing a pointer save, we can safely clear the channel + * so it can be used for other transactions. + * + * The second case is a save pointers on an active FIFO which occurs + * if the target changes to a new L_Q or busfrees/QAS' and the transfer + * has a residual. This should occur coincident with a ctxtdone. We + * disable the interrupt and allow our active routine to handle the + * save. + */ +saveptr_intr: + test DFCNTRL, HDMAENACK jz snapshot_saveptr; + and SEQIMODE, ~ENSAVEPTRS; + or SEQINTCTL, IRET ret; +snapshot_saveptr: + mvi DFFSXFRCTL, CLRCHN; + or SEQINTCTL, IRET ret; + +cfg4data_intr: + test SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun; + call load_first_seg; + call pkt_handle_xfer; + or SEQINTCTL, IRET ret; + +cfg4istat_intr: + call freeze_queue; + add NONE, -13, SCB_CDB_LEN; + jnc cfg4istat_have_sense_addr; + test SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr; + /* + * Host sets up address/count and enables transfer. + */ + SET_SEQINTCODE(CFG4ISTAT_INTR) + jmp cfg4istat_setup_handler; +cfg4istat_have_sense_addr: + bmov HADDR, SCB_SENSE_BUSADDR, 4; + mvi HCNT[1], (AHD_SENSE_BUFSIZE >> 8); + mvi SG_CACHE_PRE, LAST_SEG; + mvi DFCNTRL, PRELOADEN|SCSIEN|HDMAEN; +cfg4istat_setup_handler: + /* + * Status pkt is transferring to host. + * Wait in idle loop for transfer to complete. + * If a command completed before an attempted + * task management function completed, notify the host. + */ + test SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func; + SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) +cfg4istat_no_taskmgmt_func: + call pkt_handle_status; + or SEQINTCTL, IRET ret; + +/* + * See if the target has gone on in this context creating an + * overrun condition. For the write case, the hardware cannot + * ack bytes until data are provided. So, if the target begins + * another packet without changing contexts, implying we are + * not sitting on a packet boundary, we are in an overrun + * situation. For the read case, the hardware will continue to + * ack bytes into the FIFO, and may even ack the last overrun packet + * into the FIFO. If the FIFO should become non-empty, we are in + * a read overrun case. + */ +#define check_overrun \ + /* Not on a packet boundary. */ \ + test MDFFSTAT, DLZERO jz pkt_handle_overrun; \ + test DFSTATUS, FIFOEMP jz pkt_handle_overrun + +pkt_handle_xfer: + bmov LONGJMP_SCB, SCBPTR, 2; + test SG_STATE, LOADING_NEEDED jz pkt_last_seg; + call setjmp; + test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; + test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; + test SCSISIGO, ATNO jnz . + 2; + test SSTAT2, NONPACKREQ jz pkt_service_fifo; + /* + * Defer handling of this NONPACKREQ until we + * can be sure it pertains to this FIFO. SAVEPTRS + * will not be asserted if the NONPACKREQ is for us, + * so we must simulate it if shaddow is valid. If + * shaddow is not valid, keep running this FIFO until we + * have satisfied the transfer by loading segments and + * waiting for either shaddow valid or last_seg_done. + */ + test MDFFSTAT, SHVALID jnz pkt_saveptrs; +pkt_service_fifo: + test SG_STATE, LOADING_NEEDED jnz service_fifo; +pkt_last_seg: + call setjmp; + test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; + test SG_CACHE_SHADOW, LAST_SEG_DONE jnz last_pkt_done; + test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; + test SCSISIGO, ATNO jnz . + 2; + test SSTAT2, NONPACKREQ jz return; + test MDFFSTAT, SHVALID jz return; + /* FALLTHROUGH */ + +/* + * Either a SAVEPTRS interrupt condition is pending for this FIFO + * or we have a pending nonpackreq for this FIFO. We differentiate + * between the two by capturing the state of the SAVEPTRS interrupt + * prior to clearing this status and executing the common code for + * these two cases. + */ +pkt_saveptrs: +BEGIN_CRITICAL; + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + mov REG0, SEQINTSRC; + call calc_residual; + call save_pointers; + mvi CLRSEQINTSRC, CLRSAVEPTRS; + call disable_ccsgen; + or SEQIMODE, ENSAVEPTRS; + test DFCNTRL, DIRECTION jnz pkt_saveptrs_check_status; + test DFSTATUS, FIFOEMP jnz pkt_saveptrs_check_status; + /* + * Keep a handler around for this FIFO until it drains + * to the host to guarantee that we don't complete the + * command to the host before the data arrives. + */ +pkt_saveptrs_wait_fifoemp: + call setjmp; + test DFSTATUS, FIFOEMP jz return; +pkt_saveptrs_check_status: + or LONGJMP_ADDR[1], INVALID_ADDR; + test REG0, SAVEPTRS jz unexpected_nonpkt_phase; + test SCB_CONTROL, STATUS_RCVD jz pkt_saveptrs_clrchn; + jmp last_pkt_complete; +pkt_saveptrs_clrchn: + mvi DFFSXFRCTL, CLRCHN ret; +END_CRITICAL; + +last_pkt_done: +BEGIN_CRITICAL; + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + test SCB_CONTROL, STATUS_RCVD jz wait_pkt_end; + check_overrun; + or SCB_SGPTR, SG_LIST_NULL; + /* + * It is safe to skip the other FIFO check since + * we defer CLRCHN on SAVEPTRS until all data in + * the FIFO are seen by the host and a CFG4DATA + * in this FIFO for the same context is held off + * by hardware. + */ +last_pkt_queue_scb: + or LONGJMP_ADDR[1], INVALID_ADDR; + bmov ARG_1, SCBPTR, 2; + mvi DFFSXFRCTL, CLRCHN; + jmp queue_arg1_scb_completion; + +last_pkt_complete: + bmov ARG_1, SCBPTR, 2; + mvi DFFSXFRCTL, CLRCHN; +check_other_fifo: + clc; + TOGGLE_DFF_MODE + call check_fifo; + jnc queue_arg1_scb_completion; +return: + ret; + +wait_pkt_end: + call setjmp; +END_CRITICAL; +wait_pkt_end_loop: + test SEQINTSRC, CTXTDONE jnz pkt_end; + check_overrun; + test SSTAT2, NONPACKREQ jz return; + test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; +pkt_end: +BEGIN_CRITICAL; + check_overrun; + or LONGJMP_ADDR[1], INVALID_ADDR; + or SCB_SGPTR, SG_LIST_NULL; + test SCB_CONTROL, STATUS_RCVD jnz last_pkt_complete; + mvi DFFSXFRCTL, CLRCHN ret; +END_CRITICAL; + +check_status_overrun: + test SHCNT[2], 0xFF jz status_IU_done; + SET_SEQINTCODE(STATUS_OVERRUN) + jmp status_IU_done; +pkt_handle_status: + call setjmp_setscb; + test MDFFSTAT, LASTSDONE jnz check_status_overrun; + test SEQINTSRC, CTXTDONE jz return; +status_IU_done: +BEGIN_CRITICAL; + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + or LONGJMP_ADDR[1], INVALID_ADDR; + mvi SCB_SCSI_STATUS, STATUS_PKT_SENSE; + or SCB_CONTROL, STATUS_RCVD; + jmp last_pkt_complete; +END_CRITICAL; + +SET_SRC_MODE M_DFF0; +SET_DST_MODE M_DFF0; +BEGIN_CRITICAL; +check_fifo: + test LONGJMP_ADDR[1], INVALID_ADDR jnz return; + mov A, ARG_2; + cmp LONGJMP_SCB[1], A jne return; + mov A, ARG_1; + cmp LONGJMP_SCB[0], A jne return; + stc ret; +END_CRITICAL; + +/* + * Nonpackreq is a polled status. It can come true in three situations: + * we have received an L_Q, we have sent one or more L_Qs, or there is no + * L_Q context associated with this REQ (REQ occurs immediately after a + * (re)selection). Routines that know that the context responsible for this + * nonpackreq call directly into unexpected_nonpkt_phase. In the case of the + * top level idle loop, we exhaust all active contexts prior to determining that + * we simply do not have the full I_T_L_Q for this phase. + */ +unexpected_nonpkt_phase_find_ctxt: + /* + * This nonpackreq is most likely associated with one of the tags + * in a FIFO or an outgoing LQ. Only treat it as an I_T only + * nonpackreq if we've cleared out the FIFOs and handled any + * pending SELDO. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; + and A, FIFO1FREE|FIFO0FREE, DFFSTAT; + cmp A, FIFO1FREE|FIFO0FREE jne return; + test SSTAT0, SELDO jnz return; + mvi SCBPTR[1], SCB_LIST_NULL; +unexpected_nonpkt_phase: + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz . + 3; +SET_SRC_MODE M_DFF0; +SET_DST_MODE M_DFF0; + or LONGJMP_ADDR[1], INVALID_ADDR; + mvi DFFSXFRCTL, CLRCHN; + mvi CLRSINT2, CLRNONPACKREQ; + test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase; + SET_SEQINTCODE(ENTERING_NONPACK) + jmp ITloop; + +illegal_phase: + SET_SEQINTCODE(ILLEGAL_PHASE) + jmp ITloop; + +/* + * We have entered an overrun situation. If we have working + * BITBUCKET, flip that on and let the hardware eat any overrun + * data. Otherwise use an overrun buffer in the host to simulate + * BITBUCKET. + */ +pkt_handle_overrun: + SET_SEQINTCODE(CFG4OVERRUN) + call freeze_queue; + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) { + or DFFSXFRCTL, DFFBITBUCKET; +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + } else { + call load_overrun_buf; + mvi DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN); + } + call setjmp; + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { + test DFSTATUS, PRELOAD_AVAIL jz overrun_load_done; + call load_overrun_buf; + or DFCNTRL, PRELOADEN; +overrun_load_done: + test SEQINTSRC, CTXTDONE jnz pkt_overrun_end; + } else { + test DFFSXFRCTL, DFFBITBUCKET jz pkt_overrun_end; + } + test SSTAT2, NONPACKREQ jz return; +pkt_overrun_end: + or SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID; + test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; + test SCB_CONTROL, STATUS_RCVD jnz last_pkt_queue_scb; + mvi DFFSXFRCTL, CLRCHN ret; + +if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { +load_overrun_buf: + /* + * Load a dummy segment if preload space is available. + */ + mov HADDR[0], SHARED_DATA_ADDR; + add HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1]; + mov ACCUM_SAVE, A; + clr A; + adc HADDR[2], A, SHARED_DATA_ADDR[2]; + adc HADDR[3], A, SHARED_DATA_ADDR[3]; + mov A, ACCUM_SAVE; + bmov HADDR[4], ALLZEROS, 4; + /* PKT_OVERRUN_BUFSIZE is a multiple of 256 */ + clr HCNT[0]; + mvi HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF); + clr HCNT[2] ret; +} + +cfg4icmd_intr: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic79xx_seq.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_seq.h --- linux.21pre4/drivers/scsi/aic7xxx/aic79xx_seq.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic79xx_seq.h 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,1085 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ + */ +static uint8_t seqprog[] = { + 0xff, 0x02, 0x06, 0x78, + 0x00, 0xea, 0x46, 0x59, + 0x01, 0xea, 0x04, 0x30, + 0xff, 0x04, 0x0c, 0x78, + 0x19, 0xea, 0x46, 0x59, + 0x19, 0xea, 0x04, 0x00, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x60, 0x3a, 0x1a, 0x68, + 0x04, 0x47, 0x1b, 0x68, + 0xff, 0x21, 0x1b, 0x70, + 0x40, 0x4b, 0x88, 0x69, + 0x00, 0xe2, 0x4a, 0x59, + 0x40, 0x4b, 0x88, 0x69, + 0x20, 0x4b, 0x78, 0x69, + 0xfc, 0x42, 0x24, 0x78, + 0x10, 0x40, 0x24, 0x78, + 0x00, 0xe2, 0xa4, 0x5d, + 0x20, 0x4d, 0x28, 0x78, + 0x00, 0xe2, 0xa4, 0x5d, + 0x00, 0xe2, 0x34, 0x58, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0xe2, 0x76, 0x58, + 0x00, 0xe2, 0x06, 0x40, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x01, 0x52, 0x66, 0x7d, + 0x02, 0x58, 0x50, 0x31, + 0xff, 0xea, 0x10, 0x0b, + 0xff, 0x93, 0x45, 0x78, + 0x50, 0x4b, 0x40, 0x68, + 0xbf, 0x3a, 0x74, 0x08, + 0x14, 0xea, 0x46, 0x59, + 0x14, 0xea, 0x04, 0x00, + 0x08, 0xa8, 0x51, 0x03, + 0x01, 0xa4, 0x4d, 0x78, + 0x00, 0xe2, 0x44, 0x5b, + 0x00, 0xe2, 0x34, 0x40, + 0xff, 0xea, 0xd4, 0x19, + 0x02, 0xa8, 0x84, 0x32, + 0x00, 0xea, 0x3a, 0x59, + 0x01, 0xea, 0x00, 0x30, + 0x00, 0xe2, 0x98, 0x5d, + 0x00, 0xe2, 0x66, 0x4d, + 0x11, 0xea, 0x3a, 0x59, + 0x11, 0xea, 0x00, 0x00, + 0x00, 0xe2, 0x98, 0x5d, + 0x00, 0xe2, 0x66, 0x4d, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x00, 0xe2, 0x3a, 0x43, + 0x00, 0xea, 0x3a, 0x59, + 0x01, 0xea, 0x00, 0x30, + 0x80, 0xf9, 0x6e, 0x68, + 0x00, 0xe2, 0x38, 0x59, + 0x11, 0xea, 0x3a, 0x59, + 0x11, 0xea, 0x00, 0x00, + 0x80, 0xf9, 0x38, 0x79, + 0xff, 0xea, 0xd4, 0x0d, + 0x22, 0xea, 0x3a, 0x59, + 0x22, 0xea, 0x00, 0x00, + 0x10, 0x16, 0x80, 0x78, + 0x01, 0x0b, 0xa2, 0x32, + 0x10, 0x16, 0x2c, 0x00, + 0x18, 0xad, 0xee, 0x78, + 0x04, 0xad, 0xbc, 0x68, + 0x80, 0xad, 0x66, 0x7d, + 0x10, 0xad, 0x8a, 0x78, + 0xe7, 0xad, 0x5a, 0x0d, + 0xe7, 0xad, 0x5a, 0x09, + 0x00, 0xe2, 0x98, 0x58, + 0xff, 0xea, 0x56, 0x02, + 0x04, 0x7c, 0x78, 0x32, + 0x20, 0x16, 0x66, 0x7d, + 0x04, 0x38, 0x79, 0x32, + 0x80, 0x37, 0x6f, 0x16, + 0xff, 0x2d, 0xa7, 0x60, + 0xff, 0x29, 0xa7, 0x60, + 0x40, 0x51, 0xb7, 0x78, + 0xff, 0x4f, 0xa7, 0x68, + 0xff, 0x4d, 0xc1, 0x19, + 0x00, 0x4e, 0xd5, 0x19, + 0x00, 0xe2, 0xb6, 0x50, + 0x01, 0x4c, 0xc1, 0x31, + 0x00, 0x50, 0xd5, 0x19, + 0x00, 0xe2, 0xb6, 0x48, + 0x80, 0x18, 0x66, 0x7d, + 0x02, 0x4a, 0x1d, 0x30, + 0x10, 0xea, 0x18, 0x00, + 0x60, 0x18, 0x30, 0x00, + 0x7f, 0x18, 0x30, 0x0c, + 0x02, 0xea, 0x02, 0x00, + 0xff, 0xea, 0xa0, 0x0a, + 0x80, 0x18, 0x30, 0x04, + 0x40, 0xad, 0x66, 0x7d, + 0xe7, 0xad, 0x5a, 0x09, + 0x02, 0xa8, 0x40, 0x31, + 0xff, 0xea, 0xc0, 0x09, + 0x01, 0x4e, 0x9d, 0x1a, + 0x00, 0x4f, 0x9f, 0x22, + 0x04, 0x94, 0x49, 0x32, + 0xff, 0xea, 0x2a, 0x03, + 0xff, 0xea, 0x2e, 0x03, + 0x01, 0x10, 0xd4, 0x31, + 0x10, 0xa8, 0xe3, 0x68, + 0x3d, 0xa9, 0xc5, 0x29, + 0xfe, 0xe2, 0xc4, 0x09, + 0x01, 0xea, 0xc6, 0x01, + 0x02, 0xe2, 0xc8, 0x31, + 0x02, 0xec, 0x50, 0x31, + 0x02, 0xa0, 0xda, 0x31, + 0xff, 0xa9, 0xe2, 0x70, + 0x02, 0xa0, 0x28, 0x37, + 0xff, 0x21, 0xeb, 0x70, + 0x02, 0x22, 0x51, 0x31, + 0x02, 0xa0, 0x2c, 0x33, + 0x02, 0xa0, 0x44, 0x36, + 0x02, 0xa0, 0x40, 0x32, + 0x02, 0xa0, 0x44, 0x36, + 0x04, 0x47, 0xf3, 0x68, + 0x40, 0x16, 0x1e, 0x69, + 0xff, 0x2d, 0x23, 0x61, + 0xff, 0x29, 0x67, 0x75, + 0x01, 0x37, 0xc1, 0x31, + 0x02, 0x28, 0x55, 0x32, + 0x01, 0xea, 0x5a, 0x01, + 0x04, 0x3c, 0xf9, 0x30, + 0x02, 0x28, 0x51, 0x31, + 0x01, 0xa8, 0x60, 0x31, + 0x00, 0xa9, 0x60, 0x01, + 0x01, 0x14, 0xd4, 0x31, + 0x01, 0x50, 0xa1, 0x1a, + 0xff, 0x4e, 0x9d, 0x1a, + 0xff, 0x4f, 0x9f, 0x22, + 0xff, 0x8d, 0x17, 0x71, + 0x80, 0xac, 0x16, 0x71, + 0x20, 0x16, 0x16, 0x69, + 0x02, 0x8c, 0x51, 0x31, + 0x00, 0xe2, 0x00, 0x41, + 0x01, 0xac, 0x08, 0x31, + 0x09, 0xea, 0x5a, 0x01, + 0x02, 0x8c, 0x51, 0x32, + 0xff, 0xea, 0x1a, 0x07, + 0x04, 0x24, 0xf9, 0x30, + 0x1d, 0xea, 0x2e, 0x41, + 0x02, 0x2c, 0x51, 0x31, + 0x04, 0xac, 0xf9, 0x30, + 0x19, 0xea, 0x2e, 0x59, + 0x02, 0x8c, 0x59, 0x32, + 0x02, 0x28, 0x19, 0x33, + 0x02, 0xa8, 0x50, 0x36, + 0x06, 0xea, 0x08, 0x81, + 0x01, 0xe2, 0x5a, 0x35, + 0x02, 0xa8, 0xf4, 0x31, + 0x02, 0xf2, 0xf0, 0x35, + 0x02, 0xf2, 0xf0, 0x31, + 0x02, 0xf8, 0xe4, 0x35, + 0x80, 0xea, 0xb2, 0x01, + 0x01, 0xe2, 0x00, 0x30, + 0xff, 0xea, 0xb2, 0x0d, + 0x80, 0xea, 0xb2, 0x01, + 0x11, 0x00, 0x00, 0x10, + 0xff, 0xea, 0xb2, 0x0d, + 0x01, 0xe2, 0x04, 0x30, + 0x01, 0xea, 0x04, 0x34, + 0x02, 0x20, 0xbd, 0x30, + 0x02, 0x20, 0xb9, 0x30, + 0x02, 0x20, 0x51, 0x31, + 0x4c, 0xa9, 0xd7, 0x28, + 0x10, 0xa8, 0x59, 0x79, + 0x01, 0x6b, 0xc0, 0x30, + 0x02, 0x64, 0xc8, 0x00, + 0x40, 0x3a, 0x74, 0x04, + 0x00, 0xe2, 0x66, 0x58, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x30, 0x3f, 0xc0, 0x09, + 0x30, 0xe0, 0x5a, 0x61, + 0x20, 0x3f, 0x70, 0x69, + 0x10, 0x3f, 0x5a, 0x79, + 0x02, 0xea, 0x7e, 0x00, + 0x00, 0xea, 0x3a, 0x59, + 0x01, 0xea, 0x00, 0x30, + 0x02, 0x48, 0x51, 0x35, + 0x01, 0xea, 0x7e, 0x00, + 0x11, 0xea, 0x3a, 0x59, + 0x11, 0xea, 0x00, 0x00, + 0x02, 0x48, 0x51, 0x35, + 0x08, 0xea, 0x98, 0x00, + 0x08, 0x57, 0xae, 0x00, + 0x08, 0x3c, 0x78, 0x00, + 0xf0, 0x49, 0x68, 0x0a, + 0x0f, 0x67, 0xc0, 0x09, + 0x00, 0x34, 0x69, 0x02, + 0x20, 0xea, 0x96, 0x00, + 0x00, 0xe2, 0xee, 0x41, + 0x40, 0x3a, 0xa4, 0x69, + 0x02, 0x55, 0x06, 0x68, + 0x02, 0x56, 0xa4, 0x69, + 0xff, 0x5b, 0xa4, 0x61, + 0x02, 0x20, 0x51, 0x31, + 0x80, 0xea, 0xb2, 0x01, + 0x44, 0xea, 0x00, 0x00, + 0x01, 0x33, 0xc0, 0x31, + 0x33, 0xea, 0x00, 0x00, + 0xff, 0xea, 0xb2, 0x09, + 0xff, 0xe0, 0xc0, 0x19, + 0xff, 0xe0, 0xa6, 0x79, + 0x02, 0x94, 0x51, 0x31, + 0x00, 0xe2, 0x9c, 0x41, + 0x02, 0x5e, 0x50, 0x31, + 0x02, 0xa8, 0xb8, 0x30, + 0x02, 0x5c, 0x50, 0x31, + 0xff, 0x95, 0xb7, 0x71, + 0x02, 0x94, 0x41, 0x31, + 0x02, 0x22, 0x51, 0x31, + 0x02, 0xa0, 0x2c, 0x33, + 0x02, 0xa0, 0x44, 0x32, + 0x00, 0xe2, 0xc0, 0x41, + 0x10, 0xa8, 0xc1, 0x69, + 0x3d, 0xa9, 0xc9, 0x29, + 0x01, 0xe4, 0xc8, 0x01, + 0x01, 0xea, 0xca, 0x01, + 0xff, 0xea, 0xda, 0x01, + 0x02, 0x20, 0x51, 0x31, + 0x02, 0x96, 0x41, 0x32, + 0xff, 0x21, 0xc9, 0x61, + 0xff, 0xea, 0x46, 0x02, + 0x02, 0x5c, 0x50, 0x31, + 0x40, 0xea, 0x96, 0x00, + 0x02, 0x56, 0xac, 0x6d, + 0x01, 0x55, 0xac, 0x6d, + 0x10, 0xa8, 0xd5, 0x79, + 0x10, 0x40, 0xde, 0x69, + 0x01, 0x56, 0xde, 0x79, + 0xff, 0x93, 0x07, 0x78, + 0x13, 0xea, 0x46, 0x59, + 0x13, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x06, 0x40, + 0xbf, 0x3a, 0x74, 0x08, + 0x08, 0xea, 0x98, 0x00, + 0x08, 0x57, 0xae, 0x00, + 0x01, 0xa9, 0x69, 0x32, + 0x01, 0xaa, 0x6b, 0x32, + 0x40, 0xea, 0x66, 0x02, + 0x08, 0x3c, 0x78, 0x00, + 0x80, 0xea, 0x62, 0x02, + 0x00, 0xe2, 0xa4, 0x5b, + 0x01, 0x36, 0xc1, 0x31, + 0x9f, 0xe0, 0x38, 0x7c, + 0x80, 0xe0, 0x02, 0x72, + 0xa0, 0xe0, 0x3a, 0x72, + 0xc0, 0xe0, 0x30, 0x72, + 0xe0, 0xe0, 0x6a, 0x72, + 0x01, 0xea, 0x46, 0x59, + 0x01, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xee, 0x41, + 0x80, 0x33, 0x09, 0x7a, + 0x03, 0xea, 0x46, 0x59, + 0x03, 0xea, 0x04, 0x00, + 0xee, 0x00, 0x10, 0x6a, + 0x05, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x02, 0xa8, 0x90, 0x32, + 0x00, 0xe2, 0x60, 0x59, + 0xef, 0x92, 0xd5, 0x19, + 0x00, 0xe2, 0x20, 0x52, + 0x0b, 0x84, 0xe1, 0x30, + 0x02, 0xea, 0x36, 0x00, + 0xa8, 0xea, 0x32, 0x00, + 0x00, 0xe2, 0x26, 0x42, + 0x01, 0x92, 0xd1, 0x30, + 0x10, 0x80, 0x89, 0x31, + 0x20, 0xea, 0x32, 0x00, + 0xbf, 0x33, 0x67, 0x0a, + 0x20, 0x19, 0x28, 0x6a, + 0x02, 0x4d, 0xee, 0x69, + 0x40, 0x33, 0x67, 0x02, + 0x00, 0xe2, 0xee, 0x41, + 0x80, 0x33, 0xa7, 0x6a, + 0x01, 0x44, 0x10, 0x33, + 0x08, 0xa8, 0x51, 0x03, + 0x00, 0xe2, 0xee, 0x41, + 0x10, 0xea, 0x80, 0x00, + 0x01, 0x31, 0xc5, 0x31, + 0x80, 0xe2, 0x56, 0x62, + 0x10, 0xa8, 0x7b, 0x6a, + 0xc0, 0xaa, 0xc5, 0x01, + 0x40, 0xa8, 0x47, 0x6a, + 0xbf, 0xe2, 0xc4, 0x09, + 0x20, 0xa8, 0x5b, 0x7a, + 0x01, 0xe2, 0x88, 0x30, + 0x00, 0xe2, 0xa4, 0x5b, + 0xa0, 0x36, 0x63, 0x62, + 0x23, 0xa8, 0x89, 0x08, + 0x00, 0xe2, 0xa4, 0x5b, + 0xa0, 0x36, 0x63, 0x62, + 0x00, 0xa8, 0x5a, 0x42, + 0xff, 0xe2, 0x5a, 0x62, + 0x00, 0xe2, 0x7a, 0x42, + 0x40, 0xea, 0x98, 0x00, + 0x01, 0xe2, 0x88, 0x30, + 0x00, 0xe2, 0xa4, 0x5b, + 0xa0, 0x36, 0x39, 0x72, + 0x40, 0xea, 0x98, 0x00, + 0x01, 0x31, 0x89, 0x32, + 0x08, 0xea, 0x62, 0x02, + 0x00, 0xe2, 0xee, 0x41, + 0xe0, 0xea, 0xb4, 0x5b, + 0x80, 0xe0, 0xb2, 0x6a, + 0x04, 0xe0, 0x52, 0x73, + 0x02, 0xe0, 0x82, 0x73, + 0x00, 0xea, 0x10, 0x73, + 0x03, 0xe0, 0x92, 0x73, + 0x23, 0xe0, 0x8c, 0x72, + 0x08, 0xe0, 0xae, 0x72, + 0x00, 0xe2, 0xa4, 0x5b, + 0x07, 0xea, 0x46, 0x59, + 0x07, 0xea, 0x04, 0x00, + 0x08, 0x42, 0xef, 0x71, + 0x04, 0x42, 0x89, 0x62, + 0x01, 0x43, 0x89, 0x30, + 0x00, 0xe2, 0x7a, 0x42, + 0x01, 0x44, 0xd4, 0x31, + 0x00, 0xe2, 0x7a, 0x42, + 0x01, 0x00, 0x60, 0x32, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x4c, 0x34, 0xc1, 0x28, + 0x01, 0x64, 0xc0, 0x31, + 0x00, 0x30, 0x3b, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x01, 0xe0, 0xac, 0x7a, + 0xa0, 0xea, 0xaa, 0x5b, + 0x01, 0xa0, 0xac, 0x62, + 0x01, 0x84, 0xa5, 0x7a, + 0x01, 0xa7, 0xae, 0x7a, + 0x00, 0xe2, 0xae, 0x42, + 0x03, 0xea, 0x46, 0x59, + 0x03, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xae, 0x42, + 0x07, 0xea, 0xbc, 0x5b, + 0x01, 0x44, 0xd4, 0x31, + 0x00, 0xe2, 0xee, 0x41, + 0x3f, 0xe0, 0x6a, 0x0a, + 0xc0, 0x34, 0xc1, 0x09, + 0x00, 0x35, 0x51, 0x01, + 0xff, 0xea, 0x52, 0x09, + 0x30, 0x34, 0xc5, 0x09, + 0x3d, 0xe2, 0xc4, 0x29, + 0xb8, 0xe2, 0xc4, 0x19, + 0x01, 0xea, 0xc6, 0x01, + 0x02, 0xe2, 0xc8, 0x31, + 0x02, 0xec, 0x40, 0x31, + 0xff, 0xa1, 0xce, 0x72, + 0x02, 0xe8, 0xda, 0x31, + 0x02, 0xa0, 0x50, 0x31, + 0x00, 0xe2, 0xf0, 0x42, + 0x80, 0x33, 0x67, 0x02, + 0x01, 0x44, 0xd4, 0x31, + 0x00, 0xe2, 0xa4, 0x5b, + 0x01, 0x33, 0x67, 0x02, + 0xe0, 0x36, 0x0b, 0x63, + 0x02, 0x33, 0x67, 0x02, + 0x20, 0x46, 0x04, 0x63, + 0xff, 0xea, 0x52, 0x09, + 0xa8, 0xea, 0xaa, 0x5b, + 0x04, 0xa8, 0xeb, 0x7a, + 0x01, 0x34, 0xc1, 0x31, + 0x00, 0xa9, 0xeb, 0x62, + 0x01, 0x35, 0xc1, 0x31, + 0x00, 0xaa, 0xf5, 0x72, + 0x01, 0xa9, 0x52, 0x11, + 0xff, 0xa9, 0xe0, 0x6a, + 0x00, 0xe2, 0x04, 0x43, + 0x10, 0x33, 0x67, 0x02, + 0x04, 0xa8, 0x05, 0x7b, + 0xfb, 0xa8, 0x51, 0x0b, + 0xff, 0xea, 0x66, 0x0a, + 0x01, 0xa4, 0xff, 0x6a, + 0x02, 0xa8, 0x90, 0x32, + 0x00, 0xe2, 0x60, 0x59, + 0x10, 0xa8, 0xaf, 0x7a, + 0xff, 0xea, 0xbc, 0x5b, + 0x00, 0xe2, 0xae, 0x42, + 0x04, 0xea, 0x46, 0x59, + 0x04, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xae, 0x42, + 0x04, 0xea, 0x46, 0x59, + 0x04, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xee, 0x41, + 0x08, 0xa8, 0xa7, 0x7a, + 0xc0, 0x33, 0x1b, 0x7b, + 0x80, 0x33, 0xa7, 0x6a, + 0xff, 0x88, 0x1b, 0x6b, + 0x40, 0x33, 0xa7, 0x6a, + 0x10, 0xa8, 0x21, 0x7b, + 0x0a, 0xea, 0x46, 0x59, + 0x0a, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x3a, 0x5b, + 0x00, 0xe2, 0x6e, 0x43, + 0x50, 0x4b, 0x28, 0x6b, + 0xbf, 0x3a, 0x74, 0x08, + 0x01, 0xe0, 0xf8, 0x31, + 0xff, 0xea, 0xc0, 0x09, + 0x01, 0x2e, 0x5d, 0x1a, + 0x00, 0x2f, 0x5f, 0x22, + 0x04, 0x47, 0x8f, 0x02, + 0x01, 0xfc, 0xc0, 0x35, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x02, 0x42, 0x51, 0x31, + 0x10, 0xa8, 0x51, 0x03, + 0xff, 0x88, 0x49, 0x6b, + 0x01, 0xa4, 0x45, 0x6b, + 0x02, 0xa4, 0x4d, 0x6b, + 0x01, 0x84, 0x4d, 0x7b, + 0x02, 0x28, 0x19, 0x33, + 0x02, 0xa8, 0x50, 0x36, + 0xff, 0x88, 0x4d, 0x73, + 0x00, 0xe2, 0x24, 0x5b, + 0x02, 0x2c, 0x19, 0x33, + 0x02, 0xa8, 0x58, 0x32, + 0x04, 0xa4, 0x49, 0x07, + 0xc0, 0x33, 0xa7, 0x6a, + 0x04, 0xa8, 0x51, 0x03, + 0x20, 0xa8, 0x6f, 0x6b, + 0x02, 0xa8, 0x40, 0x31, + 0xc0, 0x34, 0xc1, 0x09, + 0x00, 0x35, 0x51, 0x01, + 0xff, 0xea, 0x52, 0x09, + 0x30, 0x34, 0xc5, 0x09, + 0x3d, 0xe2, 0xc4, 0x29, + 0xb8, 0xe2, 0xc4, 0x19, + 0x01, 0xea, 0xc6, 0x01, + 0x02, 0xe2, 0xc8, 0x31, + 0x02, 0xa0, 0xda, 0x31, + 0x02, 0xa0, 0x50, 0x31, + 0xf7, 0x57, 0xae, 0x08, + 0x08, 0xea, 0x98, 0x00, + 0x01, 0x44, 0xd4, 0x31, + 0xee, 0x00, 0x78, 0x6b, + 0x02, 0xea, 0xb4, 0x00, + 0x00, 0xe2, 0xa0, 0x5b, + 0x09, 0x4c, 0x7a, 0x7b, + 0x08, 0x4c, 0x06, 0x68, + 0x0b, 0xea, 0x46, 0x59, + 0x0b, 0xea, 0x04, 0x00, + 0x01, 0x44, 0xd4, 0x31, + 0x20, 0x33, 0xef, 0x79, + 0x00, 0xe2, 0x8a, 0x5b, + 0x00, 0xe2, 0xee, 0x41, + 0x01, 0x84, 0x8f, 0x7b, + 0x01, 0xa4, 0x49, 0x07, + 0x08, 0x60, 0x30, 0x33, + 0x08, 0x80, 0x41, 0x37, + 0xdf, 0x33, 0x67, 0x0a, + 0xee, 0x00, 0x9c, 0x6b, + 0x05, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x00, 0xe2, 0x60, 0x59, + 0x00, 0xe2, 0xae, 0x42, + 0x01, 0xea, 0x6c, 0x02, + 0xc0, 0xea, 0x66, 0x06, + 0xff, 0x42, 0xa4, 0x7b, + 0x04, 0x4c, 0xa4, 0x6b, + 0xe0, 0x41, 0x6c, 0x0e, + 0x01, 0x44, 0xd4, 0x31, + 0xff, 0x42, 0xac, 0x7b, + 0x04, 0x4c, 0xac, 0x6b, + 0xe0, 0x41, 0x6c, 0x0a, + 0xe0, 0x36, 0xef, 0x61, + 0xff, 0xea, 0xca, 0x09, + 0x01, 0xe2, 0xc8, 0x31, + 0x01, 0x46, 0xda, 0x35, + 0x01, 0x44, 0xd4, 0x35, + 0x10, 0xea, 0x80, 0x00, + 0x01, 0xe2, 0x62, 0x36, + 0x04, 0xa6, 0xc4, 0x7b, + 0xff, 0xea, 0x5a, 0x09, + 0xff, 0xea, 0x4c, 0x0d, + 0x01, 0xa6, 0xe2, 0x6b, + 0x10, 0xad, 0x66, 0x7d, + 0x80, 0xad, 0xda, 0x6b, + 0x08, 0xad, 0x66, 0x6d, + 0x04, 0x84, 0xf9, 0x30, + 0x00, 0xea, 0x08, 0x81, + 0xff, 0xea, 0xd4, 0x09, + 0x02, 0x84, 0xf9, 0x88, + 0x1d, 0xea, 0x5a, 0x01, + 0x04, 0xa6, 0x4c, 0x05, + 0x04, 0xa6, 0x66, 0x7d, + 0xff, 0xea, 0x5a, 0x09, + 0x03, 0x84, 0x59, 0x89, + 0x03, 0xea, 0x4c, 0x01, + 0x80, 0x1a, 0x66, 0x7d, + 0x08, 0xb0, 0xe0, 0x30, + 0x04, 0xb0, 0xe0, 0x30, + 0x03, 0xb0, 0xf0, 0x30, + 0x01, 0x78, 0xee, 0x7b, + 0x01, 0xa7, 0x4e, 0x11, + 0x01, 0xb0, 0x06, 0x33, + 0x7f, 0x83, 0xe9, 0x08, + 0x04, 0xac, 0x58, 0x19, + 0xff, 0xea, 0xc0, 0x09, + 0x04, 0x84, 0x09, 0x9b, + 0x00, 0x85, 0x0b, 0x23, + 0x00, 0x86, 0x0d, 0x23, + 0x00, 0x87, 0x0f, 0x23, + 0x01, 0x84, 0xc5, 0x31, + 0x01, 0xa7, 0x04, 0x7c, + 0x04, 0xe2, 0xc4, 0x01, + 0x80, 0x83, 0x0b, 0x7c, + 0x02, 0xe2, 0xc4, 0x01, + 0xff, 0xea, 0x4c, 0x09, + 0x01, 0xe2, 0x36, 0x30, + 0xc8, 0x19, 0x32, 0x00, + 0x88, 0x19, 0x32, 0x00, + 0x01, 0xac, 0xd4, 0x99, + 0x00, 0xe2, 0x66, 0x55, + 0xfe, 0xa6, 0x4c, 0x0d, + 0x0b, 0x98, 0xe1, 0x30, + 0x01, 0xa0, 0x4f, 0x09, + 0xfd, 0xa4, 0x49, 0x09, + 0x80, 0xa3, 0x21, 0x7c, + 0x02, 0xa4, 0x48, 0x01, + 0x01, 0xa7, 0x24, 0x7c, + 0x04, 0xa4, 0x48, 0x01, + 0x01, 0xa4, 0x36, 0x30, + 0xa8, 0xea, 0x32, 0x00, + 0xfd, 0xa4, 0x49, 0x0b, + 0x05, 0xa3, 0x07, 0x33, + 0x80, 0x83, 0x31, 0x6c, + 0x02, 0xea, 0x4c, 0x05, + 0xff, 0xea, 0x4c, 0x0d, + 0x00, 0xe2, 0x32, 0x59, + 0x02, 0xa6, 0xc6, 0x6b, + 0x80, 0xf9, 0xf2, 0x05, + 0xc0, 0x33, 0x3f, 0x7c, + 0x03, 0xea, 0x46, 0x59, + 0x03, 0xea, 0x04, 0x00, + 0x20, 0x33, 0x63, 0x7c, + 0x01, 0x84, 0x49, 0x6c, + 0x06, 0xea, 0x46, 0x59, + 0x06, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x66, 0x44, + 0x01, 0x00, 0x60, 0x32, + 0xee, 0x00, 0x52, 0x6c, + 0x05, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x3a, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x80, 0x3d, 0x7a, 0x00, + 0xfc, 0x42, 0x54, 0x7c, + 0x7f, 0x3d, 0x7a, 0x08, + 0x00, 0x30, 0x3b, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x09, 0xea, 0x46, 0x59, + 0x09, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xee, 0x41, + 0x01, 0xa4, 0x49, 0x6c, + 0x00, 0xe2, 0x16, 0x5c, + 0x20, 0x33, 0x67, 0x02, + 0x01, 0x00, 0x60, 0x32, + 0x02, 0xa6, 0x6e, 0x7c, + 0x00, 0xe2, 0x32, 0x5c, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0xe2, 0x76, 0x58, + 0x00, 0xe2, 0x30, 0x58, + 0x00, 0x30, 0x3b, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x20, 0x19, 0x6e, 0x6c, + 0x00, 0xe2, 0x96, 0x5c, + 0x04, 0x19, 0x88, 0x6c, + 0x02, 0x19, 0x32, 0x00, + 0x01, 0x84, 0x89, 0x7c, + 0x01, 0x1b, 0x82, 0x7c, + 0x01, 0x1a, 0x88, 0x6c, + 0x00, 0xe2, 0x38, 0x44, + 0x80, 0x4b, 0x8e, 0x6c, + 0x01, 0x4c, 0x8a, 0x7c, + 0x03, 0x42, 0x38, 0x6c, + 0x00, 0xe2, 0xc0, 0x5b, + 0x80, 0xf9, 0xf2, 0x01, + 0x04, 0x33, 0xef, 0x79, + 0x00, 0xe2, 0xee, 0x41, + 0x02, 0x1b, 0x9e, 0x7c, + 0x08, 0x5d, 0x9c, 0x7c, + 0x03, 0x68, 0x00, 0x37, + 0x01, 0x84, 0x09, 0x07, + 0x08, 0x5d, 0xa8, 0x6c, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0x30, 0x3b, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x00, 0xe2, 0x96, 0x44, + 0x80, 0x1b, 0xb2, 0x7c, + 0x80, 0x84, 0xb3, 0x6c, + 0xff, 0x85, 0x0b, 0x1b, + 0xff, 0x86, 0x0d, 0x23, + 0xff, 0x87, 0x0f, 0x23, + 0xf8, 0x1b, 0x08, 0x0b, + 0xff, 0xea, 0x4e, 0x09, + 0x04, 0x1b, 0xba, 0x7c, + 0x01, 0xa7, 0x4e, 0x01, + 0xff, 0xea, 0x06, 0x0b, + 0x03, 0x68, 0x00, 0x37, + 0x00, 0xe2, 0xb6, 0x58, + 0x10, 0xea, 0x18, 0x00, + 0xf9, 0xd9, 0xb2, 0x0d, + 0x01, 0xd9, 0xb2, 0x05, + 0xff, 0xea, 0xd4, 0x09, + 0x10, 0x5b, 0xde, 0x6c, + 0x08, 0x5b, 0xe6, 0x6c, + 0x20, 0x5b, 0xd4, 0x6c, + 0x02, 0x5b, 0xfa, 0x6d, + 0x0e, 0xea, 0x46, 0x59, + 0x0e, 0xea, 0x04, 0x00, + 0x08, 0x19, 0xda, 0x7c, + 0xdf, 0x5c, 0xb8, 0x08, + 0x01, 0xd9, 0xb2, 0x05, + 0x02, 0xea, 0xb4, 0x00, + 0x01, 0xd9, 0xb2, 0x05, + 0x01, 0xa4, 0xc3, 0x6d, + 0x00, 0xe2, 0x16, 0x5c, + 0x00, 0xe2, 0x06, 0x5d, + 0x01, 0xd9, 0xb2, 0x05, + 0x00, 0xe2, 0x24, 0x5b, + 0xf3, 0x92, 0xd5, 0x19, + 0x00, 0xe2, 0xf4, 0x54, + 0x80, 0x92, 0xf5, 0x6c, + 0x0f, 0xea, 0x46, 0x59, + 0x0f, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xfc, 0x44, + 0x04, 0x8c, 0xe1, 0x30, + 0x01, 0xea, 0xf2, 0x00, + 0x02, 0xea, 0x36, 0x00, + 0xa8, 0xea, 0x32, 0x00, + 0xff, 0x93, 0x03, 0x7d, + 0x14, 0xea, 0x46, 0x59, + 0x14, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x88, 0x5d, + 0x01, 0xd9, 0xb2, 0x05, + 0x02, 0xa8, 0xf4, 0x31, + 0x02, 0xa6, 0x18, 0x7d, + 0x00, 0xe2, 0x34, 0x59, + 0x20, 0x5b, 0x26, 0x6d, + 0xfc, 0x42, 0x12, 0x7d, + 0x10, 0x40, 0x14, 0x6d, + 0x20, 0x4d, 0x16, 0x7d, + 0x08, 0x5d, 0x26, 0x6d, + 0x02, 0xa6, 0xc6, 0x6b, + 0x00, 0xe2, 0x34, 0x59, + 0x20, 0x5b, 0x26, 0x6d, + 0x01, 0x1b, 0x46, 0x6d, + 0xfc, 0x42, 0x22, 0x7d, + 0x10, 0x40, 0x24, 0x6d, + 0x20, 0x4d, 0x66, 0x7d, + 0x08, 0x5d, 0x66, 0x7d, + 0x02, 0x19, 0x32, 0x00, + 0x01, 0x5b, 0x40, 0x31, + 0x00, 0xe2, 0x96, 0x5c, + 0x00, 0xe2, 0x8a, 0x5b, + 0x20, 0xea, 0xb6, 0x00, + 0x00, 0xe2, 0xc0, 0x5b, + 0x20, 0x5c, 0xb8, 0x00, + 0x04, 0x19, 0x3c, 0x6d, + 0x01, 0x1a, 0x3c, 0x6d, + 0x00, 0xe2, 0x34, 0x59, + 0x01, 0x1a, 0x66, 0x7d, + 0x80, 0xf9, 0xf2, 0x01, + 0x20, 0xa0, 0xac, 0x7d, + 0x08, 0xa8, 0x45, 0x7d, + 0x00, 0xe2, 0x58, 0x45, + 0x02, 0xea, 0xb4, 0x04, + 0x02, 0x19, 0x32, 0x00, + 0x08, 0xa8, 0x69, 0x7d, + 0x04, 0x5d, 0xc2, 0x7d, + 0x01, 0x1a, 0xc2, 0x7d, + 0x01, 0xa4, 0x49, 0x03, + 0x80, 0xf9, 0xf2, 0x01, + 0x02, 0xa8, 0x84, 0x32, + 0x02, 0xea, 0xb4, 0x00, + 0x00, 0xe2, 0x34, 0x43, + 0x02, 0xa8, 0x84, 0x32, + 0x02, 0xea, 0xb4, 0x00, + 0xff, 0xea, 0xd4, 0x19, + 0x00, 0xe2, 0x40, 0x59, + 0x11, 0x00, 0x00, 0x10, + 0x00, 0xe2, 0x98, 0x5d, + 0x00, 0xe2, 0x34, 0x53, + 0xff, 0xea, 0xd4, 0x0d, + 0x00, 0xe2, 0x34, 0x59, + 0x40, 0x5b, 0x74, 0x6d, + 0x04, 0x5d, 0xc2, 0x7d, + 0x01, 0x1a, 0xc2, 0x7d, + 0x20, 0x4d, 0x66, 0x7d, + 0x40, 0x5b, 0xac, 0x7d, + 0x04, 0x5d, 0xc2, 0x7d, + 0x01, 0x1a, 0xc2, 0x7d, + 0x80, 0xf9, 0xf2, 0x01, + 0x01, 0xa4, 0x49, 0x03, + 0x08, 0xa8, 0x59, 0x6d, + 0x02, 0xea, 0xb4, 0x04, + 0xff, 0x6a, 0x8e, 0x7d, + 0x10, 0xea, 0x46, 0x59, + 0x10, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x8e, 0x45, + 0x00, 0xe2, 0x32, 0x59, + 0x10, 0x5d, 0x80, 0x6d, + 0x40, 0x5b, 0x66, 0x7d, + 0x02, 0x19, 0x32, 0x00, + 0x80, 0xf9, 0xf2, 0x01, + 0xff, 0xea, 0x10, 0x03, + 0x08, 0xa8, 0x51, 0x03, + 0x00, 0xe2, 0x58, 0x45, + 0x80, 0xf9, 0x66, 0x6d, + 0x01, 0x43, 0xc1, 0x31, + 0x00, 0xfb, 0x66, 0x65, + 0x01, 0x42, 0xc1, 0x31, + 0x00, 0xfa, 0x66, 0x65, + 0x01, 0xe8, 0xd4, 0x1d, + 0x30, 0x3f, 0xc0, 0x09, + 0x30, 0xe0, 0x66, 0x65, + 0x40, 0x4b, 0x66, 0x6d, + 0xff, 0xea, 0x52, 0x01, + 0xee, 0x00, 0xb2, 0x6d, + 0x80, 0xf9, 0xf2, 0x01, + 0x02, 0xea, 0xb4, 0x00, + 0x20, 0xea, 0x9a, 0x00, + 0xf3, 0x42, 0xbc, 0x6d, + 0x12, 0xea, 0x46, 0x59, + 0x12, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xee, 0x41, + 0x0d, 0xea, 0x46, 0x59, + 0x0d, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xee, 0x41, + 0x11, 0xea, 0x46, 0x59, + 0x11, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x24, 0x5b, + 0x08, 0x5a, 0xb4, 0x00, + 0x00, 0xe2, 0xe4, 0x5d, + 0xa8, 0xea, 0x32, 0x00, + 0x00, 0xe2, 0x34, 0x59, + 0x80, 0x1a, 0xd6, 0x7d, + 0x00, 0xe2, 0xe4, 0x5d, + 0x80, 0x19, 0x32, 0x00, + 0x40, 0x5b, 0xdc, 0x6d, + 0x08, 0x5a, 0xdc, 0x7d, + 0x20, 0x4d, 0x66, 0x7d, + 0x02, 0x84, 0x09, 0x03, + 0x40, 0x5b, 0xac, 0x7d, + 0x08, 0xa8, 0x51, 0x6d, + 0x02, 0xea, 0xb4, 0x04, + 0x01, 0x38, 0xe1, 0x30, + 0x05, 0x39, 0xe3, 0x98, + 0x01, 0xe0, 0xf8, 0x31, + 0xff, 0xea, 0xc0, 0x09, + 0x00, 0x3a, 0xe5, 0x20, + 0x00, 0x3b, 0xe7, 0x20, + 0x01, 0xfc, 0xc0, 0x31, + 0x04, 0xea, 0xe8, 0x30, + 0xff, 0xea, 0xf0, 0x08, + 0x02, 0xea, 0xf2, 0x00, + 0xff, 0xea, 0xf4, 0x0c +}; + +typedef int ahd_patch_func_t (struct ahd_softc *ahd); +static ahd_patch_func_t ahd_patch18_func; + +static int +ahd_patch18_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch17_func; + +static int +ahd_patch17_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0); +} + +static ahd_patch_func_t ahd_patch16_func; + +static int +ahd_patch16_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_INITIATORROLE) != 0); +} + +static ahd_patch_func_t ahd_patch15_func; + +static int +ahd_patch15_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_TARGETROLE) != 0); +} + +static ahd_patch_func_t ahd_patch14_func; + +static int +ahd_patch14_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch13_func; + +static int +ahd_patch13_func(struct ahd_softc *ahd) +{ + return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0); +} + +static ahd_patch_func_t ahd_patch12_func; + +static int +ahd_patch12_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0); +} + +static ahd_patch_func_t ahd_patch11_func; + +static int +ahd_patch11_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0); +} + +static ahd_patch_func_t ahd_patch10_func; + +static int +ahd_patch10_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch9_func; + +static int +ahd_patch9_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0); +} + +static ahd_patch_func_t ahd_patch8_func; + +static int +ahd_patch8_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0); +} + +static ahd_patch_func_t ahd_patch7_func; + +static int +ahd_patch7_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0); +} + +static ahd_patch_func_t ahd_patch6_func; + +static int +ahd_patch6_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch5_func; + +static int +ahd_patch5_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch4_func; + +static int +ahd_patch4_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch3_func; + +static int +ahd_patch3_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch2_func; + +static int +ahd_patch2_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_SET_MODE_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch1_func; + +static int +ahd_patch1_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch0_func; + +static int +ahd_patch0_func(struct ahd_softc *ahd) +{ + return (0); +} + +static struct patch { + ahd_patch_func_t *patch_func; + uint32_t begin :10, + skip_instr :10, + skip_patch :12; +} patches[] = { + { ahd_patch1_func, 0, 3, 3 }, + { ahd_patch1_func, 1, 1, 2 }, + { ahd_patch0_func, 2, 1, 1 }, + { ahd_patch1_func, 3, 3, 3 }, + { ahd_patch1_func, 4, 1, 2 }, + { ahd_patch0_func, 5, 1, 1 }, + { ahd_patch2_func, 6, 1, 2 }, + { ahd_patch0_func, 7, 1, 1 }, + { ahd_patch2_func, 24, 1, 2 }, + { ahd_patch0_func, 25, 1, 1 }, + { ahd_patch1_func, 32, 1, 2 }, + { ahd_patch0_func, 33, 1, 1 }, + { ahd_patch2_func, 40, 1, 2 }, + { ahd_patch0_func, 41, 1, 1 }, + { ahd_patch2_func, 44, 1, 2 }, + { ahd_patch0_func, 45, 1, 1 }, + { ahd_patch2_func, 48, 1, 2 }, + { ahd_patch0_func, 49, 1, 1 }, + { ahd_patch2_func, 51, 1, 2 }, + { ahd_patch0_func, 52, 1, 1 }, + { ahd_patch2_func, 55, 1, 2 }, + { ahd_patch0_func, 56, 1, 1 }, + { ahd_patch2_func, 59, 1, 2 }, + { ahd_patch0_func, 60, 1, 1 }, + { ahd_patch2_func, 157, 6, 1 }, + { ahd_patch1_func, 163, 2, 1 }, + { ahd_patch3_func, 165, 1, 1 }, + { ahd_patch2_func, 174, 1, 2 }, + { ahd_patch0_func, 175, 1, 1 }, + { ahd_patch4_func, 176, 2, 2 }, + { ahd_patch0_func, 178, 6, 3 }, + { ahd_patch2_func, 181, 1, 2 }, + { ahd_patch0_func, 182, 1, 1 }, + { ahd_patch2_func, 185, 1, 2 }, + { ahd_patch0_func, 186, 1, 1 }, + { ahd_patch5_func, 188, 2, 1 }, + { ahd_patch3_func, 196, 16, 2 }, + { ahd_patch0_func, 212, 1, 1 }, + { ahd_patch6_func, 232, 2, 1 }, + { ahd_patch1_func, 236, 1, 2 }, + { ahd_patch0_func, 237, 1, 1 }, + { ahd_patch5_func, 240, 2, 1 }, + { ahd_patch1_func, 254, 1, 2 }, + { ahd_patch0_func, 255, 1, 1 }, + { ahd_patch1_func, 258, 1, 2 }, + { ahd_patch0_func, 259, 1, 1 }, + { ahd_patch2_func, 262, 1, 2 }, + { ahd_patch0_func, 263, 1, 1 }, + { ahd_patch1_func, 318, 1, 2 }, + { ahd_patch0_func, 319, 1, 1 }, + { ahd_patch2_func, 327, 1, 2 }, + { ahd_patch0_func, 328, 1, 1 }, + { ahd_patch2_func, 331, 1, 2 }, + { ahd_patch0_func, 332, 1, 1 }, + { ahd_patch1_func, 339, 1, 2 }, + { ahd_patch0_func, 340, 1, 1 }, + { ahd_patch7_func, 359, 1, 1 }, + { ahd_patch7_func, 362, 1, 1 }, + { ahd_patch7_func, 364, 1, 1 }, + { ahd_patch7_func, 376, 1, 1 }, + { ahd_patch1_func, 386, 1, 2 }, + { ahd_patch0_func, 387, 1, 1 }, + { ahd_patch1_func, 389, 1, 2 }, + { ahd_patch0_func, 390, 1, 1 }, + { ahd_patch1_func, 398, 1, 2 }, + { ahd_patch0_func, 399, 1, 1 }, + { ahd_patch2_func, 410, 1, 2 }, + { ahd_patch0_func, 411, 1, 1 }, + { ahd_patch8_func, 413, 1, 1 }, + { ahd_patch9_func, 440, 1, 1 }, + { ahd_patch1_func, 447, 1, 2 }, + { ahd_patch0_func, 448, 1, 1 }, + { ahd_patch2_func, 460, 1, 2 }, + { ahd_patch0_func, 461, 1, 1 }, + { ahd_patch10_func, 489, 1, 1 }, + { ahd_patch11_func, 498, 1, 2 }, + { ahd_patch0_func, 499, 1, 1 }, + { ahd_patch12_func, 504, 1, 1 }, + { ahd_patch11_func, 505, 1, 1 }, + { ahd_patch13_func, 518, 1, 2 }, + { ahd_patch0_func, 519, 1, 1 }, + { ahd_patch1_func, 541, 1, 2 }, + { ahd_patch0_func, 542, 1, 1 }, + { ahd_patch1_func, 545, 1, 2 }, + { ahd_patch0_func, 546, 1, 1 }, + { ahd_patch2_func, 551, 1, 2 }, + { ahd_patch0_func, 552, 1, 1 }, + { ahd_patch2_func, 556, 1, 2 }, + { ahd_patch0_func, 557, 1, 1 }, + { ahd_patch1_func, 558, 1, 2 }, + { ahd_patch0_func, 559, 1, 1 }, + { ahd_patch2_func, 570, 1, 2 }, + { ahd_patch0_func, 571, 1, 1 }, + { ahd_patch14_func, 575, 1, 1 }, + { ahd_patch15_func, 580, 1, 1 }, + { ahd_patch16_func, 581, 2, 1 }, + { ahd_patch15_func, 585, 1, 2 }, + { ahd_patch0_func, 586, 1, 1 }, + { ahd_patch2_func, 593, 1, 2 }, + { ahd_patch0_func, 594, 1, 1 }, + { ahd_patch2_func, 609, 1, 2 }, + { ahd_patch0_func, 610, 1, 1 }, + { ahd_patch1_func, 616, 1, 2 }, + { ahd_patch0_func, 617, 1, 1 }, + { ahd_patch1_func, 631, 1, 2 }, + { ahd_patch0_func, 632, 1, 1 }, + { ahd_patch1_func, 639, 1, 2 }, + { ahd_patch0_func, 640, 1, 1 }, + { ahd_patch14_func, 659, 1, 1 }, + { ahd_patch14_func, 675, 1, 1 }, + { ahd_patch2_func, 687, 1, 2 }, + { ahd_patch0_func, 688, 1, 1 }, + { ahd_patch1_func, 705, 1, 2 }, + { ahd_patch0_func, 706, 1, 1 }, + { ahd_patch14_func, 711, 1, 1 }, + { ahd_patch1_func, 731, 1, 2 }, + { ahd_patch0_func, 732, 1, 1 }, + { ahd_patch1_func, 734, 1, 2 }, + { ahd_patch0_func, 735, 1, 1 }, + { ahd_patch1_func, 737, 1, 2 }, + { ahd_patch0_func, 738, 1, 1 }, + { ahd_patch17_func, 740, 1, 2 }, + { ahd_patch0_func, 741, 2, 1 }, + { ahd_patch18_func, 744, 4, 2 }, + { ahd_patch0_func, 748, 1, 1 }, + { ahd_patch18_func, 754, 11, 1 } +}; + +static struct cs { + uint16_t begin; + uint16_t end; +} critical_sections[] = { + { 11, 12 }, + { 13, 14 }, + { 24, 37 }, + { 38, 51 }, + { 64, 67 }, + { 94, 119 }, + { 120, 151 }, + { 153, 157 }, + { 165, 173 }, + { 196, 245 }, + { 659, 675 }, + { 675, 693 }, + { 698, 704 }, + { 711, 716 }, + { 716, 722 } +}; + +static const int num_critical_sections = sizeof(critical_sections) + / sizeof(*critical_sections); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_93cx6.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_93cx6.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_93cx6.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_93cx6.c 2003-01-22 22:10:29.000000000 +0000 @@ -28,9 +28,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#15 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.8.2.5 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_93cx6.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_93cx6.h --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_93cx6.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_93cx6.h 2003-01-22 22:10:29.000000000 +0000 @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#10 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#12 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.h,v 1.7.2.3 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ #ifndef _AIC7XXX_93CX6_H_ #define _AIC7XXX_93CX6_H_ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_core.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_core.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_core.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_core.c 2003-01-22 22:10:29.000000000 +0000 @@ -1,8 +1,8 @@ /* * Core routines and tables shareable across OS platforms. * - * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2001 Adaptec Inc. + * Copyright (c) 1994-2002 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#69 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#112 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.41.2.22 2002/04/29 19:36:26 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -181,6 +181,7 @@ u_int period, u_int offset, u_int bus_width, u_int ppr_options); static void ahc_clear_msg_state(struct ahc_softc *ahc); +static void ahc_handle_proto_violation(struct ahc_softc *ahc); static void ahc_handle_message_phase(struct ahc_softc *ahc); typedef enum { AHCMSG_1B, @@ -330,7 +331,7 @@ printf("%s: WARNING no command for scb %d " "(cmdcmplt)\nQOUTPOS = %d\n", ahc_name(ahc), scb_index, - ahc->qoutfifonext - 1); + (ahc->qoutfifonext - 1) & 0xFF); continue; } @@ -437,10 +438,10 @@ scb_index = ahc_inb(ahc, SCB_TAG); scb = ahc_lookup_scb(ahc, scb_index); if (scb == NULL) { - printf("%s:%c:%d: ahc_intr - referenced scb " + ahc_print_devinfo(ahc, &devinfo); + printf("ahc_intr - referenced scb " "not valid during seqint 0x%x scb(%d)\n", - ahc_name(ahc), devinfo.channel, - devinfo.target, intstat, scb_index); + intstat, scb_index); ahc_dump_card_state(ahc); panic("for safety"); goto unpause; @@ -478,7 +479,7 @@ struct ahc_tmode_tstate *tstate; struct ahc_transinfo *tinfo; #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOWSENSE) { + if (ahc_debug & AHC_SHOW_SENSE) { ahc_print_path(ahc, scb); printf("SCB %d: requests Check Status\n", scb->hscb->tag); @@ -501,7 +502,7 @@ */ ahc_update_residual(ahc, scb); #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOWSENSE) { + if (ahc_debug & AHC_SHOW_SENSE) { ahc_print_path(ahc, scb); printf("Sending Sense\n"); } @@ -545,7 +546,7 @@ == ahc_get_transfer_length(scb)) { ahc_update_neg_request(ahc, &devinfo, tstate, targ_info, - /*force*/TRUE); + AHC_NEG_IF_NON_ASYNC); } if (tstate->auto_negotiate & devinfo.target_mask) { hscb->control |= MK_MESSAGE; @@ -561,16 +562,11 @@ scb->flags |= SCB_SENSE; ahc_qinfifo_requeue_tail(ahc, scb); ahc_outb(ahc, RETURN_1, SEND_SENSE); -#ifdef __FreeBSD__ /* * Ensure we have enough time to actually * retrieve the sense. */ - untimeout(ahc_timeout, (caddr_t)scb, - scb->io_ctx->ccb_h.timeout_ch); - scb->io_ctx->ccb_h.timeout_ch = - timeout(ahc_timeout, (caddr_t)scb, 5 * hz); -#endif + ahc_scb_timer_reset(scb, 5 * 1000000); break; } default: @@ -624,27 +620,10 @@ ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte); break; } - case NO_IDENT: + case PROTO_VIOLATION: { - /* - * The reconnecting target either did not send an identify - * message, or did, but we didn't find an SCB to match and - * before it could respond to our ATN/abort, it hit a dataphase. - * The only safe thing to do is to blow it away with a bus - * reset. - */ - int found; - - printf("%s:%c:%d: Target did not send an IDENTIFY message. " - "LASTPHASE = 0x%x, SAVED_SCSIID == 0x%x\n", - ahc_name(ahc), devinfo.channel, devinfo.target, - ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_SCSIID)); - found = ahc_reset_channel(ahc, devinfo.channel, - /*initiate reset*/TRUE); - printf("%s: Issued Channel %c Bus Reset. " - "%d SCBs aborted\n", ahc_name(ahc), devinfo.channel, - found); - return; + ahc_handle_proto_violation(ahc); + break; } case IGN_WIDE_RES: ahc_handle_ign_wide_residue(ahc, &devinfo); @@ -772,7 +751,44 @@ ahc_outb(ahc, LASTPHASE, curphase); ahc_outb(ahc, SCSISIGO, curphase); } - ahc_inb(ahc, SCSIDATL); + if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) { + int wait; + + /* + * In a data phase. Faster to bitbucket + * the data than to individually ack each + * byte. This is also the only strategy + * that will work with AUTOACK enabled. + */ + ahc_outb(ahc, SXFRCTL1, + ahc_inb(ahc, SXFRCTL1) | BITBUCKET); + wait = 5000; + while (--wait != 0) { + if ((ahc_inb(ahc, SCSISIGI) + & (CDI|MSGI)) != 0) + break; + ahc_delay(100); + } + ahc_outb(ahc, SXFRCTL1, + ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET); + if (wait == 0) { + struct scb *scb; + u_int scb_index; + + ahc_print_devinfo(ahc, &devinfo); + printf("Unable to clear parity error. " + "Resetting bus.\n"); + scb_index = ahc_inb(ahc, SCB_TAG); + scb = ahc_lookup_scb(ahc, scb_index); + if (scb != NULL) + ahc_set_transaction_status(scb, + CAM_UNCOR_PARITY); + ahc_reset_channel(ahc, devinfo.channel, + /*init reset*/TRUE); + } + } else { + ahc_inb(ahc, SCSIDATL); + } } break; } @@ -942,9 +958,6 @@ char cur_channel; char intr_channel; - /* Make sure the sequencer is in a safe location. */ - ahc_clear_critical_section(ahc); - if ((ahc->features & AHC_TWIN) != 0 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0)) cur_channel = 'B'; @@ -973,10 +986,13 @@ } } + /* Make sure the sequencer is in a safe location. */ + ahc_clear_critical_section(ahc); + scb_index = ahc_inb(ahc, SCB_TAG); scb = ahc_lookup_scb(ahc, scb_index); if (scb != NULL - && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0) + && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) scb = NULL; if ((ahc->features & AHC_ULTRA2) != 0 @@ -1023,6 +1039,7 @@ u_int scsirate; u_int i; u_int sstat2; + int silent; lastphase = ahc_inb(ahc, LASTPHASE); curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK; @@ -1050,29 +1067,47 @@ break; } mesg_out = ahc_phase_table[i].mesg_out; - if (scb != NULL) - ahc_print_path(ahc, scb); - else + silent = FALSE; + if (scb != NULL) { + if (SCB_IS_SILENT(scb)) + silent = TRUE; + else + ahc_print_path(ahc, scb); + scb->flags |= SCB_TRANSMISSION_ERROR; + } else printf("%s:%c:%d: ", ahc_name(ahc), intr_channel, SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID))); scsirate = ahc_inb(ahc, SCSIRATE); - printf("parity error detected %s. " - "SEQADDR(0x%x) SCSIRATE(0x%x)\n", - ahc_phase_table[i].phasemsg, - ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8), - scsirate); - - if ((ahc->features & AHC_DT) != 0) { + if (silent == FALSE) { + printf("parity error detected %s. " + "SEQADDR(0x%x) SCSIRATE(0x%x)\n", + ahc_phase_table[i].phasemsg, + ahc_inw(ahc, SEQADDR0), + scsirate); + if ((ahc->features & AHC_DT) != 0) { + if ((sstat2 & CRCVALERR) != 0) + printf("\tCRC Value Mismatch\n"); + if ((sstat2 & CRCENDERR) != 0) + printf("\tNo terminal CRC packet " + "recevied\n"); + if ((sstat2 & CRCREQERR) != 0) + printf("\tIllegal CRC packet " + "request\n"); + if ((sstat2 & DUAL_EDGE_ERR) != 0) + printf("\tUnexpected %sDT Data Phase\n", + (scsirate & SINGLE_EDGE) + ? "" : "non-"); + } + } - if ((sstat2 & CRCVALERR) != 0) - printf("\tCRC Value Mismatch\n"); - if ((sstat2 & CRCENDERR) != 0) - printf("\tNo terminal CRC packet recevied\n"); - if ((sstat2 & CRCREQERR) != 0) - printf("\tIllegal CRC packet request\n"); - if ((sstat2 & DUAL_EDGE_ERR) != 0) - printf("\tUnexpected %sDT Data Phase\n", - (scsirate & SINGLE_EDGE) ? "" : "non-"); + if ((ahc->features & AHC_DT) != 0 + && (sstat2 & DUAL_EDGE_ERR) != 0) { + /* + * This error applies regardless of + * data direction, so ignore the value + * in the phase table. + */ + mesg_out = MSG_INITIATOR_DET_ERR; } /* @@ -1128,21 +1163,29 @@ printf("%s: ahc_intr - referenced scb not " "valid during SELTO scb(%d, %d)\n", ahc_name(ahc), scbptr, scb_index); + ahc_dump_card_state(ahc); } else { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_SELTO) != 0) { + ahc_print_path(ahc, scb); + printf("Saw Selection Timeout for SCB 0x%x\n", + scb_index); + } +#endif + /* + * Force a renegotiation with this target just in + * case the cable was pulled and will later be + * re-attached. The target may forget its negotiation + * settings with us should it attempt to reselect + * during the interruption. The target will not issue + * a unit attention in this case, so we must always + * renegotiate. + */ + ahc_force_renegotiation(ahc); ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT); ahc_freeze_devq(ahc, scb); } ahc_outb(ahc, CLRINT, CLRSCSIINT); - /* - * Force a renegotiation with this target just in - * case the cable was pulled and will later be - * re-attached. The target may forget its negotiation - * settings with us should it attempt to reselect - * during the interruption. The target will not issue - * a unit attention in this case, so we must always - * renegotiate. - */ - ahc_force_renegotiation(ahc); ahc_restart(ahc); } else if ((status & BUSFREE) != 0 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) { @@ -1341,7 +1384,7 @@ devinfo.target, &tstate); ahc_update_neg_request(ahc, &devinfo, tstate, - targ_info, /*force*/TRUE); + targ_info, AHC_NEG_IF_NON_ASYNC); } #define AHC_MAX_STEPS 2000 @@ -1404,11 +1447,26 @@ simode0 = ahc_inb(ahc, SIMODE0); ahc_outb(ahc, SIMODE0, 0); simode1 = ahc_inb(ahc, SIMODE1); - ahc_outb(ahc, SIMODE1, 0); + if ((ahc->features & AHC_DT) != 0) + /* + * On DT class controllers, we + * use the enhanced busfree logic. + * Unfortunately we cannot re-enable + * busfree detection within the + * current connection, so we must + * leave it on while single stepping. + */ + ahc_outb(ahc, SIMODE1, ENBUSFREE); + else + ahc_outb(ahc, SIMODE1, 0); ahc_outb(ahc, CLRINT, CLRSCSIINT); ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP); stepping = TRUE; } + if ((ahc->features & AHC_DT) != 0) { + ahc_outb(ahc, CLRSINT1, CLRBUSFREE); + ahc_outb(ahc, CLRINT, CLRSCSIINT); + } ahc_outb(ahc, HCNTRL, ahc->unpause); while (!ahc_is_paused(ahc)) ahc_delay(200); @@ -1439,7 +1497,7 @@ /**************************** Debugging Routines ******************************/ #ifdef AHC_DEBUG -int ahc_debug = AHC_DEBUG; +uint32_t ahc_debug = AHC_DEBUG_OPTS; #endif void @@ -1496,7 +1554,8 @@ && ahc->enabled_targets[scsi_id] != master_tstate) panic("%s: ahc_alloc_tstate - Target already allocated", ahc_name(ahc)); - tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT); + tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate), + M_DEVBUF, M_NOWAIT); if (tstate == NULL) return (NULL); @@ -1593,6 +1652,10 @@ else transinfo = &tinfo->goal; *ppr_options &= transinfo->ppr_options; + if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { + maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2); + *ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } if (transinfo->period == 0) { *period = 0; *ppr_options = 0; @@ -1769,17 +1832,29 @@ int ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, struct ahc_tmode_tstate *tstate, - struct ahc_initiator_tinfo *tinfo, int force) + struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type) { u_int auto_negotiate_orig; auto_negotiate_orig = tstate->auto_negotiate; + if (neg_type == AHC_NEG_ALWAYS) { + /* + * Force our "current" settings to be + * unknown so that unless a bus reset + * occurs the need to renegotiate is + * recorded persistently. + */ + if ((ahc->features & AHC_WIDE) != 0) + tinfo->curr.width = AHC_WIDTH_UNKNOWN; + tinfo->curr.period = AHC_PERIOD_UNKNOWN; + tinfo->curr.offset = AHC_OFFSET_UNKNOWN; + } if (tinfo->curr.period != tinfo->goal.period || tinfo->curr.width != tinfo->goal.width || tinfo->curr.offset != tinfo->goal.offset || tinfo->curr.ppr_options != tinfo->goal.ppr_options - || (force - && (tinfo->goal.period != 0 + || (neg_type == AHC_NEG_IF_NON_ASYNC + && (tinfo->goal.offset != 0 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT || tinfo->goal.ppr_options != 0))) tstate->auto_negotiate |= devinfo->target_mask; @@ -1910,7 +1985,7 @@ } update_needed += ahc_update_neg_request(ahc, devinfo, tstate, - tinfo, /*force*/FALSE); + tinfo, AHC_NEG_TO_GOAL); if (update_needed) ahc_update_pending_scbs(ahc); @@ -1972,7 +2047,7 @@ } update_needed += ahc_update_neg_request(ahc, devinfo, tstate, - tinfo, /*force*/FALSE); + tinfo, AHC_NEG_TO_GOAL); if (update_needed) ahc_update_pending_scbs(ahc); } @@ -2086,7 +2161,8 @@ if (role == ROLE_TARGET && (ahc->features & AHC_MULTI_TID) != 0 - && (ahc_inb(ahc, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) { + && (ahc_inb(ahc, SEQ_FLAGS) + & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) { /* We were selected, so pull our id from TARGIDIN */ our_id = ahc_inb(ahc, TARGIDIN) & OID; } else if ((ahc->features & AHC_ULTRA2) != 0) @@ -2136,6 +2212,13 @@ devinfo->target_mask = (0x01 << devinfo->target_offset); } +void +ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) +{ + printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel, + devinfo->target, devinfo->lun); +} + static void ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, struct scb *scb) @@ -2145,7 +2228,7 @@ our_id = SCSIID_OUR_ID(scb->hscb->scsiid); role = ROLE_INITIATOR; - if ((scb->hscb->control & TARGET_SCB) != 0) + if ((scb->flags & SCB_TARGET_SCB) != 0) role = ROLE_TARGET; ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb), SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role); @@ -2270,7 +2353,6 @@ int dowide; int dosync; int doppr; - int use_ppr; u_int period; u_int ppr_options; u_int offset; @@ -2292,23 +2374,37 @@ &ppr_options, devinfo->role); dowide = tinfo->curr.width != tinfo->goal.width; dosync = tinfo->curr.period != period; - doppr = tinfo->curr.ppr_options != ppr_options; + /* + * Only use PPR if we have options that need it, even if the device + * claims to support it. There might be an expander in the way + * that doesn't. + */ + doppr = ppr_options != 0; if (!dowide && !dosync && !doppr) { dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT; - dosync = tinfo->goal.period != 0; - doppr = tinfo->goal.ppr_options != 0; + dosync = tinfo->goal.offset != 0; } if (!dowide && !dosync && !doppr) { - panic("ahc_intr: AWAITING_MSG for negotiation, " - "but no negotiation needed\n"); + /* + * Force async with a WDTR message if we have a wide bus, + * or just issue an SDTR with a 0 offset. + */ + if ((ahc->features & AHC_WIDE) != 0) + dowide = 1; + else + dosync = 1; + + if (bootverbose) { + ahc_print_devinfo(ahc, devinfo); + printf("Ensuring async\n"); + } } - use_ppr = (tinfo->curr.transport_version >= 3) || doppr; /* Target initiated PPR is not allowed in the SCSI spec */ if (devinfo->role == ROLE_TARGET) - use_ppr = 0; + doppr = 0; /* * Both the PPR message and SDTR message require the @@ -2318,14 +2414,14 @@ * Regardless, guarantee that if we are using WDTR and SDTR * messages that WDTR comes first. */ - if (use_ppr || (dosync && !dowide)) { + if (doppr || (dosync && !dowide)) { offset = tinfo->goal.offset; ahc_validate_offset(ahc, tinfo, rate, &offset, - use_ppr ? tinfo->goal.width - : tinfo->curr.width, + doppr ? tinfo->goal.width + : tinfo->curr.width, devinfo->role); - if (use_ppr) { + if (doppr) { ahc_construct_ppr(ahc, devinfo, period, offset, tinfo->goal.width, ppr_options); } else { @@ -2344,6 +2440,8 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, u_int period, u_int offset) { + if (offset == 0) + period = AHC_ASYNC_XFER_PERIOD; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR; @@ -2386,6 +2484,8 @@ u_int period, u_int offset, u_int bus_width, u_int ppr_options) { + if (offset == 0) + period = AHC_ASYNC_XFER_PERIOD; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR; @@ -2424,6 +2524,100 @@ ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING); } +static void +ahc_handle_proto_violation(struct ahc_softc *ahc) +{ + struct ahc_devinfo devinfo; + struct scb *scb; + u_int scbid; + u_int seq_flags; + u_int curphase; + u_int lastphase; + int found; + + ahc_fetch_devinfo(ahc, &devinfo); + scbid = ahc_inb(ahc, SCB_TAG); + scb = ahc_lookup_scb(ahc, scbid); + seq_flags = ahc_inb(ahc, SEQ_FLAGS); + curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK; + lastphase = ahc_inb(ahc, LASTPHASE); + if ((seq_flags & NOT_IDENTIFIED) != 0) { + + /* + * The reconnecting target either did not send an + * identify message, or did, but we didn't find an SCB + * to match. + */ + ahc_print_devinfo(ahc, &devinfo); + printf("Target did not send an IDENTIFY message. " + "LASTPHASE = 0x%x.\n", lastphase); + scb = NULL; + } else if (scb == NULL) { + /* + * We don't seem to have an SCB active for this + * transaction. Print an error and reset the bus. + */ + ahc_print_devinfo(ahc, &devinfo); + printf("No SCB found during protocol violation\n"); + goto proto_violation_reset; + } else { + ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL); + if ((seq_flags & NO_CDB_SENT) != 0) { + ahc_print_path(ahc, scb); + printf("No or incomplete CDB sent to device.\n"); + } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) { + /* + * The target never bothered to provide status to + * us prior to completing the command. Since we don't + * know the disposition of this command, we must attempt + * to abort it. Assert ATN and prepare to send an abort + * message. + */ + ahc_print_path(ahc, scb); + printf("Completed command without status.\n"); + } else { + ahc_print_path(ahc, scb); + printf("Unknown protocol violation.\n"); + ahc_dump_card_state(ahc); + } + } + if ((lastphase & ~P_DATAIN_DT) == 0 + || lastphase == P_COMMAND) { +proto_violation_reset: + /* + * Target either went directly to data/command + * phase or didn't respond to our ATN. + * The only safe thing to do is to blow + * it away with a bus reset. + */ + found = ahc_reset_channel(ahc, 'A', TRUE); + printf("%s: Issued Channel %c Bus Reset. " + "%d SCBs aborted\n", ahc_name(ahc), 'A', found); + } else { + /* + * Leave the selection hardware off in case + * this abort attempt will affect yet to + * be sent commands. + */ + ahc_outb(ahc, SCSISEQ, + ahc_inb(ahc, SCSISEQ) & ~ENSELO); + ahc_assert_atn(ahc); + ahc_outb(ahc, MSG_OUT, HOST_MSG); + if (scb == NULL) { + ahc_print_devinfo(ahc, &devinfo); + ahc->msgout_buf[0] = MSG_ABORT_TASK; + ahc->msgout_len = 1; + ahc->msgout_index = 0; + ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + } else { + ahc_print_path(ahc, scb); + scb->flags |= SCB_ABORT; + } + printf("Protocol violation %s. Attempting to abort.\n", + ahc_lookup_phase_entry(curphase)->phasemsg); + } +} + /* * Manual message loop handler. */ @@ -2449,8 +2643,21 @@ if (ahc->msgout_len == 0) panic("HOST_MSG_LOOP interrupt with no active message"); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("INITIATOR_MSG_OUT"); + } +#endif phasemis = bus_phase != P_MESGOUT; if (phasemis) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahc_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif if (bus_phase == P_MESGIN) { /* * Change gears and see if @@ -2471,6 +2678,10 @@ if (ahc->send_msg_perror) { ahc_outb(ahc, CLRSINT1, CLRATNO); ahc_outb(ahc, CLRSINT1, CLRREQINIT); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", ahc->send_msg_perror); +#endif ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR); break; } @@ -2497,6 +2708,11 @@ * the next byte on the bus. */ ahc_outb(ahc, CLRSINT1, CLRREQINIT); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahc->msgout_buf[ahc->msgout_index]); +#endif ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]); break; } @@ -2505,9 +2721,21 @@ int phasemis; int message_done; +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("INITIATOR_MSG_IN"); + } +#endif phasemis = bus_phase != P_MESGIN; - if (phasemis) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahc_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif ahc->msgin_index = 0; if (bus_phase == P_MESGOUT && (ahc->send_msg_perror == TRUE @@ -2522,6 +2750,11 @@ /* Pull the byte in without acking it */ ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahc->msgin_buf[ahc->msgin_index]); +#endif message_done = ahc_parse_msg(ahc, &devinfo); @@ -2537,8 +2770,15 @@ * assert ATN so the target takes us to the * message out phase. */ - if (ahc->msgout_len != 0) + if (ahc->msgout_len != 0) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("Asserting ATN for response\n"); + } +#endif ahc_assert_atn(ahc); + } } else ahc->msgin_index++; @@ -2939,7 +3179,7 @@ AHC_TRANS_ACTIVE, /*paused*/TRUE); if (sending_reply == FALSE && reject == FALSE) { - if (tinfo->goal.period) { + if (tinfo->goal.offset) { ahc->msgout_index = 0; ahc->msgout_len = 0; ahc_build_transfer_msg(ahc, devinfo); @@ -3204,7 +3444,7 @@ * but rejected our response, we already cleared the * sync rate before sending our WDTR. */ - if (tinfo->goal.period) { + if (tinfo->goal.offset != tinfo->curr.offset) { /* Start the sync negotiation */ ahc->msgout_index = 0; @@ -3806,6 +4046,14 @@ * to disturb the integrity of the bus. */ ahc_pause(ahc); + if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) { + /* + * The chip has not been initialized since + * PCI/EISA/VLB bus reset. Don't trust + * "left over BIOS data". + */ + ahc->flags |= AHC_NO_BIOS_INIT; + } sxfrctl1_b = 0; if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) { u_int sblkctl; @@ -4069,7 +4317,7 @@ scb_data->init_level++; /* DMA tag for our S/G structures. We allocate in page sized chunks */ - if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1, + if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/8, /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, @@ -4300,8 +4548,9 @@ size_t driver_data_size; uint32_t physaddr; -#ifdef AHC_DEBUG_SEQUENCER - ahc->flags |= AHC_SEQUENCER_DEBUG; +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0) + ahc->flags |= AHC_SEQUENCER_DEBUG; #endif #ifdef AHC_PRINT_SRAM @@ -4354,7 +4603,8 @@ /*lowaddr*/BUS_SPACE_MAXADDR, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG, + /*maxsize*/(AHC_NSEG - 1) * PAGE_SIZE, + /*nsegments*/AHC_NSEG, /*maxsegsz*/AHC_MAXTRANSFER_SIZE, /*flags*/BUS_DMA_ALLOCNOW, &ahc->buffer_dmat) != 0) { @@ -4457,7 +4707,7 @@ } #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOWMISC) { + if (ahc_debug & AHC_SHOW_MISC) { printf("%s: hardware scb %d bytes; kernel scb %d bytes; " "ahc_dma %d bytes\n", ahc_name(ahc), @@ -4635,7 +4885,7 @@ tinfo->curr.protocol_version = 2; tinfo->curr.transport_version = 2; } - tstate->ultraenb = ultraenb; + tstate->ultraenb = 0; } ahc->user_discenable = discenable; ahc->user_tagenable = tagenable; @@ -4792,21 +5042,28 @@ { int intstat; int maxloops; + int paused; maxloops = 1000; ahc->flags |= AHC_ALL_INTERRUPTS; intstat = 0; + paused = FALSE; do { + if (paused) + ahc_unpause(ahc); ahc_intr(ahc); ahc_pause(ahc); + paused = TRUE; + ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO); ahc_clear_critical_section(ahc); if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) break; - maxloops--; - } while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops); + } while (--maxloops + && (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) != 0 + || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)))); if (maxloops == 0) { printf("Infinite interrupt loop, INTSTAT = %x", - ahc_inb(ahc, INTSTAT)); + ahc_inb(ahc, INTSTAT)); } ahc_platform_flushwork(ahc); ahc->flags &= ~AHC_ALL_INTERRUPTS; @@ -5139,8 +5396,8 @@ static int ahc_qinfifo_count(struct ahc_softc *ahc) { - u_int8_t qinpos; - u_int8_t diff; + uint8_t qinpos; + uint8_t diff; if ((ahc->features & AHC_QUEUE_REGS) != 0) { qinpos = ahc_inb(ahc, SNSCB_QOFF); @@ -5444,6 +5701,7 @@ break; } case SEARCH_REMOVE: + scb->flags &= ~SCB_UNTAGGEDQ; TAILQ_REMOVE(untagged_q, scb, links.tqe); break; case SEARCH_COUNT: @@ -6017,9 +6275,10 @@ ahc_set_sense_residual(scb, resid); #ifdef AHC_DEBUG - if ((ahc_debug & AHC_SHOWMISC) != 0) { + if ((ahc_debug & AHC_SHOW_MISC) != 0) { ahc_print_path(ahc, scb); - printf("Handled Residual of %d bytes\n", resid); + printf("Handled %sResidual of %d bytes\n", + (scb->flags & SCB_SENSE) ? "Sense " : "", resid); } #endif } @@ -6234,8 +6493,11 @@ ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE); ahc_restart(ahc); - if (bootverbose) + if (bootverbose) { printf(" %d instructions downloaded\n", downloaded); + printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", + ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags); + } } static int @@ -6399,14 +6661,64 @@ } } +int +ahc_print_register(ahc_reg_parse_entry_t *table, u_int num_entries, + const char *name, u_int address, u_int value, + u_int *cur_column, u_int wrap_point) +{ + int printed; + u_int printed_mask; + + if (cur_column != NULL && *cur_column >= wrap_point) { + printf("\n"); + *cur_column = 0; + } + printed = printf("%s[0x%x]", name, value); + if (table == NULL) { + printed += printf(" "); + *cur_column += printed; + return (printed); + } + printed_mask = 0; + while (printed_mask != 0xFF) { + int entry; + + for (entry = 0; entry < num_entries; entry++) { + if (((value & table[entry].mask) + != table[entry].value) + || ((printed_mask & table[entry].mask) + == table[entry].mask)) + continue; + + printed += printf("%s%s", + printed_mask == 0 ? ":(" : "|", + table[entry].name); + printed_mask |= table[entry].mask; + + break; + } + if (entry >= num_entries) + break; + } + if (printed_mask != 0) + printed += printf(") "); + else + printed += printf(" "); + if (cur_column != NULL) + *cur_column += printed; + return (printed); +} + void ahc_dump_card_state(struct ahc_softc *ahc) { - struct scb *scb; - struct scb_tailq *untagged_q; - int target; - int maxtarget; - int i; + struct scb *scb; + struct scb_tailq *untagged_q; + u_int cur_col; + int paused; + int target; + int maxtarget; + int i; uint8_t last_phase; uint8_t qinpos; uint8_t qintail; @@ -6414,33 +6726,53 @@ uint8_t scb_index; uint8_t saved_scbptr; - saved_scbptr = ahc_inb(ahc, SCBPTR); + if (ahc_is_paused(ahc)) { + paused = 1; + } else { + paused = 0; + ahc_pause(ahc); + } + saved_scbptr = ahc_inb(ahc, SCBPTR); last_phase = ahc_inb(ahc, LASTPHASE); - printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n", + printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" + "%s: Dumping Card State %s, at SEQADDR 0x%x\n", ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg, ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); + if (paused) + printf("Card was paused\n"); printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n", ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX), ahc_inb(ahc, ARG_2)); printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT), ahc_inb(ahc, SCBPTR)); - printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x\n", - ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL)); - printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%x\n", - ahc_inb(ahc, DFCNTRL), ahc_inb(ahc, DFSTATUS)); - printf("LASTPHASE = 0x%x, SCSISIGI = 0x%x, SXFRCTL0 = 0x%x\n", - last_phase, ahc_inb(ahc, SCSISIGI), ahc_inb(ahc, SXFRCTL0)); - printf("SSTAT0 = 0x%x, SSTAT1 = 0x%x\n", - ahc_inb(ahc, SSTAT0), ahc_inb(ahc, SSTAT1)); + cur_col = 0; if ((ahc->features & AHC_DT) != 0) - printf("SCSIPHASE = 0x%x\n", ahc_inb(ahc, SCSIPHASE)); - printf("STACK == 0x%x, 0x%x, 0x%x, 0x%x\n", - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8), - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8), - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8), - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8)); - printf("SCB count = %d\n", ahc->scb_data->numscbs); + ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50); + ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50); + ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50); + ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50); + ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50); + ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50); + ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50); + ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50); + ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50); + ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50); + ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50); + ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50); + ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50); + ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50); + ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50); + ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50); + ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50); + ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50); + ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50); + if (cur_col != 0) + printf("\n"); + printf("STACK:"); + for (i = 0; i < STACK_SIZE; i++) + printf(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8)); + printf("\nSCB count = %d\n", ahc->scb_data->numscbs); printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag); printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB)); /* QINFIFO */ @@ -6500,11 +6832,12 @@ printf("Sequencer SCB Info: "); for (i = 0; i < ahc->scb_data->maxhscbs; i++) { ahc_outb(ahc, SCBPTR, i); - printf("%d(c 0x%x, s 0x%x, l %d, t 0x%x) ", - i, ahc_inb(ahc, SCB_CONTROL), - ahc_inb(ahc, SCB_SCSIID), - ahc_inb(ahc, SCB_LUN), - ahc_inb(ahc, SCB_TAG)); + cur_col = printf("\n%3d ", i); + + ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60); + ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60); + ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60); + ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60); } printf("\n"); @@ -6513,14 +6846,17 @@ LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) { if (i++ > 256) break; - if (scb != LIST_FIRST(&ahc->pending_scbs)) - printf(", "); - printf("%d(c 0x%x, s 0x%x, l %d)", scb->hscb->tag, - scb->hscb->control, scb->hscb->scsiid, scb->hscb->lun); + cur_col = printf("\n%3d ", scb->hscb->tag); + ahc_scb_control_print(scb->hscb->control, &cur_col, 60); + ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60); + ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60); if ((ahc->flags & AHC_PAGESCBS) == 0) { ahc_outb(ahc, SCBPTR, scb->hscb->tag); - printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL), - ahc_inb(ahc, SCB_TAG)); + printf("("); + ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), + &cur_col, 60); + ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60); + printf(")"); } } printf("\n"); @@ -6550,7 +6886,10 @@ } ahc_platform_dump_card_state(ahc); + printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); ahc_outb(ahc, SCBPTR, saved_scbptr); + if (paused == 0) + ahc_unpause(ahc); } /************************* Target Mode ****************************************/ @@ -6606,6 +6945,7 @@ u_int target; u_int lun; u_int target_mask; + u_int our_id; u_long s; char channel; @@ -6617,15 +6957,33 @@ return; } - if ((ahc->features & AHC_MULTIROLE) != 0) { - u_int our_id; + if (cam_sim_bus(sim) == 0) + our_id = ahc->our_id; + else + our_id = ahc->our_id_b; - if (cam_sim_bus(sim) == 0) - our_id = ahc->our_id; - else - our_id = ahc->our_id_b; + if (ccb->ccb_h.target_id != our_id) { + /* + * our_id represents our initiator ID, or + * the ID of the first target to have an + * enabled lun in target mode. There are + * two cases that may preclude enabling a + * target id other than our_id. + * + * o our_id is for an active initiator role. + * Since the hardware does not support + * reselections to the initiator role at + * anything other than our_id, and our_id + * is used by the hardware to indicate the + * ID to use for both select-out and + * reselect-out operations, the only target + * ID we can support in this mode is our_id. + * + * o The MULTARGID feature is not available and + * a previous target mode ID has been enabled. + */ + if ((ahc->features & AHC_MULTIROLE) != 0) { - if (ccb->ccb_h.target_id != our_id) { if ((ahc->features & AHC_MULTI_TID) != 0 && (ahc->flags & AHC_INITIATORROLE) != 0) { /* @@ -6647,6 +7005,10 @@ */ status = CAM_TID_INVALID; } + } else if ((ahc->features & AHC_MULTI_TID) == 0 + && ahc->enabled_luns > 0) { + + status = CAM_TID_INVALID; } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx.h --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx.h 2003-01-22 22:10:29.000000000 +0000 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#45 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#70 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.16.2.13 2002/04/29 19:36:29 gibbs Exp $ + * $FreeBSD$ */ #ifndef _AIC7XXX_H_ @@ -98,6 +98,14 @@ (SCB_GET_TARGET(ahc, scb) + (SCB_IS_SCSIBUS_B(ahc, scb) ? 8 : 0)) #define SCB_GET_TARGET_MASK(ahc, scb) \ (0x01 << (SCB_GET_TARGET_OFFSET(ahc, scb))) +#ifdef AHC_DEBUG +#define SCB_IS_SILENT(scb) \ + ((ahc_debug & AHC_SHOW_MASKED_ERRORS) == 0 \ + && (((scb)->flags & SCB_SILENT) != 0)) +#else +#define SCB_IS_SILENT(scb) \ + (((scb)->flags & SCB_SILENT) != 0) +#endif #define TCL_TARGET_OFFSET(tcl) \ ((((tcl) >> 4) & TID) >> 4) #define TCL_LUN(tcl) \ @@ -171,7 +179,7 @@ #define AHC_TMODE_CMDS 256 /* Reset line assertion time in us */ -#define AHC_BUSRESET_DELAY 250 +#define AHC_BUSRESET_DELAY 25 /******************* Chip Characteristics/Operating Settings *****************/ /* @@ -310,11 +318,11 @@ */ typedef enum { AHC_FNONE = 0x000, - AHC_PRIMARY_CHANNEL = 0x003,/* + AHC_PRIMARY_CHANNEL = 0x003, /* * The channel that should * be probed first. */ - AHC_USEDEFAULTS = 0x004,/* + AHC_USEDEFAULTS = 0x004, /* * For cards without an seeprom * or a BIOS to initialize the chip's * SRAM, we use the default target @@ -322,29 +330,29 @@ */ AHC_SEQUENCER_DEBUG = 0x008, AHC_SHARED_SRAM = 0x010, - AHC_LARGE_SEEPROM = 0x020,/* Uses C56_66 not C46 */ + AHC_LARGE_SEEPROM = 0x020, /* Uses C56_66 not C46 */ AHC_RESET_BUS_A = 0x040, AHC_RESET_BUS_B = 0x080, AHC_EXTENDED_TRANS_A = 0x100, AHC_EXTENDED_TRANS_B = 0x200, AHC_TERM_ENB_A = 0x400, AHC_TERM_ENB_B = 0x800, - AHC_INITIATORROLE = 0x1000,/* + AHC_INITIATORROLE = 0x1000, /* * Allow initiator operations on * this controller. */ - AHC_TARGETROLE = 0x2000,/* + AHC_TARGETROLE = 0x2000, /* * Allow target operations on this * controller. */ AHC_NEWEEPROM_FMT = 0x4000, AHC_RESOURCE_SHORTAGE = 0x8000, - AHC_TQINFIFO_BLOCKED = 0x10000,/* Blocked waiting for ATIOs */ - AHC_INT50_SPEEDFLEX = 0x20000,/* + AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */ + AHC_INT50_SPEEDFLEX = 0x20000, /* * Internal 50pin connector * sits behind an aic3860 */ - AHC_SCB_BTT = 0x40000,/* + AHC_SCB_BTT = 0x40000, /* * The busy targets table is * stored in SCB space rather * than SRAM. @@ -355,7 +363,9 @@ AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */ AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */ AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */ - AHC_SCB_CONFIG_USED = 0x4000000 /* No SEEPROM but SCB2 had info. */ + AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */ + AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */ + AHC_DISABLE_PCI_PERR = 0x10000000 } ahc_flag; /************************* Hardware SCB Definition ***************************/ @@ -534,10 +544,27 @@ SCB_RECOVERY_SCB = 0x0020, SCB_AUTO_NEGOTIATE = 0x0040,/* Negotiate to achieve goal. */ SCB_NEGOTIATE = 0x0080,/* Negotiation forced for command. */ - SCB_ABORT = 0x1000, - SCB_UNTAGGEDQ = 0x2000, - SCB_ACTIVE = 0x4000, - SCB_TARGET_IMMEDIATE = 0x8000 + SCB_ABORT = 0x0100, + SCB_UNTAGGEDQ = 0x0200, + SCB_ACTIVE = 0x0400, + SCB_TARGET_IMMEDIATE = 0x0800, + SCB_TRANSMISSION_ERROR = 0x1000,/* + * We detected a parity or CRC + * error that has effected the + * payload of the command. This + * flag is checked when normal + * status is returned to catch + * the case of a target not + * responding to our attempt + * to report the error. + */ + SCB_TARGET_SCB = 0x2000, + SCB_SILENT = 0x4000 /* + * Be quiet about transmission type + * errors. They are expected and we + * don't want to upset the user. This + * flag is typically used during DV. + */ } scb_flag; struct scb { @@ -662,6 +689,11 @@ #define AHC_TRANS_GOAL 0x04 /* Modify negotiation goal */ #define AHC_TRANS_USER 0x08 /* Modify user negotiation settings */ +#define AHC_WIDTH_UNKNOWN 0xFF +#define AHC_PERIOD_UNKNOWN 0xFF +#define AHC_OFFSET_UNKNOWN 0x0 +#define AHC_PPR_OPTS_UNKNOWN 0xFF + /* * Transfer Negotiation Information. */ @@ -716,10 +748,9 @@ char *rate; }; -/* - * The synchronouse transfer rate table. - */ -extern struct ahc_syncrate ahc_syncrates[]; +/* Safe and valid period for async negotiations. */ +#define AHC_ASYNC_XFER_PERIOD 0x45 +#define AHC_ULTRA2_XFER_PERIOD 0x0a /* * Indexes into our table of syncronous transfer rates. @@ -728,6 +759,8 @@ #define AHC_SYNCRATE_ULTRA2 1 #define AHC_SYNCRATE_ULTRA 3 #define AHC_SYNCRATE_FAST 6 +#define AHC_SYNCRATE_MAX AHC_SYNCRATE_DT +#define AHC_SYNCRATE_MIN 13 /***************************** Lookup Tables **********************************/ /* @@ -802,7 +835,7 @@ #define CFSEAUTOTERM 0x0400 /* Ultra2 Perform secondary Auto Term*/ #define CFSELOWTERM 0x0800 /* Ultra2 secondary low term */ #define CFSEHIGHTERM 0x1000 /* Ultra2 secondary high term */ -#define CFDOMAINVAL 0x4000 /* Perform Domain Validation*/ +#define CFENABLEDV 0x4000 /* Perform Domain Validation*/ /* * Bus Release Time, Host Adapter ID @@ -869,6 +902,7 @@ }; typedef void (*ahc_bus_intr_t)(struct ahc_softc *); +typedef void ahc_callback_t (void *); struct ahc_softc { bus_space_tag_t tag; @@ -1021,6 +1055,8 @@ /* PCI cacheline size. */ u_int pci_cachesize; + u_int stack_size; + /* Per-Unit descriptive information */ const char *description; char *name; @@ -1093,6 +1129,7 @@ struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t); int ahc_pci_config(struct ahc_softc *, struct ahc_pci_identity *); +int ahc_pci_test_register_access(struct ahc_softc *); /*************************** EISA/VL Front End ********************************/ struct aic7770_identity *aic7770_find_device(uint32_t); @@ -1191,11 +1228,20 @@ struct ahc_initiator_tinfo *tinfo, u_int *bus_width, role_t role); +/* + * Negotiation types. These are used to qualify if we should renegotiate + * even if our goal and current transport parameters are identical. + */ +typedef enum { + AHC_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */ + AHC_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */ + AHC_NEG_ALWAYS /* Renegotiat even if goal is async. */ +} ahc_neg_type; int ahc_update_neg_request(struct ahc_softc*, struct ahc_devinfo*, struct ahc_tmode_tstate*, struct ahc_initiator_tinfo*, - int /*force*/); + ahc_neg_type); void ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, u_int width, u_int type, int paused); @@ -1232,12 +1278,32 @@ #endif /******************************* Debug ***************************************/ #ifdef AHC_DEBUG -extern int ahc_debug; -#define AHC_SHOWMISC 0x1 -#define AHC_SHOWSENSE 0x2 +extern uint32_t ahc_debug; +#define AHC_SHOW_MISC 0x0001 +#define AHC_SHOW_SENSE 0x0002 +#define AHC_DUMP_SEEPROM 0x0004 +#define AHC_SHOW_TERMCTL 0x0008 +#define AHC_SHOW_MEMORY 0x0010 +#define AHC_SHOW_MESSAGES 0x0020 +#define AHC_SHOW_DV 0x0040 +#define AHC_SHOW_SELTO 0x0080 +#define AHC_SHOW_QFULL 0x0200 +#define AHC_SHOW_QUEUE 0x0400 +#define AHC_SHOW_TQIN 0x0800 +#define AHC_SHOW_MASKED_ERRORS 0x1000 +#define AHC_DEBUG_SEQUENCER 0x2000 #endif void ahc_print_scb(struct scb *scb); +void ahc_print_devinfo(struct ahc_softc *ahc, + struct ahc_devinfo *dev); void ahc_dump_card_state(struct ahc_softc *ahc); +int ahc_print_register(ahc_reg_parse_entry_t *table, + u_int num_entries, + const char *name, + u_int address, + u_int value, + u_int *cur_column, + u_int wrap_point); /******************************* SEEPROM *************************************/ int ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_inline.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_inline.h --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_inline.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_inline.h 2003-01-22 22:10:29.000000000 +0000 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#35 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#39 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.2.2.11 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ #ifndef _AIC7XXX_INLINE_H_ @@ -238,6 +238,18 @@ char channel, u_int our_id, u_int remote_id, struct ahc_tmode_tstate **tstate); +static __inline uint16_t + ahc_inw(struct ahc_softc *ahc, u_int port); +static __inline void ahc_outw(struct ahc_softc *ahc, u_int port, + u_int value); +static __inline uint32_t + ahc_inl(struct ahc_softc *ahc, u_int port); +static __inline void ahc_outl(struct ahc_softc *ahc, u_int port, + uint32_t value); +static __inline uint64_t + ahc_inq(struct ahc_softc *ahc, u_int port); +static __inline void ahc_outq(struct ahc_softc *ahc, u_int port, + uint64_t value); static __inline struct scb* ahc_get_scb(struct ahc_softc *ahc); static __inline void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb); @@ -285,6 +297,63 @@ return (&(*tstate)->transinfo[remote_id]); } +static __inline uint16_t +ahc_inw(struct ahc_softc *ahc, u_int port) +{ + return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port)); +} + +static __inline void +ahc_outw(struct ahc_softc *ahc, u_int port, u_int value) +{ + ahc_outb(ahc, port, value & 0xFF); + ahc_outb(ahc, port+1, (value >> 8) & 0xFF); +} + +static __inline uint32_t +ahc_inl(struct ahc_softc *ahc, u_int port) +{ + return ((ahc_inb(ahc, port)) + | (ahc_inb(ahc, port+1) << 8) + | (ahc_inb(ahc, port+2) << 16) + | (ahc_inb(ahc, port+3) << 24)); +} + +static __inline void +ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value) +{ + ahc_outb(ahc, port, (value) & 0xFF); + ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF); + ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF); + ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF); +} + +static __inline uint64_t +ahc_inq(struct ahc_softc *ahc, u_int port) +{ + return ((ahc_inb(ahc, port)) + | (ahc_inb(ahc, port+1) << 8) + | (ahc_inb(ahc, port+2) << 16) + | (ahc_inb(ahc, port+3) << 24) + | (((uint64_t)ahc_inb(ahc, port+4)) << 32) + | (((uint64_t)ahc_inb(ahc, port+5)) << 40) + | (((uint64_t)ahc_inb(ahc, port+6)) << 48) + | (((uint64_t)ahc_inb(ahc, port+7)) << 56)); +} + +static __inline void +ahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value) +{ + ahc_outb(ahc, port, value & 0xFF); + ahc_outb(ahc, port+1, (value >> 8) & 0xFF); + ahc_outb(ahc, port+2, (value >> 16) & 0xFF); + ahc_outb(ahc, port+3, (value >> 24) & 0xFF); + ahc_outb(ahc, port+4, (value >> 32) & 0xFF); + ahc_outb(ahc, port+5, (value >> 40) & 0xFF); + ahc_outb(ahc, port+6, (value >> 48) & 0xFF); + ahc_outb(ahc, port+7, (value >> 56) & 0xFF); +} + /* * Get a free scb. If there are none, see if we can allocate a new SCB. */ @@ -494,6 +563,15 @@ { u_int intstat; + if ((ahc->pause & INTEN) == 0) { + /* + * Our interrupt is not enabled on the chip + * and may be disabled for re-entrancy reasons, + * so just return. This is likely just a shared + * interrupt. + */ + return; + } /* * Instead of directly reading the interrupt status register, * infer the cause of the interrupt by checking our in-core diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_osm.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_osm.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-01-22 22:10:29.000000000 +0000 @@ -1,7 +1,7 @@ /* * Adaptec AIC7xxx device driver for Linux. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#103 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#179 $ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. @@ -127,16 +127,31 @@ #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" +#include + +/* + * Include aiclib.c as part of our + * "module dependencies are hard" work around. + */ +#include "aiclib.c" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) #include /* __setup */ #endif -#include "../sd.h" /* For geometry detection */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include "sd.h" /* For geometry detection */ +#endif #include /* For fetching system memory size */ #include /* For block_size() */ +#define __KERNEL_SYSCALLS__ + +#include +static int errno; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) /* * Lock protecting manipulation of the ahc softc list. @@ -280,6 +295,39 @@ }; /* + * DV option: + * + * positive value = DV Enabled + * zero = DV Disabled + * negative value = DV Default for adapter type/seeprom + */ +#ifdef CONFIG_AIC7XXX_DV_SETTING +#define AIC7XXX_CONFIGED_DV CONFIG_AIC7XXX_DV_SETTING +#else +#define AIC7XXX_CONFIGED_DV -1 +#endif + +static uint8_t aic7xxx_dv_settings[] = +{ + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV +}; + +/* * There should be a specific return value for this in scsi.h, but * it seems that most drivers ignore it. */ @@ -371,6 +419,14 @@ #endif /* + * There are lots of broken chipsets in the world. Some of them will + * violate the PCI spec when we issue byte sized memory writes to our + * controller. I/O mapped register access, if allowed by the given + * platform, will work in almost all cases. + */ +int aic7xxx_allow_memio = 1; + +/* * aic7xxx_detect() has been run, so register all device arrivals * immediately with the system rather than deferring to the sorted * attachment performed by aic7xxx_detect(). @@ -413,49 +469,97 @@ MODULE_AUTHOR("Maintainer: Justin T. Gibbs "); MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10) +#ifdef MODULE_LICENSE MODULE_LICENSE("Dual BSD/GPL"); #endif MODULE_PARM(aic7xxx, "s"); -MODULE_PARM_DESC(aic7xxx, "period delimited, options string. - verbose Enable verbose/diagnostic logging - no_probe Disable EISA/VLB controller probing - no_reset Supress initial bus resets - extended Enable extended geometry on all controllers - periodic_otag Send an ordered tagged transaction periodically - to prevent tag starvation. This may be - required by some older disk drives/RAID arrays. - reverse_scan Sort PCI devices highest Bus/Slot to lowest - tag_info: Set per-target tag depth - seltime: Selection Timeout(0/256ms,1/128ms,2/64ms,3/32ms) - - Sample /etc/modules.conf line: - Enable verbose logging - Disable EISA/VLB probing - Set tag depth on Controller 2/Target 2 to 10 tags - Shorten the selection timeout to 128ms from its default of 256 - - options aic7xxx='\"verbose.no_probe.tag_info:{{}.{}.{..10}}.seltime:1\"' -"); +MODULE_PARM_DESC(aic7xxx, +"period delimited, options string.\n" +" verbose Enable verbose/diagnostic logging\n" +" allow_memio Allow device registers to be memory mapped\n" +" debug Bitmask of debug values to enable\n" +" no_probe Disable EISA/VLB controller probing\n" +" no_reset Supress initial bus resets\n" +" extended Enable extended geometry on all controllers\n" +" periodic_otag Send an ordered tagged transaction\n" +" periodically to prevent tag starvation.\n" +" This may be required by some older disk\n" +" drives or RAID arrays.\n" +" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" +" tag_info: Set per-target tag depth\n" +" global_tag_depth: Global tag depth for every target\n" +" on every bus\n" +" dv: Set per-controller Domain Validation Setting.\n" +" seltime: Selection Timeout\n" +" (0/256ms,1/128ms,2/64ms,3/32ms)\n" +"\n" +" Sample /etc/modules.conf line:\n" +" Enable verbose logging\n" +" Disable EISA/VLB probing\n" +" Set tag depth on Controller 1/Target 2 to 10 tags\n" +" Shorten the selection timeout to 128ms\n" +"\n" +" options aic7xxx='\"verbose.no_probe.tag_info:{{}.{..10}}.seltime:1\"'\n" +); #endif static void ahc_linux_handle_scsi_status(struct ahc_softc *, struct ahc_linux_device *, struct scb *); -static void ahc_linux_filter_command(struct ahc_softc*, Scsi_Cmnd*, - struct scb*); +static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, + Scsi_Cmnd *cmd); +static void ahc_linux_filter_inquiry(struct ahc_softc*, struct ahc_devinfo*); static void ahc_linux_sem_timeout(u_long arg); -static void ahc_linux_freeze_sim_queue(struct ahc_softc *ahc); -static void ahc_linux_release_sim_queue(u_long arg); +static void ahc_linux_freeze_simq(struct ahc_softc *ahc); +static void ahc_linux_release_simq(u_long arg); static void ahc_linux_dev_timed_unfreeze(u_long arg); static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); -static void ahc_linux_select_queue_depth(struct Scsi_Host *host, - Scsi_Device *scsi_devs); +static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc); +static void ahc_linux_start_dv(struct ahc_softc *ahc); +static void ahc_linux_dv_timeout(struct scsi_cmnd *cmd); +static int ahc_linux_dv_thread(void *data); +static void ahc_linux_dv_target(struct ahc_softc *ahc, u_int target); +static void ahc_linux_dv_transition(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo); +static void ahc_linux_dv_inq(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ, + u_int request_length); +static void ahc_linux_dv_tur(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo); +static void ahc_linux_dv_rebd(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_web(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_reb(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_su(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static int ahc_linux_fallback(struct ahc_softc *ahc, + struct ahc_devinfo *devinfo); +static void ahc_linux_dv_complete(Scsi_Cmnd *cmd); +static void ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo); +static u_int ahc_linux_user_dv_setting(struct ahc_softc *ahc); static void ahc_linux_device_queue_depth(struct ahc_softc *ahc, - Scsi_Device *device); + struct ahc_linux_device *dev); static struct ahc_linux_target* ahc_linux_alloc_target(struct ahc_softc*, u_int, u_int); static void ahc_linux_free_target(struct ahc_softc*, @@ -467,34 +571,77 @@ struct ahc_linux_device*); static void ahc_linux_run_device_queue(struct ahc_softc*, struct ahc_linux_device*); -static void ahc_linux_setup_tag_info(char *p, char *end); -static int ahc_linux_next_unit(void); +static void ahc_linux_setup_tag_info(char *p, char *end, char *s); +static void ahc_linux_setup_tag_info_global(char *p); +static void ahc_linux_setup_dv(char *p, char *end, char *s); +static int aic7xxx_setup(char *s); +static int ahc_linux_next_unit(void); static void ahc_runq_tasklet(unsigned long data); -static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf); +static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf); +static void ahc_schedule_completeq(struct ahc_softc *ahc, struct ahc_cmd *acmd); +/********************************* Inlines ************************************/ +static __inline void ahc_schedule_runq(struct ahc_softc *ahc); static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, u_int lun, int alloc); -static __inline void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, - Scsi_Cmnd *cmd); -static __inline void ahc_linux_run_complete_queue(struct ahc_softc *ahc, - struct ahc_cmd *acmd); +static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc, + struct ahc_cmd *acmd); static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev); static __inline struct ahc_linux_device * ahc_linux_next_device_to_run(struct ahc_softc *ahc); static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc); -static __inline void ahc_linux_sniff_command(struct ahc_softc*, Scsi_Cmnd*, - struct scb*); static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, struct ahc_dma_seg *sg, bus_addr_t addr, bus_size_t len); +static void +ahc_schedule_completeq(struct ahc_softc *ahc, struct ahc_cmd *acmd) +{ + while (acmd != NULL) { + struct ahc_completeq *completeq; + struct ahc_cmd *list_cmd; + struct ahc_cmd *next_cmd; + + next_cmd = TAILQ_NEXT(acmd, acmd_links.tqe); + completeq = &ahc->platform_data->completeq; + list_cmd = TAILQ_FIRST(completeq); + while (list_cmd != NULL + && acmd_scsi_cmd(list_cmd).serial_number + < acmd_scsi_cmd(acmd).serial_number) + list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); + if (list_cmd != NULL) + TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); + else + TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); + acmd = next_cmd; + } + if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) { + ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER; + ahc->platform_data->completeq_timer.expires = jiffies; + add_timer(&ahc->platform_data->completeq_timer); + } +} + +static __inline void +ahc_schedule_runq(struct ahc_softc *ahc) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_schedule(&ahc->platform_data->runq_tasklet); +#else + /* + * Tasklets are not available, so run inline. + */ + ahc_runq_tasklet((unsigned long)ahc); +#endif +} + static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, - u_int lun, int alloc) + u_int lun, int alloc) { struct ahc_linux_target *targ; struct ahc_linux_device *dev; @@ -518,62 +665,41 @@ return (dev); } -static __inline void -ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) -{ - /* - * Typically, the complete queue has very few entries - * queued to it before the queue is emptied by - * ahc_linux_run_complete_queue, so sorting the entries - * by generation number should be inexpensive. - * We perform the sort so that commands that complete - * with an error are retuned in the order origionally - * queued to the controller so that any subsequent retries - * are performed in order. The underlying ahc routines do - * not guarantee the order that aborted commands will be - * returned to us. - */ - struct ahc_completeq *completeq; - struct ahc_cmd *list_cmd; - struct ahc_cmd *acmd; - - /* - * If we want the request requeued, make sure there - * are sufficent retries. In the old scsi error code, - * we used to be able to specify a result code that - * bypassed the retry count. Now we must use this - * hack. - */ - if (cmd->result == (CAM_REQUEUE_REQ << 16)) - cmd->retries--; - completeq = &ahc->platform_data->completeq; - list_cmd = TAILQ_FIRST(completeq); - acmd = (struct ahc_cmd *)cmd; - while (list_cmd != NULL - && acmd_scsi_cmd(list_cmd).serial_number - < acmd_scsi_cmd(acmd).serial_number) - list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); - if (list_cmd != NULL) - TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); - else - TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); -} - -static __inline void +#define AHC_LINUX_MAX_RETURNED_ERRORS 4 +static struct ahc_cmd * ahc_linux_run_complete_queue(struct ahc_softc *ahc, struct ahc_cmd *acmd) { - u_long done_flags; + u_long done_flags; + int with_errors; ahc_done_lock(ahc, &done_flags); + with_errors = 0; while (acmd != NULL) { Scsi_Cmnd *cmd; cmd = &acmd_scsi_cmd(acmd); acmd = TAILQ_NEXT(acmd, acmd_links.tqe); cmd->host_scribble = NULL; + if (ahc_cmd_get_transaction_status(cmd) != DID_OK + || (cmd->result & 0xFF) != SCSI_STATUS_OK) + with_errors++; + cmd->scsi_done(cmd); + + if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) { + /* + * Linux uses stack recursion to requeue + * commands that need to be retried. Avoid + * blowing out the stack by "spoon feeding" + * commands that completed with error back + * the operating system in case they are going + * to be retried. "ick" + */ + break; + } } ahc_done_unlock(ahc, &done_flags); + return (acmd); } static __inline void @@ -598,7 +724,8 @@ { if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0 - || ahc->platform_data->qfrozen != 0) + || (ahc->platform_data->qfrozen != 0 + && AHC_DV_SIMQ_FROZEN(ahc) == 0)) return (NULL); return (TAILQ_FIRST(&ahc->platform_data->device_runq)); } @@ -616,19 +743,6 @@ } static __inline void -ahc_linux_sniff_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb) -{ - /* - * Determine whether we care to filter - * information out of this command. If so, - * pass it on to ahc_linux_filter_command() for more - * heavy weight processing. - */ - if (cmd->cmnd[0] == INQUIRY) - ahc_linux_filter_command(ahc, cmd, scb); -} - -static __inline void ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) { Scsi_Cmnd *cmd; @@ -691,877 +805,2820 @@ return (consumed); } -/**************************** Tasklet Handler *********************************/ - -static void -ahc_runq_tasklet(unsigned long data) -{ - struct ahc_softc* ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = (struct ahc_softc *)data; - ahc_lock(ahc, &flags); - while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { - - TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); - dev->flags &= ~AHC_DEV_ON_RUN_LIST; - ahc_linux_check_device_queue(ahc, dev); - /* Yeild to our interrupt handler */ - ahc_unlock(ahc, &flags); - ahc_lock(ahc, &flags); - } - ahc_unlock(ahc, &flags); -} - -/************************ Shutdown/halt/reboot hook ***************************/ -#include -#include - -static struct notifier_block ahc_linux_notifier = { - ahc_linux_halt, NULL, 0 -}; - -static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf) -{ - struct ahc_softc *ahc; - - if (event == SYS_DOWN || event == SYS_HALT) { - TAILQ_FOREACH(ahc, &ahc_tailq, links) { - ahc_shutdown(ahc); - } - } - return (NOTIFY_OK); -} - -/******************************** Macros **************************************/ -#define BUILD_SCSIID(ahc, cmd) \ - ((((cmd)->target << TID_SHIFT) & TID) \ - | (((cmd)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ - | (((cmd)->channel == 0) ? 0 : TWIN_CHNLB)) +/************************ Host template entry points *************************/ +static int ahc_linux_detect(Scsi_Host_Template *); +static int ahc_linux_release(struct Scsi_Host *); +static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +static const char *ahc_linux_info(struct Scsi_Host *); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int ahc_linux_slave_alloc(Scsi_Device *); +static int ahc_linux_slave_configure(Scsi_Device *); +static void ahc_linux_slave_destroy(Scsi_Device *); +static int ahc_linux_biosparam(struct scsi_device*, + struct block_device*, + sector_t, int[]); +#else +static void ahc_linux_select_queue_depth(struct Scsi_Host *host, + Scsi_Device *scsi_devs); +static int ahc_linux_biosparam(Disk *, kdev_t, int[]); +#endif +static int ahc_linux_bus_reset(Scsi_Cmnd *); +static int ahc_linux_dev_reset(Scsi_Cmnd *); +static int ahc_linux_abort(Scsi_Cmnd *); -/******************************** Bus DMA *************************************/ -int -ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent, - bus_size_t alignment, bus_size_t boundary, - bus_addr_t lowaddr, bus_addr_t highaddr, - bus_dma_filter_t *filter, void *filterarg, - bus_size_t maxsize, int nsegments, - bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) +/* + * Try to detect an Adaptec 7XXX controller. + */ +static int +ahc_linux_detect(Scsi_Host_Template *template) { - bus_dma_tag_t dmat; - - dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); - if (dmat == NULL) - return (ENOMEM); + struct ahc_softc *ahc; + int found; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* - * Linux is very simplistic about DMA memory. For now don't - * maintain all specification information. Once Linux supplies - * better facilities for doing these operations, or the - * needs of this particular driver change, we might need to do - * more here. + * It is a bug that the upper layer takes + * this lock just prior to calling us. */ - dmat->alignment = alignment; - dmat->boundary = boundary; - dmat->maxsize = maxsize; - *ret_tag = dmat; - return (0); -} - -void -ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat) -{ - free(dmat, M_DEVBUF); -} - -int -ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, - int flags, bus_dmamap_t *mapp) -{ - bus_dmamap_t map; + spin_unlock_irq(&io_request_lock); +#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); - if (map == NULL) - return (ENOMEM); /* - * Although we can dma data above 4GB, our - * "consistent" memory is below 4GB for - * space efficiency reasons (only need a 4byte - * address). For this reason, we have to reset - * our dma mask when doing allocations. + * Sanity checking of Linux SCSI data structures so + * that some of our hacks^H^H^H^H^Hassumptions aren't + * violated. */ - if (ahc->dev_softc != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) - pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF); -#else - ahc->dev_softc->dma_mask = 0xFFFFFFFF; -#endif - } - *vaddr = pci_alloc_consistent(ahc->dev_softc, - dmat->maxsize, &map->bus_addr); - if (ahc->dev_softc != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) - pci_set_dma_mask(ahc->dev_softc, - ahc->platform_data->hw_dma_mask); -#else - ahc->dev_softc->dma_mask = ahc->platform_data->hw_dma_mask; -#endif + if (offsetof(struct ahc_cmd_internal, end) + > offsetof(struct scsi_cmnd, host_scribble)) { + printf("ahc_linux_detect: SCSI data structures changed.\n"); + printf("ahc_linux_detect: Unable to attach\n"); + return (0); } -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ +#ifdef MODULE /* - * At least in 2.2.14, malloc is a slab allocator so all - * allocations are aligned. We assume for these kernel versions - * that all allocations will be bellow 4Gig, physically contiguous, - * and accessable via DMA by the controller. + * If we've been passed any parameters, process them now. */ - map = NULL; /* No additional information to store */ - *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); + if (aic7xxx) + aic7xxx_setup(aic7xxx); + if (dummy_buffer[0] != 'P') + printk(KERN_WARNING +"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n" +"aic7xxx: to see the proper way to specify options to the aic7xxx module\n" +"aic7xxx: Specifically, don't use any commas when passing arguments to\n" +"aic7xxx: insmod or else it might trash certain memory areas.\n"); #endif - if (*vaddr == NULL) - return (ENOMEM); - *mapp = map; - return(0); -} -void -ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, - void* vaddr, bus_dmamap_t map) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - pci_free_consistent(ahc->dev_softc, dmat->maxsize, - vaddr, map->bus_addr); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) + template->proc_name = "aic7xxx"; #else - free(vaddr, M_DEVBUF); + template->proc_dir = &proc_scsi_aic7xxx; #endif -} -int -ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, - void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, - void *cb_arg, int flags) -{ /* - * Assume for now that this will only be used during - * initialization and not for per-transaction buffer mapping. + * Initialize our softc list lock prior to + * probing for any adapters. */ - bus_dma_segment_t stack_sg; + ahc_list_lockinit(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - stack_sg.ds_addr = map->bus_addr; -#else - stack_sg.ds_addr = VIRT_TO_BUS(buf); +#ifdef CONFIG_PCI + ahc_linux_pci_probe(template); #endif - stack_sg.ds_len = dmat->maxsize; - cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); - return (0); -} -void -ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) -{ + if (aic7xxx_no_probe == 0) + aic7770_linux_probe(template); + /* - * The map may is NULL in our < 2.3.X implementation. + * Register with the SCSI layer all + * controllers we've found. */ - if (map != NULL) - free(map, M_DEVBUF); -} + found = 0; + TAILQ_FOREACH(ahc, &ahc_tailq, links) { -int -ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) -{ - /* Nothing to do */ - return (0); + if (ahc_linux_register_host(ahc, template) == 0) + found++; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + aic7xxx_detect_complete++; + return (found); } -/********************* Platform Dependent Functions ***************************/ +/* + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + */ int -ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) +ahc_linux_release(struct Scsi_Host * host) { - int value; - int rvalue; - int lvalue; - - /* - * Under Linux, cards are ordered as follows: - * 1) VLB/EISA BIOS enabled devices sorted by BIOS address. - * 2) PCI devices with BIOS enabled sorted by bus/slot/func. - * 3) All remaining VLB/EISA devices sorted by ioport. - * 4) All remaining PCI devices sorted by bus/slot/func. - */ - value = (lahc->flags & AHC_BIOS_ENABLED) - - (rahc->flags & AHC_BIOS_ENABLED); - if (value != 0) - /* Controllers with BIOS enabled have a *higher* priority */ - return (-value); - - /* - * Same BIOS setting, now sort based on bus type. - * EISA and VL controllers sort together. EISA/VL - * have higher priority than PCI. - */ - rvalue = (rahc->chip & AHC_BUS_MASK); - if (rvalue == AHC_VL) - rvalue = AHC_EISA; - lvalue = (lahc->chip & AHC_BUS_MASK); - if (lvalue == AHC_VL) - lvalue = AHC_EISA; - value = lvalue - rvalue; - if (value != 0) - return (value); + struct ahc_softc *ahc; + u_long l; - /* Still equal. Sort by BIOS address, ioport, or bus/slot/func. */ - switch (rvalue) { - case AHC_PCI: - { - char primary_channel; + ahc_list_lock(&l); + if (host != NULL) { - if (aic7xxx_reverse_scan != 0) - value = ahc_get_pci_bus(rahc->dev_softc) - - ahc_get_pci_bus(lahc->dev_softc); - else - value = ahc_get_pci_bus(lahc->dev_softc) - - ahc_get_pci_bus(rahc->dev_softc); - if (value != 0) - break; - if (aic7xxx_reverse_scan != 0) - value = ahc_get_pci_slot(rahc->dev_softc) - - ahc_get_pci_slot(lahc->dev_softc); - else - value = ahc_get_pci_slot(lahc->dev_softc) - - ahc_get_pci_slot(rahc->dev_softc); - if (value != 0) - break; /* - * On multi-function devices, the user can choose - * to have function 1 probed before function 0. - * Give whichever channel is the primary channel - * the lowest priority. + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. */ - primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A'; - value = 1; - if (lahc->channel == primary_channel) - value = -1; - break; - } - case AHC_EISA: - if ((rahc->flags & AHC_BIOS_ENABLED) != 0) { - value = lahc->platform_data->bios_address - - rahc->platform_data->bios_address; - } else { - value = lahc->bsh.ioport - - rahc->bsh.ioport; + ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); + if (ahc != NULL) { + u_long s; + + ahc_lock(ahc, &s); + ahc_intr_enable(ahc, FALSE); + ahc_unlock(ahc, &s); + ahc_free(ahc); } - break; - default: - panic("ahc_softc_sort: invalid bus type"); } - return (value); + ahc_list_unlock(&l); + return (0); } -static void -ahc_linux_setup_tag_info(char *p, char *end) +/* + * Return a string describing the driver. + */ +static const char * +ahc_linux_info(struct Scsi_Host *host) { - char *base; - char *tok; - char *tok_end; - char *tok_end2; - int i; - int instance; - int targ; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; + static char buffer[512]; + char ahc_info[256]; + char *bp; + struct ahc_softc *ahc; - if (*p != ':') - return; + bp = &buffer[0]; + ahc = *(struct ahc_softc **)host->hostdata; + memset(bp, 0, sizeof(buffer)); + strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); + strcat(bp, AIC7XXX_DRIVER_VERSION); + strcat(bp, "\n"); + strcat(bp, " <"); + strcat(bp, ahc->description); + strcat(bp, ">\n"); + strcat(bp, " "); + ahc_controller_info(ahc, ahc_info); + strcat(bp, ahc_info); + strcat(bp, "\n"); - instance = -1; - targ = -1; - done = FALSE; - base = p; - /* Forward us just past the ':' */ - tok = base + 1; - tok_end = strchr(tok, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*tok) { - case '{': - if (instance == -1) - instance = 0; - else if (targ == -1) - targ = 0; - tok++; - break; - case '}': - if (targ != -1) - targ = -1; - else if (instance != -1) - instance = -1; - tok++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (targ >= 0) - targ++; - else if (instance >= 0) - instance++; - if ((targ >= AHC_NUM_TARGETS) || - (instance >= NUM_ELEMENTS(aic7xxx_tag_info))) - done = TRUE; - tok++; - if (!done) { - base = tok; - } - break; - case '\0': - done = TRUE; - break; - default: - done = TRUE; - tok_end = strchr(tok, '\0'); - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(tok, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) { - tok_end = tok_end2; - done = FALSE; - } - } - if ((instance >= 0) && (targ >= 0) - && (instance < NUM_ELEMENTS(aic7xxx_tag_info)) - && (targ < AHC_NUM_TARGETS)) { - aic7xxx_tag_info[instance].tag_commands[targ] = - simple_strtoul(tok, NULL, 0) & 0xff; - } - tok = tok_end; - break; - } - } - while ((p != base) && (p != NULL)) - p = strtok(NULL, ",."); + return (bp); } /* - * Handle Linux boot parameters. This routine allows for assigning a value - * to a parameter with a ':' between the parameter and the value. - * ie. aic7xxx=stpwlev:1,extended + * Queue an SCB to the controller. */ -int -aic7xxx_setup(char *s) +static int +ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) { - int i, n; - char *p; - char *end; + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; - static struct { - const char *name; - uint32_t *flag; - } options[] = { - { "extended", &aic7xxx_extended }, - { "no_reset", &aic7xxx_no_reset }, - { "verbose", &aic7xxx_verbose }, - { "reverse_scan", &aic7xxx_reverse_scan }, - { "no_probe", &aic7xxx_no_probe }, - { "periodic_otag", &aic7xxx_periodic_otag }, - { "pci_parity", &aic7xxx_pci_parity }, - { "seltime", &aic7xxx_seltime }, - { "tag_info", NULL } - }; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; - end = strchr(s, '\0'); + /* + * Save the callback on completion function. + */ + cmd->scsi_done = scsi_done; - for (p = strtok(s, ",."); p; p = strtok(NULL, ",.")) { - for (i = 0; i < NUM_ELEMENTS(options); i++) { - n = strlen(options[i].name); + ahc_midlayer_entrypoint_lock(ahc, &flags); - if (strncmp(options[i].name, p, n) != 0) - continue; + /* + * Close the race of a command that was in the process of + * being queued to us just as our simq was frozen. Let + * DV commands through so long as we are only frozen to + * perform DV. + */ + if (ahc->platform_data->qfrozen != 0 + && AHC_DV_CMD(cmd) == 0) { - if (strncmp(p, "tag_info", n) == 0) { - ahc_linux_setup_tag_info(p + n, end); - } else if (p[n] == ':') { - *(options[i].flag) = - simple_strtoul(p + n + 1, NULL, 0); - } else if (!strncmp(p, "verbose", n)) { - *(options[i].flag) = 1; - } else { - *(options[i].flag) = ~(*(options[i].flag)); - } - break; - } + ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); + ahc_linux_queue_cmd_complete(ahc, cmd); + ahc_schedule_completeq(ahc, NULL); + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); } - return 1; + dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/TRUE); + if (dev == NULL) { + ahc_midlayer_entrypoint_unlock(ahc, &flags); + printf("aic7xxx_linux_queue: Unable to allocate device!\n"); + return (-ENOMEM); + } + cmd->result = CAM_REQ_INPROG << 16; + TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); + if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); + dev->flags |= AHC_DEV_ON_RUN_LIST; + ahc_linux_run_device_queues(ahc); + } + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) -__setup("aic7xxx=", aic7xxx_setup); -#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +ahc_linux_slave_alloc(Scsi_Device *device) +{ + struct ahc_softc *ahc; -int aic7xxx_verbose; + ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id); + return (0); +} -/* - * Try to detect an Adaptec 7XXX controller. - */ -int -ahc_linux_detect(Scsi_Host_Template *template) +static int +ahc_linux_slave_configure(Scsi_Device *device) { struct ahc_softc *ahc; - int found; - - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); + struct ahc_linux_device *dev; + u_long flags; + ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id); + ahc_midlayer_entrypoint_lock(ahc, &flags); /* - * Sanity checking of Linux SCSI data structures so - * that some of our hacks^H^H^H^H^Hassumptions aren't - * violated. + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. */ - if (offsetof(struct ahc_cmd_internal, end) - > offsetof(struct scsi_cmnd, host_scribble)) { - printf("ahc_linux_detect: SCSI data structures changed.\n"); - printf("ahc_linux_detect: Unable to attach\n"); - return (0); + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHC_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahc_linux_device_queue_depth(ahc, dev); } -#ifdef MODULE - /* - * If we've been passed any parameters, process them now. - */ - if (aic7xxx) - aic7xxx_setup(aic7xxx); - if (dummy_buffer[0] != 'P') - printk(KERN_WARNING -"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n" -"aic7xxx: to see the proper way to specify options to the aic7xxx module\n" -"aic7xxx: Specifically, don't use any commas when passing arguments to\n" -"aic7xxx: insmod or else it might trash certain memory areas.\n"); -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) - template->proc_name = "aic7xxx"; -#else - template->proc_dir = &proc_scsi_aic7xxx; -#endif + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); +} -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - /* - * We can only map 16MB per-SG - * so create a sector limit of - * "16MB" in 2K sectors. - */ - template->max_sectors = 8192; -#endif +static void +ahc_linux_slave_destroy(Scsi_Device *device) +{ + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; + ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id); + ahc_midlayer_entrypoint_lock(ahc, &flags); + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/FALSE); /* - * Initialize our softc list lock prior to - * probing for any adapters. + * Filter out "silly" deletions of real devices by only + * deleting devices that have had slave_configure() + * called on them. All other devices that have not + * been configured will automatically be deleted by + * the refcounting process. */ - ahc_list_lockinit(); - -#ifdef CONFIG_PCI - ahc_linux_pci_probe(template); -#endif - - if (aic7xxx_no_probe == 0) - aic7770_linux_probe(template); + if (dev != NULL + && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) { + dev->flags |= AHC_DEV_UNCONFIGURED; + if (TAILQ_EMPTY(&dev->busyq) + && dev->active == 0) + ahc_linux_free_device(ahc, dev); + } + ahc_midlayer_entrypoint_unlock(ahc, &flags); +} +#else +/* + * Sets the queue depth for each SCSI device hanging + * off the input host adapter. + */ +static void +ahc_linux_select_queue_depth(struct Scsi_Host * host, + Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + struct ahc_softc *ahc; + u_long flags; - /* - * Register with the SCSI layer all - * controllers we've found. - */ - spin_lock_irq(&io_request_lock); - found = 0; - TAILQ_FOREACH(ahc, &ahc_tailq, links) { + ahc = *((struct ahc_softc **)host->hostdata); + ahc_midlayer_entrypoint_lock(ahc, &flags); + for (device = scsi_devs; device != NULL; device = device->next) { + if (device->host == host) { + struct ahc_linux_device *dev; - if (ahc_linux_register_host(ahc, template) == 0) - found++; + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHC_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahc_linux_device_queue_depth(ahc, dev); + device->queue_depth = dev->openings + + dev->active; + if ((dev->flags & (AHC_DEV_Q_BASIC + | AHC_DEV_Q_TAGGED)) == 0) { + /* + * We allow the OS to queue 2 untagged + * transactions to us at any time even + * though we can only execute them + * serially on the controller/device. + * This should remove some latency. + */ + device->queue_depth = 2; + } + } + } } - aic7xxx_detect_complete++; - return (found); + ahc_midlayer_entrypoint_unlock(ahc, &flags); } +#endif -int -ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) +/* + * Return the disk geometry for the given SCSI device. + */ +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) { - char buf[80]; - struct Scsi_Host *host; - char *new_name; - u_long s; + uint8_t *bh; +#else +ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + struct scsi_device *sdev = disk->device; + u_long capacity = disk->capacity; + struct buffer_head *bh; +#endif + int heads; + int sectors; + int cylinders; + int ret; + int extended; + struct ahc_softc *ahc; + u_int channel; + ahc = *((struct ahc_softc **)sdev->host->hostdata); + channel = sdev->channel; - template->name = ahc->description; - host = scsi_register(template, sizeof(struct ahc_softc *)); - if (host == NULL) - return (ENOMEM); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + bh = scsi_bios_ptable(bdev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); +#else + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); +#endif - ahc_lock(ahc, &s); - *((struct ahc_softc **)host->hostdata) = ahc; - ahc->platform_data->host = host; - host->can_queue = AHC_MAX_QUEUE; - host->cmd_per_lun = 2; - host->sg_tablesize = AHC_NSEG; - host->select_queue_depths = ahc_linux_select_queue_depth; - /* XXX No way to communicate the ID for multiple channels */ - host->this_id = ahc->our_id; - host->irq = ahc->platform_data->irq; - host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8; - host->max_lun = AHC_NUM_LUNS; - host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; - ahc_set_unit(ahc, ahc_linux_next_unit()); - sprintf(buf, "scsi%d", host->host_no); - new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); - if (new_name != NULL) { - strcpy(new_name, buf); - ahc_set_name(ahc, new_name); - } - host->unique_id = ahc->unit; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) - scsi_set_pci_device(host, ahc->dev_softc); + if (bh) { + ret = scsi_partsize(bh, capacity, + &geom[2], &geom[0], &geom[1]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + kfree(bh); +#else + brelse(bh); #endif - ahc_linux_initialize_scsi_bus(ahc); - ahc_unlock(ahc, &s); + if (ret != -1) + return (ret); + } + heads = 64; + sectors = 32; + cylinders = aic_sector_div(capacity, heads, sectors); + + if (aic7xxx_extended != 0) + extended = 1; + else if (channel == 0) + extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0; + else + extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0; + if (extended && cylinders >= 1024) { + heads = 255; + sectors = 63; + cylinders = aic_sector_div(capacity, heads, sectors); + } + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; return (0); } -uint64_t -ahc_linux_get_memsize() +/* + * Abort the current SCSI command(s). + */ +static int +ahc_linux_abort(Scsi_Cmnd *cmd) { - struct sysinfo si; + int error; - si_meminfo(&si); - return (si.totalram << PAGE_SHIFT); + error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); + if (error != 0) + printf("aic7xxx_abort returns 0x%x\n", error); + return (error); } /* - * Find the smallest available unit number to use - * for a new device. We don't just use a static - * count to handle the "repeated hot-(un)plug" - * scenario. + * Attempt to send a target reset message to the device that timed out. */ static int -ahc_linux_next_unit() +ahc_linux_dev_reset(Scsi_Cmnd *cmd) { - struct ahc_softc *ahc; - int unit; + int error; - unit = 0; -retry: - TAILQ_FOREACH(ahc, &ahc_tailq, links) { - if (ahc->unit == unit) { - unit++; - goto retry; - } - } - return (unit); + error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); + if (error != 0) + printf("aic7xxx_dev_reset returns 0x%x\n", error); + return (error); } /* - * Place the SCSI bus into a known state by either resetting it, - * or forcing transfer negotiations on the next command to any - * target. + * Reset the SCSI bus. */ -void -ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) +static int +ahc_linux_bus_reset(Scsi_Cmnd *cmd) { - int i; - int numtarg; + struct ahc_softc *ahc; + struct ahc_cmd *acmd; + u_long s; + int found; + + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahc_midlayer_entrypoint_lock(ahc, &s); + found = ahc_reset_channel(ahc, cmd->device->channel + 'A', + /*initiate reset*/TRUE); + acmd = TAILQ_FIRST(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->completeq); + ahc_midlayer_entrypoint_unlock(ahc, &s); + if (bootverbose) + printf("%s: SCSI bus reset delivered. " + "%d SCBs aborted.\n", ahc_name(ahc), found); + + if (acmd != NULL) { + acmd = ahc_linux_run_complete_queue(ahc, acmd); + if (acmd != NULL) { + ahc_midlayer_entrypoint_lock(ahc, &s); + ahc_schedule_completeq(ahc, acmd); + ahc_midlayer_entrypoint_unlock(ahc, &s); + } + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + return SUCCESS; +} + +Scsi_Host_Template aic7xxx_driver_template = { + .proc_info = ahc_linux_proc_info, + .detect = ahc_linux_detect, + .release = ahc_linux_release, + .info = ahc_linux_info, + .queuecommand = ahc_linux_queue, + .eh_abort_handler = ahc_linux_abort, + .eh_device_reset_handler = ahc_linux_dev_reset, + .eh_bus_reset_handler = ahc_linux_bus_reset, +#if defined(__i386__) + .bios_param = ahc_linux_biosparam, +#endif + .can_queue = AHC_MAX_QUEUE, + .this_id = -1, + .sg_tablesize = AHC_NSEG, + .cmd_per_lun = 2, + .use_clustering = ENABLE_CLUSTERING, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) + /* + * We can only map 16MB per-SG + * so create a sector limit of + * "16MB" in 2K sectors. + */ + .max_sectors = 8192, +#endif +#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) +/* Assume RedHat Distribution with its different HIGHIO conventions. */ + .can_dma_32 = 1, + .single_sg_okay = 1, +#else + .highmem_io = 1, +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + .name = "aic7xxx", + .slave_alloc = ahc_linux_slave_alloc, + .slave_configure = ahc_linux_slave_configure, + .slave_destroy = ahc_linux_slave_destroy, +#else + .select_queue_depths = ahc_linux_select_queue_depth, + .use_new_eh_code = 1, +#endif +}; + +#define driver_template aic7xxx_driver_template +#include "scsi_module.c" + +/**************************** Tasklet Handler *********************************/ + +static void +ahc_runq_tasklet(unsigned long data) +{ + struct ahc_softc* ahc; + struct ahc_linux_device *dev; + u_long flags; + + ahc = (struct ahc_softc *)data; + ahc_lock(ahc, &flags); + while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { + + TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); + dev->flags &= ~AHC_DEV_ON_RUN_LIST; + ahc_linux_check_device_queue(ahc, dev); + /* Yeild to our interrupt handler */ + ahc_unlock(ahc, &flags); + ahc_lock(ahc, &flags); + } + ahc_unlock(ahc, &flags); +} + +/************************ Shutdown/halt/reboot hook ***************************/ +#include +#include + +static struct notifier_block ahc_linux_notifier = { + ahc_linux_halt, NULL, 0 +}; + +static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + struct ahc_softc *ahc; + + /* + * In 2.5.X, this is called prior to the filesystems + * being synced and the SCSI layer being properly + * shutdown. A different API is required there, + * but the device hooks for this don't quite look + * right. + */ + if (event == SYS_DOWN || event == SYS_HALT) { + TAILQ_FOREACH(ahc, &ahc_tailq, links) { + ahc_shutdown(ahc); + } + } +#endif + return (NOTIFY_OK); +} + +/******************************** Macros **************************************/ +#define BUILD_SCSIID(ahc, cmd) \ + ((((cmd)->device->id << TID_SHIFT) & TID) \ + | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ + | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB)) + +/******************************** Bus DMA *************************************/ +int +ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent, + bus_size_t alignment, bus_size_t boundary, + bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, + bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) +{ + bus_dma_tag_t dmat; + + dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); + if (dmat == NULL) + return (ENOMEM); + + /* + * Linux is very simplistic about DMA memory. For now don't + * maintain all specification information. Once Linux supplies + * better facilities for doing these operations, or the + * needs of this particular driver change, we might need to do + * more here. + */ + dmat->alignment = alignment; + dmat->boundary = boundary; + dmat->maxsize = maxsize; + *ret_tag = dmat; + return (0); +} + +void +ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat) +{ + free(dmat, M_DEVBUF); +} + +int +ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, + int flags, bus_dmamap_t *mapp) +{ + bus_dmamap_t map; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); + if (map == NULL) + return (ENOMEM); + /* + * Although we can dma data above 4GB, our + * "consistent" memory is below 4GB for + * space efficiency reasons (only need a 4byte + * address). For this reason, we have to reset + * our dma mask when doing allocations. + */ + if (ahc->dev_softc != NULL) + ahc_pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF); + *vaddr = pci_alloc_consistent(ahc->dev_softc, + dmat->maxsize, &map->bus_addr); + if (ahc->dev_softc != NULL) + ahc_pci_set_dma_mask(ahc->dev_softc, + ahc->platform_data->hw_dma_mask); +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + /* + * At least in 2.2.14, malloc is a slab allocator so all + * allocations are aligned. We assume for these kernel versions + * that all allocations will be bellow 4Gig, physically contiguous, + * and accessable via DMA by the controller. + */ + map = NULL; /* No additional information to store */ + *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); +#endif + if (*vaddr == NULL) + return (ENOMEM); + *mapp = map; + return(0); +} + +void +ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, + void* vaddr, bus_dmamap_t map) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + pci_free_consistent(ahc->dev_softc, dmat->maxsize, + vaddr, map->bus_addr); +#else + free(vaddr, M_DEVBUF); +#endif +} + +int +ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, + void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, + void *cb_arg, int flags) +{ + /* + * Assume for now that this will only be used during + * initialization and not for per-transaction buffer mapping. + */ + bus_dma_segment_t stack_sg; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + stack_sg.ds_addr = map->bus_addr; +#else + stack_sg.ds_addr = VIRT_TO_BUS(buf); +#endif + stack_sg.ds_len = dmat->maxsize; + cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); + return (0); +} + +void +ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* + * The map may is NULL in our < 2.3.X implementation. + */ + if (map != NULL) + free(map, M_DEVBUF); +} + +int +ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* Nothing to do */ + return (0); +} + +/********************* Platform Dependent Functions ***************************/ +int +ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) +{ + int value; + int rvalue; + int lvalue; + + /* + * Under Linux, cards are ordered as follows: + * 1) VLB/EISA BIOS enabled devices sorted by BIOS address. + * 2) PCI devices with BIOS enabled sorted by bus/slot/func. + * 3) All remaining VLB/EISA devices sorted by ioport. + * 4) All remaining PCI devices sorted by bus/slot/func. + */ + value = (lahc->flags & AHC_BIOS_ENABLED) + - (rahc->flags & AHC_BIOS_ENABLED); + if (value != 0) + /* Controllers with BIOS enabled have a *higher* priority */ + return (-value); + + /* + * Same BIOS setting, now sort based on bus type. + * EISA and VL controllers sort together. EISA/VL + * have higher priority than PCI. + */ + rvalue = (rahc->chip & AHC_BUS_MASK); + if (rvalue == AHC_VL) + rvalue = AHC_EISA; + lvalue = (lahc->chip & AHC_BUS_MASK); + if (lvalue == AHC_VL) + lvalue = AHC_EISA; + value = lvalue - rvalue; + if (value != 0) + return (value); + + /* Still equal. Sort by BIOS address, ioport, or bus/slot/func. */ + switch (rvalue) { + case AHC_PCI: + { + char primary_channel; + + if (aic7xxx_reverse_scan != 0) + value = ahc_get_pci_bus(rahc->dev_softc) + - ahc_get_pci_bus(lahc->dev_softc); + else + value = ahc_get_pci_bus(lahc->dev_softc) + - ahc_get_pci_bus(rahc->dev_softc); + if (value != 0) + break; + if (aic7xxx_reverse_scan != 0) + value = ahc_get_pci_slot(rahc->dev_softc) + - ahc_get_pci_slot(lahc->dev_softc); + else + value = ahc_get_pci_slot(lahc->dev_softc) + - ahc_get_pci_slot(rahc->dev_softc); + if (value != 0) + break; + /* + * On multi-function devices, the user can choose + * to have function 1 probed before function 0. + * Give whichever channel is the primary channel + * the lowest priority. + */ + primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A'; + value = 1; + if (lahc->channel == primary_channel) + value = -1; + break; + } + case AHC_EISA: + if ((rahc->flags & AHC_BIOS_ENABLED) != 0) { + value = lahc->platform_data->bios_address + - rahc->platform_data->bios_address; + } else { + value = lahc->bsh.ioport + - rahc->bsh.ioport; + } + break; + default: + panic("ahc_softc_sort: invalid bus type"); + } + return (value); +} + +static void +ahc_linux_setup_tag_info(char *p, char *end, char *s) +{ + char *base; + char *tok; + char *tok_end; + char *tok_end2; + int i; + int instance; + int targ; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + if (*p != ':') + return; + + instance = -1; + targ = -1; + done = FALSE; + base = p; + /* Forward us just past the ':' */ + tok = base + 1; + tok_end = strchr(tok, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*tok) { + case '{': + if (instance == -1) + instance = 0; + else if (targ == -1) + targ = 0; + tok++; + break; + case '}': + if (targ != -1) + targ = -1; + else if (instance != -1) + instance = -1; + tok++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (targ >= 0) + targ++; + else if (instance >= 0) + instance++; + if ((targ >= AHC_NUM_TARGETS) || + (instance >= NUM_ELEMENTS(aic7xxx_tag_info))) + done = TRUE; + tok++; + if (!done) { + base = tok; + } + break; + case '\0': + done = TRUE; + break; + default: + done = TRUE; + tok_end = strchr(tok, '\0'); + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(tok, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) { + tok_end = tok_end2; + done = FALSE; + } + } + if ((instance >= 0) && (targ >= 0) + && (instance < NUM_ELEMENTS(aic7xxx_tag_info)) + && (targ < AHC_NUM_TARGETS)) { + aic7xxx_tag_info[instance].tag_commands[targ] = + simple_strtoul(tok, NULL, 0) & 0xff; + } + tok = tok_end; + break; + } + } + while ((p != base) && (p != NULL)) + p = strsep(&s, ",."); +} + +static void +ahc_linux_setup_tag_info_global(char *p) +{ + int tags, i, j; + + tags = simple_strtoul(p + 1, NULL, 0) & 0xff; + printf("Setting Global Tags= %d\n", tags); + + for (i = 0; i < NUM_ELEMENTS(aic7xxx_tag_info); i++) { + for (j = 0; j < AHC_NUM_TARGETS; j++) { + aic7xxx_tag_info[i].tag_commands[j] = tags; + } + } +} + +static void +ahc_linux_setup_dv(char *p, char *end, char *s) +{ + char *base; + char *tok; + char *tok_end; + char *tok_end2; + int i; + int instance; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + if (*p != ':') + return; + + instance = -1; + done = FALSE; + base = p; + /* Forward us just past the ':' */ + tok = base + 1; + tok_end = strchr(tok, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*tok) { + case '{': + if (instance == -1) + instance = 0; + tok++; + break; + case '}': + if (instance != -1) + instance = -1; + tok++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (instance >= 0) + instance++; + if (instance >= NUM_ELEMENTS(aic7xxx_dv_settings)) + done = TRUE; + tok++; + if (!done) { + base = tok; + } + break; + case '\0': + done = TRUE; + break; + default: + done = TRUE; + tok_end = strchr(tok, '\0'); + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(tok, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) { + tok_end = tok_end2; + done = FALSE; + } + } + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic7xxx_dv_settings))) { + aic7xxx_dv_settings[instance] = + simple_strtol(tok, NULL, 0); + } + tok = tok_end; + break; + } + } + while ((p != base) && (p != NULL)) + p = strsep(&s, ",."); +} + +/* + * Handle Linux boot parameters. This routine allows for assigning a value + * to a parameter with a ':' between the parameter and the value. + * ie. aic7xxx=stpwlev:1,extended + */ +static int +aic7xxx_setup(char *s) +{ + int i, n; + char *p; + char *end; + + static struct { + const char *name; + uint32_t *flag; + } options[] = { + { "extended", &aic7xxx_extended }, + { "no_reset", &aic7xxx_no_reset }, + { "verbose", &aic7xxx_verbose }, + { "allow_memio", &aic7xxx_allow_memio}, +#ifdef AHC_DEBUG + { "debug", &ahc_debug }, +#endif + { "reverse_scan", &aic7xxx_reverse_scan }, + { "no_probe", &aic7xxx_no_probe }, + { "periodic_otag", &aic7xxx_periodic_otag }, + { "pci_parity", &aic7xxx_pci_parity }, + { "seltime", &aic7xxx_seltime }, + { "tag_info", NULL }, + { "global_tag_depth", NULL }, + { "dv", NULL } + }; + + end = strchr(s, '\0'); + + while ((p = strsep(&s, ",.")) != NULL) { + if (*p == '\0') + continue; + for (i = 0; i < NUM_ELEMENTS(options); i++) { + n = strlen(options[i].name); + + if (strncmp(options[i].name, p, n) != 0) + continue; + + if (!strncmp(p, "global_tag_depth", n)) { + ahc_linux_setup_tag_info_global(p + n); + } else if (!strncmp(p, "tag_info", n)) { + ahc_linux_setup_tag_info(p + n, end, s); + } else if (strncmp(p, "dv", n) == 0) { + ahc_linux_setup_dv(p + n, end, s); + } else if (p[n] == ':') { + *(options[i].flag) = + simple_strtoul(p + n + 1, NULL, 0); + } else if (!strncmp(p, "verbose", n)) { + *(options[i].flag) = 1; + } else { + *(options[i].flag) = ~(*(options[i].flag)); + } + break; + } + } + return 1; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) +__setup("aic7xxx=", aic7xxx_setup); +#endif + +int aic7xxx_verbose; + +int +ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) +{ + char buf[80]; + struct Scsi_Host *host; + char *new_name; + u_long s; + u_int target; + + template->name = ahc->description; + host = scsi_register(template, sizeof(struct ahc_softc *)); + if (host == NULL) + return (ENOMEM); + + *((struct ahc_softc **)host->hostdata) = ahc; + ahc_lock(ahc, &s); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_assign_lock(host, &ahc->platform_data->spin_lock); +#endif + ahc->platform_data->host = host; + host->can_queue = AHC_MAX_QUEUE; + host->cmd_per_lun = 2; + host->sg_tablesize = AHC_NSEG; + /* XXX No way to communicate the ID for multiple channels */ + host->this_id = ahc->our_id; + host->irq = ahc->platform_data->irq; + host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8; + host->max_lun = AHC_NUM_LUNS; + host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; + ahc_set_unit(ahc, ahc_linux_next_unit()); + sprintf(buf, "scsi%d", host->host_no); + new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (new_name != NULL) { + strcpy(new_name, buf); + ahc_set_name(ahc, new_name); + } + host->unique_id = ahc->unit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) + scsi_set_pci_device(host, ahc->dev_softc); +#endif + ahc_linux_initialize_scsi_bus(ahc); + ahc_unlock(ahc, &s); + ahc->platform_data->dv_pid = kernel_thread(ahc_linux_dv_thread, ahc, 0); + ahc_lock(ahc, &s); + if (ahc->platform_data->dv_pid < 0) { + printf("%s: Failed to create DV thread, error= %d\n", + ahc_name(ahc), ahc->platform_data->dv_pid); + return (-ahc->platform_data->dv_pid); + } + /* + * Initially allocate *all* of our linux target objects + * so that the DV thread will scan them all in parallel + * just after driver initialization. Any device that + * does not exist will have its target object destroyed + * by the selection timeout handler. In the case of a + * device that appears after the initial DV scan, async + * negotiation will occur for the first command, and DV + * will comence should that first command be successful. + */ + for (target = 0; target < host->max_id*host->max_channel+1; target++) { + u_int channel; + + channel = 0; + if (target > 7 + && (ahc->features & AHC_TWIN) != 0) + channel = 1; + ahc_linux_alloc_target(ahc, channel, target); + } + ahc_intr_enable(ahc, TRUE); + ahc_linux_start_dv(ahc); + ahc_unlock(ahc, &s); + return (0); +} + +uint64_t +ahc_linux_get_memsize() +{ + struct sysinfo si; + + si_meminfo(&si); + return ((uint64_t)si.totalram << PAGE_SHIFT); +} + +/* + * Find the smallest available unit number to use + * for a new device. We don't just use a static + * count to handle the "repeated hot-(un)plug" + * scenario. + */ +static int +ahc_linux_next_unit() +{ + struct ahc_softc *ahc; + int unit; + + unit = 0; +retry: + TAILQ_FOREACH(ahc, &ahc_tailq, links) { + if (ahc->unit == unit) { + unit++; + goto retry; + } + } + return (unit); +} + +/* + * Place the SCSI bus into a known state by either resetting it, + * or forcing transfer negotiations on the next command to any + * target. + */ +void +ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) +{ + int i; + int numtarg; + + i = 0; + numtarg = 0; + + if (aic7xxx_no_reset != 0) + ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B); + + if ((ahc->flags & AHC_RESET_BUS_A) != 0) + ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE); + else + numtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + + if ((ahc->features & AHC_TWIN) != 0) { + + if ((ahc->flags & AHC_RESET_BUS_B) != 0) { + ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE); + } else { + if (numtarg == 0) + i = 8; + numtarg += 8; + } + } + + /* + * Force negotiation to async for all targets that + * will not see an initial bus reset. + */ + for (; i < numtarg; i++) { + struct ahc_devinfo devinfo; + struct ahc_initiator_tinfo *tinfo; + struct ahc_tmode_tstate *tstate; + u_int our_id; + u_int target_id; + char channel; + + channel = 'A'; + our_id = ahc->our_id; + target_id = i; + if (i > 7 && (ahc->features & AHC_TWIN) != 0) { + channel = 'B'; + our_id = ahc->our_id_b; + target_id = i % 8; + } + tinfo = ahc_fetch_transinfo(ahc, channel, our_id, + target_id, &tstate); + ahc_compile_devinfo(&devinfo, our_id, target_id, + CAM_LUN_WILDCARD, channel, ROLE_INITIATOR); + ahc_update_neg_request(ahc, &devinfo, tstate, + tinfo, AHC_NEG_ALWAYS); + } + /* Give the bus some time to recover */ + if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) { + ahc_linux_freeze_simq(ahc); + init_timer(&ahc->platform_data->reset_timer); + ahc->platform_data->reset_timer.data = (u_long)ahc; + ahc->platform_data->reset_timer.expires = + jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000; + ahc->platform_data->reset_timer.function = + ahc_linux_release_simq; + add_timer(&ahc->platform_data->reset_timer); + } +} + +int +ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) +{ + + ahc->platform_data = + malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT); + if (ahc->platform_data == NULL) + return (ENOMEM); + memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); + TAILQ_INIT(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->device_runq); + ahc->platform_data->irq = AHC_LINUX_NOIRQ; + ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; + ahc_lockinit(ahc); + ahc_done_lockinit(ahc); + init_timer(&ahc->platform_data->completeq_timer); + ahc->platform_data->completeq_timer.data = (u_long)ahc; + ahc->platform_data->completeq_timer.function = + (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); + init_MUTEX_LOCKED(&ahc->platform_data->dv_sem); + init_MUTEX_LOCKED(&ahc->platform_data->dv_cmd_sem); +#else + ahc->platform_data->eh_sem = MUTEX_LOCKED; + ahc->platform_data->dv_sem = MUTEX_LOCKED; + ahc->platform_data->dv_cmd_sem = MUTEX_LOCKED; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, + (unsigned long)ahc); +#endif + ahc->seltime = (aic7xxx_seltime & 0x3) << 4; + ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; + if (aic7xxx_pci_parity == 0) + ahc->flags |= AHC_DISABLE_PCI_PERR; + + if (TAILQ_EMPTY(&ahc_tailq)) + register_reboot_notifier(&ahc_linux_notifier); + return (0); +} + +void +ahc_platform_free(struct ahc_softc *ahc) +{ + struct ahc_linux_target *targ; + struct ahc_linux_device *dev; + u_long s; + int i, j; + + if (ahc->platform_data != NULL) { + /* Kill the DV kthread */ + if (ahc->platform_data->dv_pid > 0) { + ahc_lock(ahc, &s); + ahc->platform_data->flags |= AHC_DV_SHUTDOWN; + ahc_unlock(ahc, &s); + up(&ahc->platform_data->dv_sem); + do { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + printf("%s: Waiting for DV thread to " + "exit\n", ahc_name(ahc)); + } +#endif + } while (waitpid(ahc->platform_data->dv_pid, NULL, + __WCLONE) == -ERESTARTSYS); + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_kill(&ahc->platform_data->runq_tasklet); +#endif + if (ahc->platform_data->host != NULL) + scsi_unregister(ahc->platform_data->host); + + /* destroy all of the device and target objects */ + for (i = 0; i < AHC_NUM_TARGETS; i++) { + targ = ahc->platform_data->targets[i]; + if (targ != NULL) { + for (j = 0; j < AHC_NUM_LUNS; j++) { + if (targ->devices[j] != NULL) { + dev = targ->devices[j]; + ahc_linux_free_device(ahc, dev); + } + if (ahc->platform_data->targets[i] == + NULL) + break; + } + } + } + + if (ahc->platform_data->irq != AHC_LINUX_NOIRQ) + free_irq(ahc->platform_data->irq, ahc); + if (ahc->tag == BUS_SPACE_PIO + && ahc->bsh.ioport != 0) + release_region(ahc->bsh.ioport, 256); + if (ahc->tag == BUS_SPACE_MEMIO + && ahc->bsh.maddr != NULL) { + u_long base_addr; - i = 0; - numtarg = 0; + base_addr = (u_long)ahc->bsh.maddr; + base_addr &= PAGE_MASK; + iounmap((void *)base_addr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(ahc->platform_data->mem_busaddr, + 0x1000); +#endif + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + /* XXX Need an instance detach in the PCI code */ + if (ahc->dev_softc != NULL) + ahc->dev_softc->driver = NULL; +#endif + free(ahc->platform_data, M_DEVBUF); + } + if (TAILQ_EMPTY(&ahc_tailq)) { + unregister_reboot_notifier(&ahc_linux_notifier); +#ifdef CONFIG_PCI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pci_unregister_driver(&aic7xxx_pci_driver); +#endif +#endif + } +} + +void +ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) +{ + ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb), + SCB_GET_CHANNEL(ahc, scb), + SCB_GET_LUN(scb), SCB_LIST_NULL, + ROLE_UNKNOWN, CAM_REQUEUE_REQ); +} + +void +ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, + ahc_queue_alg alg) +{ + struct ahc_linux_device *dev; + int was_queuing; + int now_queuing; + + dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', + devinfo->target, + devinfo->lun, /*alloc*/FALSE); + if (dev == NULL) + return; + was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); + now_queuing = alg != AHC_QUEUE_NONE; + if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0 + && (was_queuing != now_queuing) + && (dev->active != 0)) { + dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY; + dev->qfrozen++; + } + + dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG); + if (now_queuing) { + u_int usertags; + + usertags = ahc_linux_user_tagdepth(ahc, devinfo); + if (!was_queuing) { + /* + * Start out agressively and allow our + * dynamic queue depth algorithm to take + * care of the rest. + */ + dev->maxtags = usertags; + dev->openings = dev->maxtags - dev->active; + } + if (dev->maxtags == 0) { + /* + * Queueing is disabled by the user. + */ + dev->openings = 1; + } else if (alg == AHC_QUEUE_TAGGED) { + dev->flags |= AHC_DEV_Q_TAGGED; + if (aic7xxx_periodic_otag != 0) + dev->flags |= AHC_DEV_PERIODIC_OTAG; + } else + dev->flags |= AHC_DEV_Q_BASIC; + } else { + /* We can only have one opening. */ + dev->maxtags = 0; + dev->openings = 1 - dev->active; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (dev->scsi_device != NULL) { + switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { + case AHC_DEV_Q_BASIC: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_SIMPLE_TASK, + dev->openings + dev->active); + break; + case AHC_DEV_Q_TAGGED: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_ORDERED_TASK, + dev->openings + dev->active); + break; + default: + /* + * We allow the OS to queue 2 untagged transactions to + * us at any time even though we can only execute them + * serially on the controller/device. This should + * remove some latency. + */ + scsi_adjust_queue_depth(dev->scsi_device, + /*NON-TAGGED*/0, + /*queue depth*/2); + break; + } + } +#endif +} + +int +ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status) +{ + int chan; + int maxchan; + int targ; + int maxtarg; + int clun; + int maxlun; + int count; + + if (tag != SCB_LIST_NULL) + return (0); + + chan = 0; + if (channel != ALL_CHANNELS) { + chan = channel - 'A'; + maxchan = chan + 1; + } else { + maxchan = (ahc->features & AHC_TWIN) ? 2 : 1; + } + targ = 0; + if (target != CAM_TARGET_WILDCARD) { + targ = target; + maxtarg = targ + 1; + } else { + maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + } + clun = 0; + if (lun != CAM_LUN_WILDCARD) { + clun = lun; + maxlun = clun + 1; + } else { + maxlun = AHC_NUM_LUNS; + } + + count = 0; + for (; chan < maxchan; chan++) { + + for (; targ < maxtarg; targ++) { + + for (; clun < maxlun; clun++) { + struct ahc_linux_device *dev; + struct ahc_busyq *busyq; + struct ahc_cmd *acmd; + + dev = ahc_linux_get_device(ahc, chan, + targ, clun, + /*alloc*/FALSE); + if (dev == NULL) + continue; + + busyq = &dev->busyq; + while ((acmd = TAILQ_FIRST(busyq)) != NULL) { + Scsi_Cmnd *cmd; + + cmd = &acmd_scsi_cmd(acmd); + TAILQ_REMOVE(busyq, acmd, + acmd_links.tqe); + count++; + cmd->result = status << 16; + ahc_linux_queue_cmd_complete(ahc, cmd); + } + } + } + } + + return (count); +} + +static void +ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc) +{ + struct ahc_cmd *acmd; + u_long flags; + + ahc_lock(ahc, &flags); + del_timer(&ahc->platform_data->completeq_timer); + ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER; + acmd = TAILQ_FIRST(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->completeq); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif + if (acmd != NULL) { + acmd = ahc_linux_run_complete_queue(ahc, acmd); + if (acmd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_lock(ahc, &flags); +#endif + ahc_schedule_completeq(ahc, acmd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif + } + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif +} + +static void +ahc_linux_start_dv(struct ahc_softc *ahc) +{ + + /* + * Freeze the simq and signal ahc_linux_queue to not let any + * more commands through + */ + if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s: Waking DV thread\n", ahc_name(ahc)); +#endif + + ahc->platform_data->flags |= AHC_DV_ACTIVE; + ahc_linux_freeze_simq(ahc); + + /* Wake up the DV kthread */ + up(&ahc->platform_data->dv_sem); + } +} + +static int +ahc_linux_dv_thread(void *data) +{ + struct ahc_softc *ahc; + int target; + u_long s; + + ahc = (struct ahc_softc *)data; + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("Launching DV Thread\n"); +#endif + + /* + * Don't care about any signals. + */ + siginitsetinv(¤t->blocked, 0); + + /* + * Complete thread creation. + */ + lock_kernel(); + daemonize(); + sprintf(current->comm, "ahc_dv_%d", ahc->unit); + unlock_kernel(); + + while (1) { + /* + * Use down_interruptible() rather than down() to + * avoid inclusion in the load average. + */ + down_interruptible(&ahc->platform_data->dv_sem); + + /* Check to see if we've been signaled to exit */ + ahc_lock(ahc, &s); + if ((ahc->platform_data->flags & AHC_DV_SHUTDOWN) != 0) { + ahc_unlock(ahc, &s); + return (0); + } + ahc_unlock(ahc, &s); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s: Beginning Domain Validation\n", + ahc_name(ahc)); +#endif + + /* + * Wait for any pending commands to drain before proceeding. + */ + ahc_lock(ahc, &s); + while (LIST_FIRST(&ahc->pending_scbs) != NULL) { + ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_EMPTY; + ahc_unlock(ahc, &s); + down_interruptible(&ahc->platform_data->dv_sem); + ahc_lock(ahc, &s); + } + + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + while (AHC_DV_SIMQ_FROZEN(ahc) == 0) { + ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE; + ahc_unlock(ahc, &s); + down_interruptible(&ahc->platform_data->dv_sem); + ahc_lock(ahc, &s); + } + ahc_unlock(ahc, &s); + + for (target = 0; target < AHC_NUM_TARGETS; target++) + ahc_linux_dv_target(ahc, target); + + ahc_lock(ahc, &s); + ahc->platform_data->flags &= ~AHC_DV_ACTIVE; + ahc_unlock(ahc, &s); + + /* + * Release the SIMQ so that normal commands are + * allowed to continue on the bus. + */ + ahc_linux_release_simq((u_long)ahc); + } + + return (0); +} + +#define AHC_LINUX_DV_INQ_SHORT_LEN 36 +#define AHC_LINUX_DV_INQ_LEN 256 +#define AHC_LINUX_DV_TIMEOUT (HZ / 4) + +#define AHC_SET_DV_STATE(ahc, targ, newstate) \ + ahc_set_dv_state(ahc, targ, newstate, __LINE__) + +static __inline void +ahc_set_dv_state(struct ahc_softc *ahc, struct ahc_linux_target *targ, + ahc_dv_state newstate, u_int line) +{ + ahc_dv_state oldstate; - if (aic7xxx_no_reset != 0) - ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B); + oldstate = targ->dv_state; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s:%d: Going from state %d to state %d\n", + ahc_name(ahc), line, oldstate, newstate); +#endif - if ((ahc->flags & AHC_RESET_BUS_A) != 0) - ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE); + if (oldstate == newstate) + targ->dv_state_retry++; else - numtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + targ->dv_state_retry = 0; + targ->dv_state = newstate; +} - if ((ahc->features & AHC_TWIN) != 0) { +static void +ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset) +{ + struct ahc_devinfo devinfo; + struct ahc_linux_target *targ; + struct scsi_cmnd *cmd; + struct scsi_device *scsi_dev; + struct scsi_sense_data *sense; + uint8_t *buffer; + u_long s; + u_int timeout; + int echo_size; + + sense = NULL; + buffer = NULL; + echo_size = 0; + ahc_lock(ahc, &s); + targ = ahc->platform_data->targets[target_offset]; + if (targ == NULL || (targ->flags & AHC_DV_REQUIRED) == 0) { + ahc_unlock(ahc, &s); + return; + } + ahc_compile_devinfo(&devinfo, ahc->our_id, targ->target, /*lun*/0, + targ->channel + 'A', ROLE_INITIATOR); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, &devinfo); + printf("Performing DV\n"); + } +#endif - if ((ahc->flags & AHC_RESET_BUS_B) != 0) { - ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE); - } else { - if (numtarg == 0) - i = 8; - numtarg += 8; + ahc_unlock(ahc, &s); + + cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); + scsi_dev->host = ahc->platform_data->host; + scsi_dev->id = devinfo.target; + scsi_dev->lun = devinfo.lun; + scsi_dev->channel = devinfo.channel - 'A'; + ahc->platform_data->dv_scsi_dev = scsi_dev; + + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC); + + while (targ->dv_state != AHC_DV_STATE_EXIT) { + timeout = AHC_LINUX_DV_TIMEOUT; + switch (targ->dv_state) { + case AHC_DV_STATE_INQ_SHORT_ASYNC: + case AHC_DV_STATE_INQ_ASYNC: + case AHC_DV_STATE_INQ_ASYNC_VERIFY: + /* + * Set things to async narrow to reduce the + * chance that the INQ will fail. + */ + ahc_lock(ahc, &s); + ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_unlock(ahc, &s); + timeout = 10 * HZ; + targ->flags &= ~AHC_INQ_VALID; + /* FALLTHROUGH */ + case AHC_DV_STATE_INQ_VERIFY: + { + u_int inq_len; + + if (targ->dv_state == AHC_DV_STATE_INQ_SHORT_ASYNC) + inq_len = AHC_LINUX_DV_INQ_SHORT_LEN; + else + inq_len = targ->inq_data->additional_length + 5; + ahc_linux_dv_inq(ahc, cmd, &devinfo, targ, inq_len); + break; } - } + case AHC_DV_STATE_TUR: + case AHC_DV_STATE_BUSY: + ahc_linux_dv_tur(ahc, cmd, &devinfo); + break; + case AHC_DV_STATE_REBD: + ahc_linux_dv_rebd(ahc, cmd, &devinfo, targ); + break; + case AHC_DV_STATE_WEB: + ahc_linux_dv_web(ahc, cmd, &devinfo, targ); + break; - for (; i < numtarg; i++) { - struct ahc_devinfo devinfo; - struct ahc_initiator_tinfo *tinfo; - struct ahc_tmode_tstate *tstate; - u_int our_id; - u_int target_id; - char channel; + case AHC_DV_STATE_REB: + ahc_linux_dv_reb(ahc, cmd, &devinfo, targ); + break; - channel = 'A'; - our_id = ahc->our_id; - target_id = i; - if (i > 7 && (ahc->features & AHC_TWIN) != 0) { - channel = 'B'; - our_id = ahc->our_id_b; - target_id = i % 8; + case AHC_DV_STATE_SU: + ahc_linux_dv_su(ahc, cmd, &devinfo, targ); + timeout = 50 * HZ; + break; + + default: + ahc_print_devinfo(ahc, &devinfo); + printf("Unknown DV state %d\n", targ->dv_state); + goto out; } - tinfo = ahc_fetch_transinfo(ahc, channel, our_id, - target_id, &tstate); - tinfo->goal = tinfo->user; + + /* Queue the command and wait for it to complete */ + /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */ + init_timer(&cmd->eh_timeout); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + /* + * All of the printfs during negotiation + * really slow down the negotiation. + * Add a bit of time just to be safe. + */ + timeout += HZ; +#endif + scsi_add_timer(cmd, timeout, ahc_linux_dv_timeout); /* - * Don't try negotiations that require PPR messages - * until we successfully retrieve Inquiry data. + * In 2.5.X, it is assumed that all calls from the + * "midlayer" (which we are emulating) will have the + * ahc host lock held. */ - tinfo->goal.ppr_options = 0; - if (tinfo->goal.transport_version > SCSI_REV_2) - tinfo->goal.transport_version = SCSI_REV_2; - ahc_compile_devinfo(&devinfo, our_id, target_id, - CAM_LUN_WILDCARD, channel, ROLE_INITIATOR); - ahc_update_neg_request(ahc, &devinfo, tstate, - tinfo, /*force*/FALSE); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc_lock(ahc, &s); +#endif + ahc_linux_queue(cmd, ahc_linux_dv_complete); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &s); +#endif + down_interruptible(&ahc->platform_data->dv_cmd_sem); + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + ahc_lock(ahc, &s); + while (AHC_DV_SIMQ_FROZEN(ahc) == 0) { + ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE; + ahc_unlock(ahc, &s); + down_interruptible(&ahc->platform_data->dv_sem); + ahc_lock(ahc, &s); + } + ahc_unlock(ahc, &s); + + ahc_linux_dv_transition(ahc, cmd, &devinfo, targ); } - /* Give the bus some time to recover */ - if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) { - ahc_linux_freeze_sim_queue(ahc); - init_timer(&ahc->platform_data->reset_timer); - ahc->platform_data->reset_timer.data = (u_long)ahc; - ahc->platform_data->reset_timer.expires = - jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000; - ahc->platform_data->reset_timer.function = - ahc_linux_release_sim_queue; - add_timer(&ahc->platform_data->reset_timer); + +out: + if ((targ->flags & AHC_INQ_VALID) != 0 + && ahc_linux_get_device(ahc, devinfo.channel - 'A', + devinfo.target, devinfo.lun, + /*alloc*/FALSE) == NULL) { + /* + * The DV state machine failed to configure this device. + * This is normal if DV is disabled. Since we have inquiry + * data, filter it and use the "optimistic" negotiation + * parameters found in the inquiry string. + */ + ahc_linux_filter_inquiry(ahc, &devinfo); + if ((targ->flags & (AHC_BASIC_DV|AHC_ENHANCED_DV)) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("DV failed to configure device. " + "Please file a bug report against " + "this driver.\n"); + } + } + + if (cmd != NULL) + free(cmd, M_DEVBUF); + + if (ahc->platform_data->dv_scsi_dev != NULL) { + free(ahc->platform_data->dv_scsi_dev, M_DEVBUF); + ahc->platform_data->dv_scsi_dev = NULL; + } + + ahc_lock(ahc, &s); + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + targ->flags &= ~AHC_DV_REQUIRED; + if (targ->refcount == 0) + ahc_linux_free_target(ahc, targ); + ahc_unlock(ahc, &s); +} + +static void +ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ) +{ + cam_status cam_status; + u_int32_t status; + u_int scsi_status; + + scsi_status = ahc_cmd_get_scsi_status(cmd); + cam_status = ahc_cmd_get_transaction_status(cmd); + status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status); + + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Entering ahc_linux_dv_transition, state= %d, " + "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state, + status, cmd->result); + } +#endif + + switch (targ->dv_state) { + case AHC_DV_STATE_INQ_SHORT_ASYNC: + case AHC_DV_STATE_INQ_ASYNC: + switch (status & SS_MASK) { + case SS_NOP: + { + AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1); + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if ((status & SS_ERRMASK) == EBUSY) + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHC_DV_STATE_INQ_ASYNC_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + u_int xportflags; + u_int spi3data; + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHC_LINUX_DV_INQ_LEN) != 0) { + /* + * Inquiry data must have changed. + * Try from the top again. + */ + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + } + + AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1); + targ->flags |= AHC_INQ_VALID; + if (ahc_linux_user_dv_setting(ahc) == 0) + break; + + xportflags = targ->inq_data->flags; + if ((xportflags & (SID_Sync|SID_WBus16)) == 0) + break; + + spi3data = targ->inq_data->spi3data; + switch (spi3data & SID_SPI_CLOCK_DT_ST) { + default: + case SID_SPI_CLOCK_ST: + /* Assume only basic DV is supported. */ + targ->flags |= AHC_BASIC_DV; + break; + case SID_SPI_CLOCK_DT: + case SID_SPI_CLOCK_DT_ST: + targ->flags |= AHC_ENHANCED_DV; + break; + } + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + + if ((status & SS_ERRMASK) == EBUSY) + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHC_DV_STATE_INQ_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHC_LINUX_DV_INQ_LEN) == 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + int i; + + ahc_print_devinfo(ahc, devinfo); + printf("Inquiry buffer mismatch:"); + for (i = 0; i < AHC_LINUX_DV_INQ_LEN; i++) { + if ((i & 0xF) == 0) + printf("\n "); + printf("0x%x:0x0%x ", + ((uint8_t *)targ->inq_data)[i], + targ->dv_buffer[i]); + } + printf("\n"); + } +#endif + + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } else if ((status & SS_ERRMASK) == EBUSY) + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + + case AHC_DV_STATE_TUR: + switch (status & SS_MASK) { + case SS_NOP: + if ((targ->flags & AHC_BASIC_DV) != 0) { + ahc_linux_filter_inquiry(ahc, devinfo); + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_VERIFY); + } else if ((targ->flags & AHC_ENHANCED_DV) != 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REBD); + } else { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + } + break; + case SS_RETRY: + case SS_TUR: + if ((status & SS_ERRMASK) == EBUSY) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + break; + } + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry >= 10) { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV TUR reties exhausted\n"); + } +#endif + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + if (status & SSQ_DELAY) + scsi_sleep(1 * HZ); + + break; + case SS_START: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_SU); + break; + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_REBD: + switch (status & SS_MASK) { + case SS_NOP: + { + uint32_t echo_size; + + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB); + echo_size = scsi_3btoul(&targ->dv_buffer[1]); + echo_size &= 0x1FFF; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Echo buffer size= %d\n", echo_size); + } +#endif + if (echo_size == 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + + /* Generate the buffer pattern */ + targ->dv_echo_size = echo_size; + ahc_linux_generate_dv_pattern(targ); + /* + * Setup initial negotiation values. + */ + ahc_linux_filter_inquiry(ahc, devinfo); + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if (targ->dv_state_retry <= 10) + break; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV REBD reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + case SS_FATAL: + default: + /* + * Setup initial negotiation values + * and try level 1 DV. + */ + ahc_linux_filter_inquiry(ahc, devinfo); + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_VERIFY); + targ->dv_echo_size = 0; + break; + } + break; + + case AHC_DV_STATE_WEB: + switch (status & SS_MASK) { + case SS_NOP: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REB); + break; + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry <= 10) + break; + /* FALLTHROUGH */ +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV WEB reties exhausted\n"); + } +#endif + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_REB: + switch (status & SS_MASK) { + case SS_NOP: + if (memcmp(targ->dv_buffer, targ->dv_buffer1, + targ->dv_echo_size) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + else + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_WEB); + break; + } + + if (targ->dv_buffer != NULL) { + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = NULL; + } + if (targ->dv_buffer1 != NULL) { + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = NULL; + } + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB); + } + if (targ->dv_state_retry <= 10) { + if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0) + scsi_sleep(ahc->our_id*HZ/10); + break; + } +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV REB reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_SU: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_BUSY: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if (targ->dv_state_retry < 60) { + if ((status & SSQ_DELAY) != 0) + scsi_sleep(1 * HZ); + } else { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV BUSY reties exhausted\n"); + } +#endif + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + } + break; + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + default: + printf("%s: Invalid DV completion state %d\n", ahc_name(ahc), + targ->dv_state); + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; } } -int -ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) +static void +ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo) +{ + memset(cmd, 0, sizeof(struct scsi_cmnd)); + cmd->device = ahc->platform_data->dv_scsi_dev; + cmd->scsi_done = ahc_linux_dv_complete; +} + +/* + * Synthesize an inquiry command. On the return trip, it'll be + * sniffed and the device transfer settings set for us. + */ +static void +ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ, + u_int request_length) { - ahc->platform_data = - malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT); - if (ahc->platform_data == NULL) - return (ENOMEM); - memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); - TAILQ_INIT(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->device_runq); - ahc->platform_data->irq = AHC_LINUX_NOIRQ; - ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; - ahc_lockinit(ahc); - ahc_done_lockinit(ahc); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); -#else - ahc->platform_data->eh_sem = MUTEX_LOCKED; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, - (unsigned long)ahc); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending INQ\n"); + } #endif - ahc->seltime = (aic7xxx_seltime & 0x3) << 4; - ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; - if (TAILQ_EMPTY(&ahc_tailq)) - register_reboot_notifier(&ahc_linux_notifier); - return (0); + if (targ->inq_data == NULL) + targ->inq_data = malloc(AHC_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) { + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHC_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + } + + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 6; + cmd->cmnd[0] = INQUIRY; + cmd->cmnd[4] = request_length; + cmd->request_bufflen = request_length; + if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) + cmd->request_buffer = targ->dv_buffer; + else + cmd->request_buffer = targ->inq_data; + memset(cmd->request_buffer, 0, AHC_LINUX_DV_INQ_LEN); } -void -ahc_platform_free(struct ahc_softc *ahc) +static void +ahc_linux_dv_tur(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo) { - if (ahc->platform_data != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_kill(&ahc->platform_data->runq_tasklet); -#endif - if (ahc->platform_data->host != NULL) - scsi_unregister(ahc->platform_data->host); - if (ahc->platform_data->irq != AHC_LINUX_NOIRQ) - free_irq(ahc->platform_data->irq, ahc); - if (ahc->tag == BUS_SPACE_PIO - && ahc->bsh.ioport != 0) - release_region(ahc->bsh.ioport, 256); - if (ahc->tag == BUS_SPACE_MEMIO - && ahc->bsh.maddr != NULL) { - u_long base_addr; - base_addr = (u_long)ahc->bsh.maddr; - base_addr &= PAGE_MASK; - iounmap((void *)base_addr); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - release_mem_region(ahc->platform_data->mem_busaddr, - 0x1000); -#endif - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - /* XXX Need an instance detach in the PCI code */ - if (ahc->dev_softc != NULL) - ahc->dev_softc->driver = NULL; -#endif - free(ahc->platform_data, M_DEVBUF); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending TUR\n"); } - if (TAILQ_EMPTY(&ahc_tailq)) { - unregister_reboot_notifier(&ahc_linux_notifier); -#ifdef CONFIG_PCI -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - pci_unregister_driver(&aic7xxx_pci_driver); -#endif #endif + /* Do a TUR to clear out any non-fatal transitional state */ + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = TEST_UNIT_READY; +} + +#define AHC_REBD_LEN 4 + +static void +ahc_linux_dv_rebd(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) +{ + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending REBD\n"); } +#endif + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHC_REBD_LEN, M_DEVBUF, M_WAITOK); + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0b; + scsi_ulto3b(AHC_REBD_LEN, &cmd->cmnd[6]); + cmd->request_bufflen = AHC_REBD_LEN; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; } -void -ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) +static void +ahc_linux_dv_web(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) { - ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb), - SCB_GET_CHANNEL(ahc, scb), - SCB_GET_LUN(scb), SCB_LIST_NULL, - ROLE_UNKNOWN, CAM_REQUEUE_REQ); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending WEB\n"); + } +#endif + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_WRITE; + cmd->cmd_len = 10; + cmd->cmnd[0] = WRITE_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; } -void -ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, - ahc_queue_alg alg) +static void +ahc_linux_dv_reb(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) { - struct ahc_linux_device *dev; - int was_queuing; - int now_queuing; - dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', - devinfo->target, - devinfo->lun, /*alloc*/FALSE); - if (dev == NULL) - return; - was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); - now_queuing = alg != AHC_QUEUE_NONE; - if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0 - && (was_queuing != now_queuing) - && (dev->active != 0)) { - dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY; - dev->qfrozen++; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending REB\n"); } +#endif + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer1; +} - dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG); - if (now_queuing) { - u_int usertags; +static void +ahc_linux_dv_su(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ) +{ + u_int le; + + le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0; + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending SU\n"); + } +#endif + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = START_STOP_UNIT; + cmd->cmnd[4] = le | SSS_START; +} - usertags = ahc_linux_user_tagdepth(ahc, devinfo); - if (!was_queuing) { +static int +ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) +{ + struct ahc_linux_target *targ; + struct ahc_initiator_tinfo *tinfo; + struct ahc_transinfo *goal; + struct ahc_tmode_tstate *tstate; + struct ahc_syncrate *syncrate; + u_long s; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int cur_speed; + u_int wide_speed; + u_int narrow_speed; + u_int fallback_speed; + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Trying to fallback\n"); + } +#endif + ahc_lock(ahc, &s); + targ = ahc->platform_data->targets[devinfo->target_offset]; + tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + goal = &tinfo->goal; + width = goal->width; + period = goal->period; + offset = goal->offset; + ppr_options = goal->ppr_options; + if (offset == 0) + period = AHC_ASYNC_XFER_PERIOD; + if (targ->dv_next_narrow_period == 0) + targ->dv_next_narrow_period = MAX(period, AHC_SYNCRATE_ULTRA2); + if (targ->dv_next_wide_period == 0) + targ->dv_next_wide_period = period; + if (targ->dv_max_width == 0) + targ->dv_max_width = width; + if (targ->dv_max_ppr_options == 0) + targ->dv_max_ppr_options = ppr_options; + if (targ->dv_last_ppr_options == 0) + targ->dv_last_ppr_options = ppr_options; + + cur_speed = aic_calc_speed(width, period, offset, AHC_SYNCRATE_MIN); + wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, + targ->dv_next_wide_period, + MAX_OFFSET, + AHC_SYNCRATE_MIN); + narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, + targ->dv_next_narrow_period, + MAX_OFFSET, + AHC_SYNCRATE_MIN); + fallback_speed = aic_calc_speed(width, period+1, offset, + AHC_SYNCRATE_MIN); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " + "fallback_speed= %d\n", cur_speed, wide_speed, + narrow_speed, fallback_speed); + } +#endif + + if (cur_speed > 160000) { + /* + * Paced/DT/IU_REQ only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + } else if (cur_speed > 80000) { + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { /* - * Start out agressively and allow our - * dynamic queue depth algorithm to take - * care of the rest. + * Try without IU_REQ as it may be confusing + * an expander. */ - dev->maxtags = usertags; - dev->openings = dev->maxtags - dev->active; + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else { + /* + * Paced/DT only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + ppr_options = targ->dv_max_ppr_options; } - if (alg == AHC_QUEUE_TAGGED) { - dev->flags |= AHC_DEV_Q_TAGGED; - if (aic7xxx_periodic_otag != 0) - dev->flags |= AHC_DEV_PERIODIC_OTAG; - } else - dev->flags |= AHC_DEV_Q_BASIC; - } else { - /* We can only have one opening. */ - dev->maxtags = 0; - dev->openings = 1 - dev->active; - } -} + } else if (cur_speed > 3300) { -int -ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, - int lun, u_int tag, role_t role, uint32_t status) -{ - int chan; - int maxchan; - int targ; - int maxtarg; - int clun; - int maxlun; - int count; + /* + * In this range we the following + * options ordered from highest to + * lowest desireability: + * + * o Wide/DT + * o Wide/non-DT + * o Narrow at a potentally higher sync rate. + * + * All modes are tested with and without IU_REQ + * set since using IUs may confuse an expander. + */ + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - if (tag != SCB_LIST_NULL) - return (0); + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + /* + * Try going non-DT. + */ + ppr_options = targ->dv_max_ppr_options; + ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } else if (targ->dv_last_ppr_options != 0) { + /* + * Try without QAS or any other PPR options. + * We may need a non-PPR message to work with + * an expander. We look at the "last PPR options" + * so we will perform this fallback even if the + * target responded to our PPR negotiation with + * no option bits set. + */ + ppr_options = 0; + } else if (width == MSG_EXT_WDTR_BUS_16_BIT) { + /* + * If the next narrow speed is greater than + * the next wide speed, fallback to narrow. + * Otherwise fallback to the next DT/Wide setting. + * The narrow async speed will always be smaller + * than the wide async speed, so handle this case + * specifically. + */ + ppr_options = targ->dv_max_ppr_options; + if (narrow_speed > fallback_speed + || period >= AHC_ASYNC_XFER_PERIOD) { + targ->dv_next_wide_period = period+1; + width = MSG_EXT_WDTR_BUS_8_BIT; + period = targ->dv_next_narrow_period; + } else { + period++; + } + } else if ((ahc->features & AHC_WIDE) != 0 + && targ->dv_max_width != 0 + && wide_speed >= fallback_speed + && (targ->dv_next_wide_period <= AHC_ASYNC_XFER_PERIOD + || period >= AHC_ASYNC_XFER_PERIOD)) { - chan = 0; - if (channel != ALL_CHANNELS) { - chan = channel - 'A'; - maxchan = chan + 1; - } else { - maxchan = (ahc->features & AHC_TWIN) ? 2 : 1; - } - targ = 0; - if (target != CAM_TARGET_WILDCARD) { - targ = target; - maxtarg = targ + 1; + /* + * We are narrow. Try falling back + * to the next wide speed with + * all supported ppr options set. + */ + targ->dv_next_narrow_period = period+1; + width = MSG_EXT_WDTR_BUS_16_BIT; + period = targ->dv_next_wide_period; + ppr_options = targ->dv_max_ppr_options; + } else { + /* Only narrow fallback is allowed. */ + period++; + ppr_options = targ->dv_max_ppr_options; + } } else { - maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + ahc_unlock(ahc, &s); + return (-1); } - clun = 0; - if (lun != CAM_LUN_WILDCARD) { - clun = lun; - maxlun = clun + 1; - } else { - maxlun = AHC_NUM_LUNS; + offset = MAX_OFFSET; + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); + ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, FALSE); + if (period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + if (width == MSG_EXT_WDTR_BUS_8_BIT) + targ->dv_next_narrow_period = AHC_ASYNC_XFER_PERIOD; + else + targ->dv_next_wide_period = AHC_ASYNC_XFER_PERIOD; } + ahc_set_syncrate(ahc, devinfo, syncrate, period, offset, + ppr_options, AHC_TRANS_GOAL, FALSE); + targ->dv_last_ppr_options = ppr_options; + ahc_unlock(ahc, &s); + return (0); +} - count = 0; - for (; chan < maxchan; chan++) { - - for (; targ < maxtarg; targ++) { +static void +ahc_linux_dv_timeout(struct scsi_cmnd *cmd) +{ + struct ahc_softc *ahc; + struct ahc_cmd *acmd; + struct ahc_linux_device *next_dev; + struct scb *scb; + u_long flags; - for (; clun < maxlun; clun++) { - struct ahc_linux_device *dev; - struct ahc_busyq *busyq; - struct ahc_cmd *acmd; + ahc = *((struct ahc_softc **)cmd->device->host->hostdata); + ahc_lock(ahc, &flags); - dev = ahc_linux_get_device(ahc, chan, - targ, clun, - /*alloc*/FALSE); - if (dev == NULL) - continue; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + printf("%s: Timeout while doing DV command %x.\n", + ahc_name(ahc), cmd->cmnd[0]); + ahc_dump_card_state(ahc); + } +#endif + + /* + * Guard against "done race". No action is + * required if we just completed. + */ + if ((scb = (struct scb *)cmd->host_scribble) == NULL) { + ahc_unlock(ahc, &flags); + return; + } - busyq = &dev->busyq; - while ((acmd = TAILQ_FIRST(busyq)) != NULL) { - Scsi_Cmnd *cmd; + /* + * Command has not completed. Mark this + * SCB as having failing status prior to + * resetting the bus, so we get the correct + * error code. + */ + if ((scb->flags & SCB_SENSE) != 0) + ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); + else + ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); + ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE); - cmd = &acmd_scsi_cmd(acmd); - TAILQ_REMOVE(busyq, acmd, - acmd_links.tqe); - count++; - cmd->result = status << 16; - ahc_linux_queue_cmd_complete(ahc, cmd); - } - } + /* + * Add a minimal bus settle delay for devices that are slow to + * respond after bus resets. + */ + ahc_linux_freeze_simq(ahc); + init_timer(&ahc->platform_data->reset_timer); + ahc->platform_data->reset_timer.data = (u_long)ahc; + ahc->platform_data->reset_timer.expires = jiffies + HZ / 2; + ahc->platform_data->reset_timer.function = + (ahc_linux_callback_t *)ahc_linux_release_simq; + add_timer(&ahc->platform_data->reset_timer); + /* + * In 2.5.X, the "done lock" is the ahc_lock. + * Instead of dropping and re-acquiring the same + * lock in the 2.5.X case, just hold our ahc_lock + * the whole time. ahc_done_lock() has been + * made a no-op for 2.5.X too. + */ + acmd = TAILQ_FIRST(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->completeq); + next_dev = ahc_linux_next_device_to_run(ahc); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif + if (next_dev) + ahc_schedule_runq(ahc); + if (acmd != NULL) { + acmd = ahc_linux_run_complete_queue(ahc, acmd); + if (acmd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_lock(ahc, &flags); +#endif + ahc_schedule_completeq(ahc, acmd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif +} - return (count); +static void +ahc_linux_dv_complete(struct scsi_cmnd *cmd) +{ + struct ahc_softc *ahc; + + ahc = *((struct ahc_softc **)cmd->device->host->hostdata); + + /* Delete the DV timer before it goes off! */ + scsi_delete_timer(cmd); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s:%d:%d: Command completed, status= 0x%x\n", + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->result); +#endif + + /* Wake up the state machine */ + up(&ahc->platform_data->dv_cmd_sem); } -/* - * Sets the queue depth for each SCSI device hanging - * off the input host adapter. - */ static void -ahc_linux_select_queue_depth(struct Scsi_Host * host, - Scsi_Device * scsi_devs) +ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ) { - Scsi_Device *device; - struct ahc_softc *ahc; - u_long flags; - int scbnum; + uint16_t b; + u_int i; + u_int j; + + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); - ahc = *((struct ahc_softc **)host->hostdata); - ahc_lock(ahc, &flags); - scbnum = 0; - for (device = scsi_devs; device != NULL; device = device->next) { - if (device->host == host) { - ahc_linux_device_queue_depth(ahc, device); - scbnum += device->queue_depth; + i = 0; + b = 0x0001; + for (j = 0 ; i < targ->dv_echo_size; j++) { + if (j < 32) { + /* + * 32bytes of sequential numbers. + */ + targ->dv_buffer[i++] = j & 0xff; + } else if (j < 48) { + /* + * 32bytes of repeating 0x0000, 0xffff. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00; + } else if (j < 64) { + /* + * 32bytes of repeating 0x5555, 0xaaaa. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55; + } else { + /* + * Remaining buffer is filled with a repeating + * patter of: + * + * 0xffff + * ~0x0001 << shifted once in each loop. + */ + if (j & 0x02) { + if (j & 0x01) { + targ->dv_buffer[i++] = ~(b >> 8) & 0xff; + b <<= 1; + if (b == 0x0000) + b = 0x0001; + } else { + targ->dv_buffer[i++] = (~b & 0xff); + } + } else { + targ->dv_buffer[i++] = 0xff; + } } } - ahc_unlock(ahc, &flags); } static u_int @@ -1595,74 +3652,76 @@ return (tags); } +static u_int +ahc_linux_user_dv_setting(struct ahc_softc *ahc) +{ + static int warned_user; + int dv; + + if (warned_user == 0 + && ahc->unit >= NUM_ELEMENTS(aic7xxx_dv_settings)) { + + printf("aic7xxx: WARNING, insufficient " + "dv settings instances for installed " + "controllers. Using defaults\n"); + printf("aic7xxx: Please update the " + "aic7xxx_dv_settings array in the " + "aic7xxx.c source file.\n"); + dv = -1; + warned_user++; + } else { + + dv = aic7xxx_dv_settings[ahc->unit]; + } + + if (dv < 0) { + u_long s; + + /* + * Apply the default. + */ + /* + * XXX - Enable DV on non-U160 controllers once it + * has been tested there. + */ + ahc_lock(ahc, &s); + dv = (ahc->features & AHC_DT); + if (ahc->seep_config != 0 + && ahc->seep_config->signature >= CFSIGNATURE2) + dv = (ahc->seep_config->adapter_control & CFENABLEDV); + ahc_unlock(ahc, &s); + } + return (dv); +} + /* * Determines the queue depth for a given device. */ static void -ahc_linux_device_queue_depth(struct ahc_softc *ahc, Scsi_Device * device) +ahc_linux_device_queue_depth(struct ahc_softc *ahc, + struct ahc_linux_device *dev) { struct ahc_devinfo devinfo; u_int tags; ahc_compile_devinfo(&devinfo, - device->channel == 0 ? ahc->our_id : ahc->our_id_b, - device->id, device->lun, - device->channel == 0 ? 'A' : 'B', + dev->target->channel == 0 + ? ahc->our_id : ahc->our_id_b, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', ROLE_INITIATOR); tags = ahc_linux_user_tagdepth(ahc, &devinfo); if (tags != 0 - && device->tagged_supported != 0) { + && dev->scsi_device != NULL + && dev->scsi_device->tagged_supported != 0) { - device->queue_depth = tags; ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED); printf("scsi%d:%c:%d:%d: Tagged Queuing enabled. Depth %d\n", ahc->platform_data->host->host_no, devinfo.channel, devinfo.target, devinfo.lun, tags); } else { - /* - * We allow the OS to queue 2 untagged transactions to - * us at any time even though we can only execute them - * serially on the controller/device. This should remove - * some latency. - */ - device->queue_depth = 2; - } -} - -/* - * Queue an SCB to the controller. - */ -int -ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) -{ - struct ahc_softc *ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = *(struct ahc_softc **)cmd->host->hostdata; - - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - ahc_lock(ahc, &flags); - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/TRUE); - if (dev == NULL) { - ahc_unlock(ahc, &flags); - printf("aic7xxx_linux_queue: Unable to allocate device!\n"); - return (-ENOMEM); - } - cmd->result = CAM_REQ_INPROG << 16; - TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); - if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; - ahc_linux_run_device_queues(ahc); + ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE); } - ahc_unlock(ahc, &flags); - return (0); } static void @@ -1686,8 +3745,8 @@ * Schedule us to run later. The only reason we are not * running is because the whole controller Q is frozen. */ - if (ahc->platform_data->qfrozen != 0) { - + if (ahc->platform_data->qfrozen != 0 + && AHC_DV_SIMQ_FROZEN(ahc) == 0) { TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); dev->flags |= AHC_DEV_ON_RUN_LIST; @@ -1728,12 +3787,26 @@ if ((ahc->user_discenable & mask) != 0) hscb->control |= DISCENB; + if (AHC_DV_CMD(cmd) != 0) + scb->flags |= SCB_SILENT; + if ((tstate->auto_negotiate & mask) != 0) { scb->flags |= SCB_AUTO_NEGOTIATE; scb->hscb->control |= MK_MESSAGE; } if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + int msg_bytes; + uint8_t tag_msgs[2]; + + msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); + if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { + hscb->control |= tag_msgs[0]; + if (tag_msgs[0] == MSG_ORDERED_TASK) + dev->commands_since_idle_or_otag = 0; + } else +#endif if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { hscb->control |= MSG_ORDERED_TASK; @@ -1881,16 +3954,33 @@ acmd = TAILQ_FIRST(&ahc->platform_data->completeq); TAILQ_INIT(&ahc->platform_data->completeq); next_dev = ahc_linux_next_device_to_run(ahc); + /* + * In 2.5.X, the "done lock" is the ahc_lock. + * Instead of dropping and re-acquiring the same + * lock in the 2.5.X case, just hold our ahc_lock + * the whole time. ahc_done_lock() has been + * made a no-op for 2.5.X too. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ahc_unlock(ahc, &flags); - if (next_dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_schedule(&ahc->platform_data->runq_tasklet); -#else - ahc_runq_tasklet((unsigned long)ahc); #endif + if (next_dev) + ahc_schedule_runq(ahc); + if (acmd != NULL) { + acmd = ahc_linux_run_complete_queue(ahc, acmd); + if (acmd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_lock(ahc, &flags); +#endif + ahc_schedule_completeq(ahc, acmd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif + } } - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, &flags); +#endif } void @@ -1900,8 +3990,8 @@ acmd = TAILQ_FIRST(&ahc->platform_data->completeq); TAILQ_INIT(&ahc->platform_data->completeq); - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); + while (acmd != NULL) + acmd = ahc_linux_run_complete_queue(ahc, acmd); } static struct ahc_linux_target* @@ -1910,6 +4000,19 @@ struct ahc_linux_target *targ; u_int target_offset; + target_offset = target; + if (channel != 0) + target_offset += 8; + /* + * Never allow allocation of a target object for + * our own SCSIID. + */ + if ((channel == 0 && target == ahc->our_id) + || (channel == 1 && target == ahc->our_id_b)) { + ahc->platform_data->targets[target_offset] = NULL; + return (NULL); + } + targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT); if (targ == NULL) return (NULL); @@ -1917,9 +4020,7 @@ targ->channel = channel; targ->target = target; targ->ahc = ahc; - target_offset = target; - if (channel != 0) - target_offset += 8; + targ->flags = AHC_DV_REQUIRED; ahc->platform_data->targets[target_offset] = targ; return (targ); } @@ -1927,12 +4028,41 @@ static void ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ) { + struct ahc_devinfo devinfo; + struct ahc_initiator_tinfo *tinfo; + struct ahc_tmode_tstate *tstate; + u_int our_id; u_int target_offset; + char channel; + /* + * Force a negotiation to async/narrow on any + * future command to this device unless a bus + * reset occurs between now and that command. + */ + channel = 'A' + targ->channel; + our_id = ahc->our_id; target_offset = targ->target; - if (targ->channel != 0) + if (targ->channel != 0) { target_offset += 8; + our_id = ahc->our_id_b; + } + tinfo = ahc_fetch_transinfo(ahc, channel, our_id, + targ->target, &tstate); + ahc_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD, + channel, ROLE_INITIATOR); + ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS); ahc->platform_data->targets[target_offset] = NULL; + if (targ->inq_data != NULL) + free(targ->inq_data, M_DEVBUF); + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); free(targ, M_DEVBUF); } @@ -1980,38 +4110,11 @@ targ->devices[dev->lun] = NULL; free(dev, M_DEVBUF); targ->refcount--; - if (targ->refcount == 0) + if (targ->refcount == 0 + && (targ->flags & AHC_DV_REQUIRED) == 0) ahc_linux_free_target(ahc, targ); } -/* - * Return a string describing the driver. - */ -const char * -ahc_linux_info(struct Scsi_Host *host) -{ - static char buffer[512]; - char ahc_info[256]; - char *bp; - struct ahc_softc *ahc; - - bp = &buffer[0]; - ahc = *(struct ahc_softc **)host->hostdata; - memset(bp, 0, sizeof(buffer)); - strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); - strcat(bp, AIC7XXX_DRIVER_VERSION); - strcat(bp, "\n"); - strcat(bp, " <"); - strcat(bp, ahc->description); - strcat(bp, ">\n"); - strcat(bp, " "); - ahc_controller_info(ahc, ahc_info); - strcat(bp, ahc_info); - strcat(bp, "\n"); - - return (bp); -} - void ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun, ac_code code, void *arg) @@ -2082,7 +4185,34 @@ break; } case AC_SENT_BDR: + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + Scsi_Device *scsi_dev; + + /* + * Find the SCSI device associated with this + * request and indicate that a UA is expected. + * XXX This should really be handled by the mid-layer. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + list_for_each_entry(scsi_dev, + &ahc->platform_data->host->my_devices, + siblings) { +#else + for (scsi_dev = ahc->platform_data->host->host_queue; + scsi_dev != NULL; scsi_dev = scsi_dev->next) { +#endif + if (channel - 'A' == scsi_dev->channel + && target == scsi_dev->id + && (lun == CAM_LUN_WILDCARD + || lun == scsi_dev->lun)) { + scsi_dev->was_reset = 1; + scsi_dev->expecting_cc_ua = 1; + } + } +#endif break; + } case AC_BUS_RESET: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) if (ahc->platform_data->host != NULL) { @@ -2100,10 +4230,10 @@ * Calls the higher level scsi done function and frees the scb. */ void -ahc_done(struct ahc_softc *ahc, struct scb * scb) +ahc_done(struct ahc_softc *ahc, struct scb *scb) { Scsi_Cmnd *cmd; - struct ahc_linux_device *dev; + struct ahc_linux_device *dev; LIST_REMOVE(scb, pending_links); if ((scb->flags & SCB_UNTAGGEDQ) != 0) { @@ -2125,27 +4255,33 @@ dev = scb->platform_data->dev; dev->active--; dev->openings++; - ahc_linux_unmap_scb(ahc, scb); - if (scb->flags & SCB_SENSE) { - memcpy(cmd->sense_buffer, ahc_get_sense_buf(ahc, scb), - MIN(sizeof(struct scsi_sense_data), - sizeof(cmd->sense_buffer))); - cmd->result |= (DRIVER_SENSE << 24); - } else { - /* - * Guard against stale sense data. - * The Linux mid-layer assumes that sense - * was retrieved anytime the first byte of - * the sense buffer looks "sane". - */ - cmd->sense_buffer[0] = 0; + if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) { + cmd->result &= ~(CAM_DEV_QFRZN << 16); + dev->qfrozen--; } + ahc_linux_unmap_scb(ahc, scb); + + /* + * Guard against stale sense data. + * The Linux mid-layer assumes that sense + * was retrieved anytime the first byte of + * the sense buffer looks "sane". + */ + cmd->sense_buffer[0] = 0; if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) { uint32_t amount_xferred; amount_xferred = ahc_get_transfer_length(scb) - ahc_get_residual(scb); - if (amount_xferred < scb->io_ctx->underflow) { + if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MISC) != 0) { + ahc_print_path(ahc, scb); + printf("Set CAM_UNCOR_PARITY\n"); + } +#endif + ahc_set_transaction_status(scb, CAM_UNCOR_PARITY); + } else if (amount_xferred < scb->io_ctx->underflow) { printf("Saw underflow (%ld of %ld bytes). " "Treated as error\n", ahc_get_residual(scb), @@ -2153,20 +4289,21 @@ ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR); } else { ahc_set_transaction_status(scb, CAM_REQ_CMP); - ahc_linux_sniff_command(ahc, cmd, scb); } - } else if (ahc_get_transaction_status(scb) == DID_OK) { + } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { ahc_linux_handle_scsi_status(ahc, dev, scb); - } else if (ahc_get_transaction_status(scb) == DID_NO_CONNECT) { - /* - * Should a selection timeout kill the device? - * That depends on whether the selection timeout - * is persistent. Since we have no guarantee that - * the mid-layer will issue an inquiry for this device - * again, we can't just kill it off. + } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { dev->flags |= AHC_DEV_UNCONFIGURED; - */ + if (AHC_DV_CMD(cmd) == FALSE) + dev->target->flags &= ~AHC_DV_REQUIRED; } + /* + * Start DV for devices that require it assuming the first command + * sent does not result in a selection timeout. + */ + if (ahc_get_transaction_status(scb) != CAM_SEL_TIMEOUT + && (dev->target->flags & AHC_DV_REQUIRED) != 0) + ahc_linux_start_dv(ahc); if (dev->openings == 1 && ahc_get_transaction_status(scb) == CAM_REQ_CMP @@ -2198,17 +4335,38 @@ if ((scb->flags & SCB_RECOVERY_SCB) != 0) { printf("Recovery SCB completes\n"); - up(&ahc->platform_data->eh_sem); + if (ahc_get_transaction_status(scb) == CAM_BDR_SENT + || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED) + ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + up(&ahc->platform_data->eh_sem); + } } ahc_free_scb(ahc, scb); ahc_linux_queue_cmd_complete(ahc, cmd); + + if ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_EMPTY) != 0 + && LIST_FIRST(&ahc->pending_scbs) == NULL) { + ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_EMPTY; + up(&ahc->platform_data->dv_sem); + } + } static void ahc_linux_handle_scsi_status(struct ahc_softc *ahc, struct ahc_linux_device *dev, struct scb *scb) { + struct ahc_devinfo devinfo; + + ahc_compile_devinfo(&devinfo, + ahc->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', + ROLE_INITIATOR); + /* * We don't currently trust the mid-layer to * properly deal with queue full or busy. So, @@ -2222,6 +4380,45 @@ switch (ahc_get_scsi_status(scb)) { default: break; + case SCSI_STATUS_CHECK_COND: + case SCSI_STATUS_CMD_TERMINATED: + { + Scsi_Cmnd *cmd; + + /* + * Copy sense information to the OS's cmd + * structure if it is available. + */ + cmd = scb->io_ctx; + if (scb->flags & SCB_SENSE) { + u_int sense_size; + + sense_size = MIN(sizeof(struct scsi_sense_data) + - ahc_get_sense_residual(scb), + sizeof(cmd->sense_buffer)); + memcpy(cmd->sense_buffer, + ahc_get_sense_buf(ahc, scb), sense_size); + if (sense_size < sizeof(cmd->sense_buffer)) + memset(&cmd->sense_buffer[sense_size], 0, + sizeof(cmd->sense_buffer) - sense_size); + cmd->result |= (DRIVER_SENSE << 24); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_SENSE) { + int i; + + printf("Copied %d bytes of sense data:", + sense_size); + for (i = 0; i < sense_size; i++) { + if ((i & 0xF) == 0) + printf("\n"); + printf("0x%x ", cmd->sense_buffer[i]); + } + printf("\n"); + } +#endif + } + break; + } case SCSI_STATUS_QUEUE_FULL: { /* @@ -2267,239 +4464,319 @@ } ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); ahc_set_scsi_status(scb, SCSI_STATUS_OK); + ahc_set_tags(ahc, &devinfo, + (dev->flags & AHC_DEV_Q_BASIC) + ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); + break; + } + /* + * Drop down to a single opening, and treat this + * as if the target returned BUSY SCSI status. + */ + dev->openings = 1; + ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); + ahc_set_tags(ahc, &devinfo, + (dev->flags & AHC_DEV_Q_BASIC) + ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); + /* FALLTHROUGH */ + } + case SCSI_STATUS_BUSY: + { + /* + * Set a short timer to defer sending commands for + * a bit since Linux will not delay in this case. + */ + if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) { + printf("%s:%c:%d: Device Timer still active during " + "busy processing\n", ahc_name(ahc), + dev->target->channel, dev->target->target); + break; + } + dev->flags |= AHC_DEV_TIMER_ACTIVE; + dev->qfrozen++; + init_timer(&dev->timer); + dev->timer.data = (u_long)dev; + dev->timer.expires = jiffies + (HZ/2); + dev->timer.function = ahc_linux_dev_timed_unfreeze; + add_timer(&dev->timer); + break; + } + } +} + +static void +ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) +{ + /* + * Typically, the complete queue has very few entries + * queued to it before the queue is emptied by + * ahc_linux_run_complete_queue, so sorting the entries + * by generation number should be inexpensive. + * We perform the sort so that commands that complete + * with an error are retuned in the order origionally + * queued to the controller so that any subsequent retries + * are performed in order. The underlying ahc routines do + * not guarantee the order that aborted commands will be + * returned to us. + */ + struct ahc_completeq *completeq; + struct ahc_cmd *list_cmd; + struct ahc_cmd *acmd; + + /* + * Map CAM error codes into Linux Error codes. We + * avoid the conversion so that the DV code has the + * full error information available when making + * state change decisions. + */ + if (AHC_DV_CMD(cmd) == FALSE) { + u_int new_status; + + switch (ahc_cmd_get_transaction_status(cmd)) { + case CAM_REQ_INPROG: + case CAM_REQ_CMP: + case CAM_SCSI_STATUS_ERROR: + new_status = DID_OK; + break; + case CAM_REQ_ABORTED: + new_status = DID_ABORT; + break; + case CAM_BUSY: + new_status = DID_BUS_BUSY; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + new_status = DID_BAD_TARGET; + break; + case CAM_SEL_TIMEOUT: + new_status = DID_NO_CONNECT; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + new_status = DID_RESET; + break; + case CAM_UNCOR_PARITY: + new_status = DID_PARITY; + break; + case CAM_CMD_TIMEOUT: + new_status = DID_TIME_OUT; + break; + case CAM_UA_ABORT: + case CAM_REQ_CMP_ERR: + case CAM_AUTOSENSE_FAIL: + case CAM_NO_HBA: + case CAM_DATA_RUN_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_SEQUENCE_FAIL: + case CAM_CCB_LEN_ERR: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TERMIO: + case CAM_UNREC_HBA_ERROR: + case CAM_REQ_TOO_BIG: + new_status = DID_ERROR; + break; + case CAM_REQUEUE_REQ: + /* + * If we want the request requeued, make sure there + * are sufficent retries. In the old scsi error code, + * we used to be able to specify a result code that + * bypassed the retry count. Now we must use this + * hack. We also "fake" a check condition with + * a sense code of ABORTED COMMAND. This seems to + * evoke a retry even if this command is being sent + * via the eh thread. Ick! Ick! Ick! + */ + if (cmd->retries > 0) + cmd->retries--; + new_status = DID_OK; + ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); + cmd->result |= (DRIVER_SENSE << 24); + memset(cmd->sense_buffer, 0, + sizeof(cmd->sense_buffer)); + cmd->sense_buffer[0] = SSD_ERRCODE_VALID + | SSD_CURRENT_ERROR; + cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; break; - } - /* - * Drop down to a single opening, and treat this - * as if the target return BUSY SCSI status. - */ - dev->openings = 1; - /* FALLTHROUGH */ - } - case SCSI_STATUS_BUSY: - { - /* - * Set a short timer to defer sending commands for - * a bit since Linux will not delay in this case. - */ - if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) { - printf("%s:%c:%d: Device Timer still active during " - "busy processing\n", ahc_name(ahc), - dev->target->channel, dev->target->target); + default: + /* We should never get here */ + new_status = DID_ERROR; break; } - dev->flags |= AHC_DEV_TIMER_ACTIVE; - dev->qfrozen++; - init_timer(&dev->timer); - dev->timer.data = (u_long)dev; - dev->timer.expires = jiffies + (HZ/2); - dev->timer.function = ahc_linux_dev_timed_unfreeze; - add_timer(&dev->timer); - break; - } + + ahc_cmd_set_transaction_status(cmd, new_status); } + + completeq = &ahc->platform_data->completeq; + list_cmd = TAILQ_FIRST(completeq); + acmd = (struct ahc_cmd *)cmd; + while (list_cmd != NULL + && acmd_scsi_cmd(list_cmd).serial_number + < acmd_scsi_cmd(acmd).serial_number) + list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); + if (list_cmd != NULL) + TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); + else + TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); } static void -ahc_linux_filter_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb) +ahc_linux_filter_inquiry(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { - switch (cmd->cmnd[0]) { - case INQUIRY: - { - struct ahc_devinfo devinfo; - struct scsi_inquiry *inq; - struct scsi_inquiry_data *sid; - struct ahc_initiator_tinfo *tinfo; - struct ahc_transinfo *user; - struct ahc_transinfo *goal; - struct ahc_transinfo *curr; - struct ahc_tmode_tstate *tstate; - struct ahc_syncrate *syncrate; - struct ahc_linux_device *dev; - u_int scsiid; - u_int maxsync; - int transferred_len; - int minlen; - u_int width; - u_int period; - u_int offset; - u_int ppr_options; - - /* - * Validate the command. We only want to filter - * standard inquiry commands, not those querying - * Vital Product Data. - */ - inq = (struct scsi_inquiry *)cmd->cmnd; - if ((inq->byte2 & SI_EVPD) != 0 - || inq->page_code != 0) - break; - - if (cmd->use_sg != 0) { - printf("%s: SG Inquiry response ignored\n", - ahc_name(ahc)); - break; - } - transferred_len = ahc_get_transfer_length(scb) - - ahc_get_residual(scb); - sid = (struct scsi_inquiry_data *)cmd->request_buffer; + struct scsi_inquiry_data *sid; + struct ahc_initiator_tinfo *tinfo; + struct ahc_transinfo *user; + struct ahc_transinfo *goal; + struct ahc_transinfo *curr; + struct ahc_tmode_tstate *tstate; + struct ahc_syncrate *syncrate; + struct ahc_linux_device *dev; + u_int maxsync; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int trans_version; + u_int prot_version; - /* - * Determine if this lun actually exists. If so, - * hold on to its corresponding device structure. - * If not, make sure we release the device and - * don't bother processing the rest of this inquiry - * command. - */ - dev = ahc_linux_get_device(ahc, cmd->channel, - cmd->target, cmd->lun, - /*alloc*/FALSE); - if (transferred_len >= 1 - && SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { + /* + * Determine if this lun actually exists. If so, + * hold on to its corresponding device structure. + * If not, make sure we release the device and + * don't bother processing the rest of this inquiry + * command. + */ + dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', + devinfo->target, devinfo->lun, + /*alloc*/TRUE); - dev->flags &= ~AHC_DEV_UNCONFIGURED; - } else { - dev->flags |= AHC_DEV_UNCONFIGURED; - break; - } + sid = (struct scsi_inquiry_data *)dev->target->inq_data; + if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { - /* - * Update our notion of this device's transfer - * negotiation capabilities. - */ - scsiid = BUILD_SCSIID(ahc, cmd); - ahc_compile_devinfo(&devinfo, SCSIID_OUR_ID(scsiid), - cmd->target, cmd->lun, - SCSIID_CHANNEL(ahc, scsiid), - ROLE_INITIATOR); - tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, - devinfo.our_scsiid, - devinfo.target, &tstate); - user = &tinfo->user; - goal = &tinfo->goal; - curr = &tinfo->curr; - width = user->width; - period = user->period; - offset = user->offset; - ppr_options = user->ppr_options; - minlen = offsetof(struct scsi_inquiry_data, version) + 1; - if (transferred_len >= minlen) { - curr->protocol_version = SID_ANSI_REV(sid); + dev->flags &= ~AHC_DEV_UNCONFIGURED; + } else { + dev->flags |= AHC_DEV_UNCONFIGURED; + return; + } - /* - * Only attempt SPI3 once we've verified that - * the device claims to support SPI3 features. - */ - if (curr->protocol_version < SCSI_REV_2) - curr->transport_version = SID_ANSI_REV(sid); - else - curr->transport_version = SCSI_REV_2; - } + /* + * Update our notion of this device's transfer + * negotiation capabilities. + */ + tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + user = &tinfo->user; + goal = &tinfo->goal; + curr = &tinfo->curr; + width = user->width; + period = user->period; + offset = user->offset; + ppr_options = user->ppr_options; + trans_version = user->transport_version; + prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid)); - minlen = offsetof(struct scsi_inquiry_data, flags) + 1; - if (transferred_len >= minlen - && (sid->additional_length + 4) >= minlen) { - if ((sid->flags & SID_WBus16) == 0) - width = MSG_EXT_WDTR_BUS_8_BIT; - if ((sid->flags & SID_Sync) == 0) { - period = 0; - offset = 0; - ppr_options = 0; - } - } else { - /* Keep current settings */ - break; - } - minlen = offsetof(struct scsi_inquiry_data, spi3data) + 1; - /* - * This is a kludge to deal with inquiry requests that - * are not large enough for us to pull the spi3/4 bits. - * In this case, we assume that a device that tells us - * they can provide inquiry data that spans the SPI3 - * bits and says its SCSI3 can handle a PPR request. - * If the inquiry request has sufficient buffer space to - * cover SPI3 bits, we honor them regardless of reported - * SCSI REV. We also allow any device that has had its - * goal ppr_options set to allow DT speeds to keep that - * option if a short inquiry occurs that would fail the - * normal tests outlined above. - */ - if ((sid->additional_length + 4) >= minlen) { - if (transferred_len >= minlen) { - if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) - ppr_options = 0; - } else if ((goal->ppr_options & MSG_EXT_PPR_DT_REQ)== 0) - ppr_options = 0; + /* + * Only attempt SPI3/4 once we've verified that + * the device claims to support SPI3/4 features. + */ + if (prot_version < SCSI_REV_2) + trans_version = SID_ANSI_REV(sid); + else + trans_version = SCSI_REV_2; - if (curr->protocol_version > SCSI_REV_2) - curr->transport_version = 3; - } else { - ppr_options = 0; - } - ahc_validate_width(ahc, /*tinfo limit*/NULL, &width, - ROLE_UNKNOWN); - if ((ahc->features & AHC_ULTRA2) != 0) - maxsync = AHC_SYNCRATE_DT; - else if ((ahc->features & AHC_ULTRA) != 0) - maxsync = AHC_SYNCRATE_ULTRA; - else - maxsync = AHC_SYNCRATE_FAST; + if ((sid->flags & SID_WBus16) == 0) + width = MSG_EXT_WDTR_BUS_8_BIT; + if ((sid->flags & SID_Sync) == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + if ((sid->spi3data & SID_SPI_QAS) == 0) + ppr_options &= ~MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_IUS) == 0) + ppr_options &= (MSG_EXT_PPR_DT_REQ + | MSG_EXT_PPR_QAS_REQ); + + if (prot_version > SCSI_REV_2 + && ppr_options != 0) + trans_version = user->transport_version; + + ahc_validate_width(ahc, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN); + if ((ahc->features & AHC_ULTRA2) != 0) + maxsync = AHC_SYNCRATE_DT; + else if ((ahc->features & AHC_ULTRA) != 0) + maxsync = AHC_SYNCRATE_ULTRA; + else + maxsync = AHC_SYNCRATE_FAST; - syncrate = ahc_find_syncrate(ahc, &period, - &ppr_options, maxsync); - ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate, - &offset, width, ROLE_UNKNOWN); - if (offset == 0 || period == 0) { - period = 0; - offset = 0; - ppr_options = 0; - } - /* Apply our filtered user settings. */ - ahc_set_width(ahc, &devinfo, width, - AHC_TRANS_GOAL, /*paused*/FALSE); - ahc_set_syncrate(ahc, &devinfo, syncrate, period, - offset, ppr_options, AHC_TRANS_GOAL, - /*paused*/FALSE); - break; - } - default: - panic("ahc_linux_filter_command: Unexpected Command type %x\n", - cmd->cmnd[0]); - break; - } + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, maxsync); + ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate, + &offset, width, ROLE_UNKNOWN); + if (offset == 0 || period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + /* Apply our filtered user settings. */ + curr->transport_version = trans_version; + curr->protocol_version = prot_version; + ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_syncrate(ahc, devinfo, syncrate, period, + offset, ppr_options, AHC_TRANS_GOAL, + /*paused*/FALSE); } static void ahc_linux_sem_timeout(u_long arg) { - struct semaphore *sem; + struct ahc_softc *ahc; + u_long s; + + ahc = (struct ahc_softc *)arg; - sem = (struct semaphore *)arg; - up(sem); + ahc_lock(ahc, &s); + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + up(&ahc->platform_data->eh_sem); + } + ahc_unlock(ahc, &s); } static void -ahc_linux_freeze_sim_queue(struct ahc_softc *ahc) +ahc_linux_freeze_simq(struct ahc_softc *ahc) { ahc->platform_data->qfrozen++; - if (ahc->platform_data->qfrozen == 1) + if (ahc->platform_data->qfrozen == 1) { scsi_block_requests(ahc->platform_data->host); + + /* XXX What about Twin channels? */ + ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ); + } } static void -ahc_linux_release_sim_queue(u_long arg) +ahc_linux_release_simq(u_long arg) { struct ahc_softc *ahc; u_long s; int unblock_reqs; ahc = (struct ahc_softc *)arg; + unblock_reqs = 0; ahc_lock(ahc, &s); if (ahc->platform_data->qfrozen > 0) ahc->platform_data->qfrozen--; - if (ahc->platform_data->qfrozen == 0) { + if (ahc->platform_data->qfrozen == 0) unblock_reqs = 1; + if (AHC_DV_SIMQ_FROZEN(ahc) + && ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_RELEASE) != 0)) { + ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_RELEASE; + up(&ahc->platform_data->dv_sem); } ahc_unlock(ahc, &s); /* @@ -2508,14 +4785,10 @@ * a bottom half handler to run the queues * so we can unblock with our own lock held. */ - if (unblock_reqs) { + if (unblock_reqs) scsi_unblock_requests(ahc->platform_data->host); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_schedule(&ahc->platform_data->runq_tasklet); -#else - ahc_runq_tasklet((unsigned long)ahc); -#endif - } + + ahc_schedule_runq(ahc); } static void @@ -2549,27 +4822,41 @@ u_int saved_scbptr; u_int active_scb_index; u_int last_phase; + u_int saved_scsiid; int retval; int paused; int wait; int disconnected; + pending_scb = NULL; paused = FALSE; wait = FALSE; - ahc = *(struct ahc_softc **)cmd->host->hostdata; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; acmd = (struct ahc_cmd *)cmd; printf("%s:%d:%d:%d: Attempting to queue a%s message\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun, + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->device->lun, flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. + * In all versions of Linux, we have to work around + * a major flaw in how the mid-layer is locked down + * if we are to sleep successfully in our error handler + * while allowing our interrupt handler to run. Since + * the midlayer acquires either the io_request_lock or + * our lock prior to calling us, we must use the + * spin_unlock_irq() method for unlocking our lock. + * This will force interrupts to be enabled on the + * current CPU. Since the EH thread should not have + * been running with CPU interrupts disabled other than + * by acquiring either the io_request_lock or our own + * lock, this *should* be safe. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) spin_unlock_irq(&io_request_lock); - - ahc_lock(ahc, &s); +#endif + ahc_midlayer_entrypoint_lock(ahc, &s); /* * First determine if we currently own this command. @@ -2578,8 +4865,8 @@ * at all, and the system wanted us to just abort the * command return success. */ - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/FALSE); + dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); if (dev == NULL) { /* @@ -2587,7 +4874,8 @@ * so we must not still own the command. */ printf("%s:%d:%d:%d: Is not an active device\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = SUCCESS; goto no_cmd; } @@ -2599,7 +4887,8 @@ if (list_acmd != NULL) { printf("%s:%d:%d:%d: Command found on device queue\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); if (flag == SCB_ABORT) { TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); cmd->result = DID_ABORT << 16; @@ -2610,11 +4899,13 @@ } if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 - && ahc_search_untagged_queues(ahc, cmd, cmd->target, - cmd->channel + 'A', cmd->lun, + && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) { printf("%s:%d:%d:%d: Command found on untagged queue\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = SUCCESS; goto done; } @@ -2631,8 +4922,9 @@ /* Any SCB for this device will do for a target reset */ LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) { - if (ahc_match_scb(ahc, pending_scb, cmd->target, - cmd->channel + 'A', CAM_LUN_WILDCARD, + if (ahc_match_scb(ahc, pending_scb, cmd->device->id, + cmd->device->channel + 'A', + CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_INITIATOR) == 0) break; } @@ -2640,7 +4932,8 @@ if (pending_scb == NULL) { printf("%s:%d:%d:%d: Command not found\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); goto no_cmd; } @@ -2654,52 +4947,44 @@ /* * Ensure that the card doesn't do anything - * behind our back and that no selections have occurred - * that have not been serviced. Also make sure that we - * didn't "just" miss an interrupt that would - * affect this cmd. - */ - ahc->flags |= AHC_ALL_INTERRUPTS; - do { - if (paused) - ahc_unpause(ahc); - ahc_intr(ahc); - ahc_pause(ahc); - paused = TRUE; - ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO); - ahc_clear_critical_section(ahc); - } while ((ahc_inb(ahc, INTSTAT) & INT_PEND) != 0 - || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO))); - ahc->flags &= ~AHC_ALL_INTERRUPTS; + * behind our back and that we didn't "just" miss + * an interrupt that would affect this cmd. + */ + ahc_pause_and_flushwork(ahc); + paused = TRUE; ahc_dump_card_state(ahc); if ((pending_scb->flags & SCB_ACTIVE) == 0) { printf("%s:%d:%d:%d: Command already completed\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); goto no_cmd; } disconnected = TRUE; if (flag == SCB_ABORT) { - if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + if (ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, + pending_scb->hscb->tag, ROLE_INITIATOR, CAM_REQ_ABORTED, SEARCH_COMPLETE) > 0) { printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahc_name(ahc), cmd->channel, cmd->target, - cmd->lun); + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->device->lun); retval = SUCCESS; goto done; } - } else if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + } else if (ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, ROLE_INITIATOR, /*status*/0, SEARCH_COUNT) > 0) { disconnected = FALSE; } - if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0) { + if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { struct scb *bus_scb; bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG)); @@ -2722,10 +5007,11 @@ last_phase = ahc_inb(ahc, LASTPHASE); saved_scbptr = ahc_inb(ahc, SCBPTR); active_scb_index = ahc_inb(ahc, SCB_TAG); + saved_scsiid = ahc_inb(ahc, SAVED_SCSIID); if (last_phase != P_BUSFREE && (pending_scb->hscb->tag == active_scb_index || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)) == cmd->target))) { + && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) { /* * We're active on the bus, so assert ATN @@ -2736,7 +5022,8 @@ ahc_outb(ahc, MSG_OUT, HOST_MSG); ahc_outb(ahc, SCSISIGO, last_phase|ATNO); printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); wait = TRUE; } else if (disconnected) { @@ -2766,8 +5053,9 @@ * same element in the SCB, SCB_NEXT, for * both the qinfifo and the disconnected list. */ - ahc_search_disc_list(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + ahc_search_disc_list(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, /*stop_on_first*/TRUE, /*remove*/TRUE, /*save_state*/FALSE); @@ -2790,19 +5078,20 @@ * so we are the next SCB for this target * to run. */ - ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR, - CAM_REQUEUE_REQ, SEARCH_COMPLETE); - ahc_print_path(ahc, pending_scb); - printf("Queuing a recovery SCB\n"); + ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ, + SEARCH_COMPLETE); ahc_qinfifo_requeue_tail(ahc, pending_scb); ahc_outb(ahc, SCBPTR, saved_scbptr); - printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_print_path(ahc, pending_scb); + printf("Device is disconnected, re-queuing SCB\n"); wait = TRUE; } else { printf("%s:%d:%d:%d: Unable to deliver message\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->channel, cmd->device->id, + cmd->device->lun); retval = FAILED; goto done; } @@ -2822,9 +5111,14 @@ struct timer_list timer; int ret; + ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ahc_unlock(ahc, &s); +#else + spin_unlock_irq(ahc->platform_data->host->host_lock); +#endif init_timer(&timer); - timer.data = (u_long)&ahc->platform_data->eh_sem; + timer.data = (u_long)ahc; timer.expires = jiffies + (5 * HZ); timer.function = ahc_linux_sem_timeout; add_timer(&timer); @@ -2836,160 +5130,28 @@ printf("Timer Expired\n"); retval = FAILED; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ahc_lock(ahc, &s); - } - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - ahc_unlock(ahc, &s); - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); - ahc_runq_tasklet((unsigned long)ahc); - spin_lock_irq(&io_request_lock); - return (retval); -} - -/* - * Abort the current SCSI command(s). - */ -int -ahc_linux_abort(Scsi_Cmnd *cmd) -{ - int error; - - error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); - if (error != 0) - printf("aic7xxx_abort returns 0x%x\n", error); - return (error); -} - -/* - * Attempt to send a target reset message to the device that timed out. - */ -int -ahc_linux_dev_reset(Scsi_Cmnd *cmd) -{ - int error; - - error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); - if (error != 0) - printf("aic7xxx_dev_reset returns 0x%x\n", error); - return (error); -} - -/* - * Reset the SCSI bus. - */ -int -ahc_linux_bus_reset(Scsi_Cmnd *cmd) -{ - struct ahc_softc *ahc; - struct ahc_cmd *acmd; - u_long s; - int found; - - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); - - ahc = *(struct ahc_softc **)cmd->host->hostdata; - ahc_lock(ahc, &s); - found = ahc_reset_channel(ahc, cmd->channel + 'A', - /*initiate reset*/TRUE); - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - ahc_unlock(ahc, &s); - if (bootverbose) - printf("%s: SCSI bus reset delivered. " - "%d SCBs aborted.\n", ahc_name(ahc), found); - - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); - - spin_lock_irq(&io_request_lock); - return SUCCESS; -} - -/* - * Return the disk geometry for the given SCSI device. - */ -int -ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) -{ - int heads; - int sectors; - int cylinders; - int ret; - int extended; - struct ahc_softc *ahc; - struct buffer_head *bh; - - ahc = *((struct ahc_softc **)disk->device->host->hostdata); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); #else - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); + spin_lock_irq(ahc->platform_data->host->host_lock); #endif - - if (bh) { - ret = scsi_partsize(bh, disk->capacity, - &geom[2], &geom[0], &geom[1]); - brelse(bh); - if (ret != -1) - return (ret); - } - heads = 64; - sectors = 32; - cylinders = disk->capacity / (heads * sectors); - - if (aic7xxx_extended != 0) - extended = 1; - else if (disk->device->channel == 0) - extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0; - else - extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0; - if (extended && cylinders >= 1024) { - heads = 255; - sectors = 63; - cylinders = disk->capacity / (heads * sectors); } - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - return (0); -} - -/* - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - */ -int -ahc_linux_release(struct Scsi_Host * host) -{ - struct ahc_softc *ahc; - u_long l; - - ahc_list_lock(&l); - if (host != NULL) { - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); - if (ahc != NULL) { - u_long s; - - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, FALSE); - ahc_unlock(ahc, &s); - ahc_free(ahc); + acmd = TAILQ_FIRST(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->completeq); + ahc_midlayer_entrypoint_unlock(ahc, &s); + if (acmd != NULL) { + acmd = ahc_linux_run_complete_queue(ahc, acmd); + if (acmd != NULL) { + ahc_midlayer_entrypoint_lock(ahc, &s); + ahc_schedule_completeq(ahc, acmd); + ahc_midlayer_entrypoint_unlock(ahc, &s); } } - ahc_list_unlock(&l); - return (0); + ahc_schedule_runq(ahc); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + return (retval); } void @@ -3030,9 +5192,3 @@ } } } - -#if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static Scsi_Host_Template driver_template = AIC7XXX; -Scsi_Host_Template *aic7xxx_driver_template = &driver_template; -#include "../scsi_module.c" -#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_osm.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_osm.h --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_osm.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_osm.h 2003-02-21 16:32:35.000000000 +0000 @@ -18,9 +18,7 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 $ - * - * Copyright (c) 2000-2001 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,7 +53,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#123 $ * */ #ifndef _AIC7XXX_LINUX_H_ @@ -67,12 +65,14 @@ #include #include #include +#include #include #ifndef AHC_MODVERSION_FILE #define __NO_VERSION__ #endif #include #include +#include #ifndef KERNEL_VERSION #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) @@ -87,8 +87,9 @@ #endif /* Core SCSI definitions */ -#include "../scsi.h" -#include "../hosts.h" +#define AIC_LIB_PREFIX ahc +#include "scsi.h" +#include "hosts.h" /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD @@ -98,6 +99,21 @@ #include "cam.h" #include "queue.h" #include "scsi_message.h" +#include "aiclib.h" + +/*********************************** Debugging ********************************/ +#ifdef CONFIG_AIC7XXX_DEBUG_ENABLE +#ifdef CONFIG_AIC7XXX_DEBUG_MASK +#define AHC_DEBUG 1 +#define AHC_DEBUG_OPTS CONFIG_AIC7XXX_DEBUG_MASK +#else +/* + * Compile in debugging code, but do not enable any printfs. + */ +#define AHC_DEBUG 1 +#endif +/* No debugging code. */ +#endif /************************* Forward Declarations *******************************/ struct ahc_softc; @@ -138,8 +154,9 @@ /************************* Configuration Data *********************************/ extern int aic7xxx_no_probe; +extern int aic7xxx_allow_memio; extern int aic7xxx_detect_complete; -extern Scsi_Host_Template* aic7xxx_driver_template; +extern Scsi_Host_Template aic7xxx_driver_template; /***************************** Bus Space/DMA **********************************/ @@ -240,176 +257,52 @@ */ #define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op) -/************************** SCSI Constants/Structures *************************/ -#define SCSI_REV_2 2 -#define SCSI_STATUS_OK 0x00 -#define SCSI_STATUS_CHECK_COND 0x02 -#define SCSI_STATUS_COND_MET 0x04 -#define SCSI_STATUS_BUSY 0x08 -#define SCSI_STATUS_INTERMED 0x10 -#define SCSI_STATUS_INTERMED_COND_MET 0x14 -#define SCSI_STATUS_RESERV_CONFLICT 0x18 -#define SCSI_STATUS_CMD_TERMINATED 0x22 -#define SCSI_STATUS_QUEUE_FULL 0x28 +/************************** Timer DataStructures ******************************/ +typedef struct timer_list ahc_timer_t; -/* - * 6 byte request sense CDB format. - */ -struct scsi_sense -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; - -struct scsi_sense_data -{ - uint8_t error_code; - uint8_t segment; - uint8_t flags; - uint8_t info[4]; - uint8_t extra_len; - uint8_t cmd_spec_info[4]; - uint8_t add_sense_code; - uint8_t add_sense_code_qual; - uint8_t fru; - uint8_t sense_key_spec[3]; - uint8_t extra_bytes[14]; -}; +/********************************** Includes **********************************/ +#if CONFIG_AIC7XXX_REG_PRETTY_PRINT +#define AIC_DEBUG_REGISTERS 1 +#else +#define AIC_DEBUG_REGISTERS 0 +#endif +#include "aic7xxx.h" -struct scsi_inquiry -{ - u_int8_t opcode; - u_int8_t byte2; -#define SI_EVPD 0x01 - u_int8_t page_code; - u_int8_t reserved; - u_int8_t length; - u_int8_t control; -}; +/***************************** Timer Facilities *******************************/ +#define ahc_timer_init init_timer +#define ahc_timer_stop del_timer +typedef void ahc_linux_callback_t (u_long); +static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec, + ahc_callback_t *func, void *arg); +static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec); -struct scsi_inquiry_data +static __inline void +ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg) { - uint8_t device; -#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f) -#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5) -#define SID_QUAL_LU_CONNECTED 0x00 /* - * The specified peripheral device - * type is currently connected to - * logical unit. If the target cannot - * determine whether or not a physical - * device is currently connected, it - * shall also use this peripheral - * qualifier when returning the INQUIRY - * data. This peripheral qualifier - * does not mean that the device is - * ready for access by the initiator. - */ -#define SID_QUAL_LU_OFFLINE 0x01 /* - * The target is capable of supporting - * the specified peripheral device type - * on this logical unit; however, the - * physical device is not currently - * connected to this logical unit. - */ -#define SID_QUAL_RSVD 0x02 -#define SID_QUAL_BAD_LU 0x03 /* - * The target is not capable of - * supporting a physical device on - * this logical unit. For this - * peripheral qualifier the peripheral - * device type shall be set to 1Fh to - * provide compatibility with previous - * versions of SCSI. All other - * peripheral device type values are - * reserved for this peripheral - * qualifier. - */ -#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) - uint8_t dev_qual2; -#define SID_QUAL2 0x7F -#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) - uint8_t version; -#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07) -#define SCSI_REV_0 0 -#define SCSI_REV_CCS 1 -#define SCSI_REV_2 2 -#define SCSI_REV_SPC 3 -#define SCSI_REV_SPC2 4 - -#define SID_ECMA 0x38 -#define SID_ISO 0xC0 - uint8_t response_format; -#define SID_AENC 0x80 -#define SID_TrmIOP 0x40 - uint8_t additional_length; - uint8_t reserved[2]; - uint8_t flags; -#define SID_SftRe 0x01 -#define SID_CmdQue 0x02 -#define SID_Linked 0x08 -#define SID_Sync 0x10 -#define SID_WBus16 0x20 -#define SID_WBus32 0x40 -#define SID_RelAdr 0x80 -#define SID_VENDOR_SIZE 8 - char vendor[SID_VENDOR_SIZE]; -#define SID_PRODUCT_SIZE 16 - char product[SID_PRODUCT_SIZE]; -#define SID_REVISION_SIZE 4 - char revision[SID_REVISION_SIZE]; - /* - * The following fields were taken from SCSI Primary Commands - 2 - * (SPC-2) Revision 14, Dated 11 November 1999 - */ -#define SID_VENDOR_SPECIFIC_0_SIZE 20 - u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE]; - /* - * An extension of SCSI Parallel Specific Values - */ -#define SID_SPI_IUS 0x01 -#define SID_SPI_QAS 0x02 -#define SID_SPI_CLOCK_ST 0x00 -#define SID_SPI_CLOCK_DT 0x04 -#define SID_SPI_CLOCK_DT_ST 0x0C -#define SID_SPI_MASK 0x0F - uint8_t spi3data; - uint8_t reserved2; - /* - * Version Descriptors, stored 2 byte values. - */ - uint8_t version1[2]; - uint8_t version2[2]; - uint8_t version3[2]; - uint8_t version4[2]; - uint8_t version5[2]; - uint8_t version6[2]; - uint8_t version7[2]; - uint8_t version8[2]; + struct ahc_softc *ahc; - uint8_t reserved3[22]; - -#define SID_VENDOR_SPECIFIC_1_SIZE 160 - uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE]; -}; - -/********************************** Includes **********************************/ -/* Host template and function declarations referenced by the template. */ -#include "aic7xxx_host.h" + ahc = (struct ahc_softc *)arg; + del_timer(timer); + timer->data = (u_long)arg; + timer->expires = jiffies + (usec * HZ)/1000000; + timer->function = (ahc_linux_callback_t*)func; + add_timer(timer); +} -/* Core driver definitions */ -#include "aic7xxx.h" +static __inline void +ahc_scb_timer_reset(struct scb *scb, u_int usec) +{ + mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); +} -/* SMP support */ +/***************************** SMP support ************************************/ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) #include #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) #include #endif -#define AIC7XXX_DRIVER_VERSION "6.2.8" +#define AIC7XXX_DRIVER_VERSION "6.2.28" /**************************** Front End Queues ********************************/ /* @@ -456,8 +349,9 @@ AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ - AHC_DEV_PERIODIC_OTAG = 0x40 /* Send OTAG to prevent starvation */ -} ahc_dev_flags; + AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ + AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ +} ahc_linux_dev_flags; struct ahc_linux_target; struct ahc_linux_device { @@ -500,7 +394,7 @@ u_int tag_success_count; #define AHC_TAG_SUCCESS_INTERVAL 50 - ahc_dev_flags flags; + ahc_linux_dev_flags flags; /* * Per device timer. @@ -540,16 +434,54 @@ #define AHC_OTAG_THRESH 500 int lun; + Scsi_Device *scsi_device; struct ahc_linux_target *target; }; +typedef enum { + AHC_DV_REQUIRED = 0x01, + AHC_INQ_VALID = 0x02, + AHC_BASIC_DV = 0x04, + AHC_ENHANCED_DV = 0x08 +} ahc_linux_targ_flags; + +/* DV States */ +typedef enum { + AHC_DV_STATE_EXIT = 0, + AHC_DV_STATE_INQ_SHORT_ASYNC, + AHC_DV_STATE_INQ_ASYNC, + AHC_DV_STATE_INQ_ASYNC_VERIFY, + AHC_DV_STATE_TUR, + AHC_DV_STATE_REBD, + AHC_DV_STATE_INQ_VERIFY, + AHC_DV_STATE_WEB, + AHC_DV_STATE_REB, + AHC_DV_STATE_SU, + AHC_DV_STATE_BUSY +} ahc_dv_state; + struct ahc_linux_target { - struct ahc_linux_device *devices[AHC_NUM_LUNS]; - int channel; - int target; - int refcount; - struct ahc_transinfo last_tinfo; - struct ahc_softc *ahc; + struct ahc_linux_device *devices[AHC_NUM_LUNS]; + int channel; + int target; + int refcount; + struct ahc_transinfo last_tinfo; + struct ahc_softc *ahc; + ahc_linux_targ_flags flags; + struct scsi_inquiry_data *inq_data; + /* + * The next "fallback" period to use for narrow/wide transfers. + */ + uint8_t dv_next_narrow_period; + uint8_t dv_next_wide_period; + uint8_t dv_max_width; + uint8_t dv_max_ppr_options; + uint8_t dv_last_ppr_options; + u_int dv_echo_size; + ahc_dv_state dv_state; + u_int dv_state_retry; + char *dv_buffer; + char *dv_buffer1; }; /********************* Definitions Required by the Core ***********************/ @@ -564,6 +496,10 @@ /* * Per-SCB OSM storage. */ +typedef enum { + AHC_UP_EH_SEMAPHORE = 0x1 +} ahc_linux_scb_flags; + struct scb_platform_data { struct ahc_linux_device *dev; bus_addr_t buf_busaddr; @@ -571,6 +507,8 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) uint32_t resid; /* Transfer residual */ #endif + uint32_t sense_resid; /* Auto-Sense residual */ + ahc_linux_scb_flags flags; }; /* @@ -579,7 +517,16 @@ * alignment restrictions of the various platforms supported by * this driver. */ +typedef enum { + AHC_DV_WAIT_SIMQ_EMPTY = 0x01, + AHC_DV_WAIT_SIMQ_RELEASE = 0x02, + AHC_DV_ACTIVE = 0x04, + AHC_DV_SHUTDOWN = 0x08, + AHC_RUN_CMPLT_Q_TIMER = 0x10 +} ahc_linux_softc_flags; + TAILQ_HEAD(ahc_completeq, ahc_cmd); + struct ahc_platform_data { /* * Fields accessed from interrupt context. @@ -588,21 +535,29 @@ TAILQ_HEAD(, ahc_linux_device) device_runq; struct ahc_completeq completeq; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) spinlock_t spin_lock; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct tasklet_struct runq_tasklet; #endif u_int qfrozen; + pid_t dv_pid; + struct timer_list completeq_timer; struct timer_list reset_timer; struct semaphore eh_sem; + struct semaphore dv_sem; + struct semaphore dv_cmd_sem; /* XXX This needs to be in + * the target struct + */ + struct scsi_device *dv_scsi_dev; struct Scsi_Host *host; /* pointer to scsi host */ #define AHC_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ bus_addr_t hw_dma_mask; + ahc_linux_softc_flags flags; }; /************************** OS Utility Wrappers *******************************/ @@ -724,6 +679,12 @@ static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags); static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags); +/* Lock acquisition and release of the above lock in midlayer entry points. */ +static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *, + unsigned long *flags); +static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *, + unsigned long *flags); + /* Lock held during command compeletion to the upper layer */ static __inline void ahc_done_lockinit(struct ahc_softc *); static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags); @@ -756,22 +717,54 @@ } static __inline void +ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags) +{ + /* + * In 2.5.X, the midlayer takes our lock just before + * calling us, so avoid locking again. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_lock(ahc, flags); +#endif +} + +static __inline void +ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags) +{ + /* + * In 2.5.X, the midlayer takes our lock just before + * calling us and unlocks when we return, so let it do the unlock. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahc_unlock(ahc, flags); +#endif +} + +static __inline void ahc_done_lockinit(struct ahc_softc *ahc) { - /* We don't own the iorequest lock, so we don't initialize it. */ + /* + * In 2.5.X, our own lock is held during completions. + * In previous versions, the io_request_lock is used. + * In either case, we can't initialize this lock again. + */ } static __inline void ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) *flags = 0; spin_lock_irqsave(&io_request_lock, *flags); +#endif } static __inline void ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) spin_unlock_irqrestore(&io_request_lock, *flags); +#endif } static __inline void @@ -793,8 +786,9 @@ spin_unlock_irqrestore(&ahc_list_spinlock, *flags); } -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,93) */ +static __inline void ahc_lockinit(struct ahc_softc *ahc) { } @@ -872,6 +866,7 @@ #define PCIM_CMD_BUSMASTEREN 0x0004 #define PCIM_CMD_MWRICEN 0x0010 #define PCIM_CMD_PERRESPEN 0x0040 +#define PCIM_CMD_SERRESPEN 0x0100 #define PCIR_STATUS 0x06 #define PCIR_REVID 0x08 #define PCIR_PROGIF 0x09 @@ -1019,38 +1014,99 @@ #define pci_unmap_single(pdev, buffer, buflen, direction) #endif -/*********************** Transaction Access Wrappers **************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) +#define ahc_pci_set_dma_mask pci_set_dma_mask +#else +/* + * Always "return" 0 for success. + */ +#define ahc_pci_set_dma_mask(dev_softc, mask) \ + (((dev_softc)->dma_mask = mask) && 0) +#endif +/**************************** Proc FS Support *********************************/ +int ahc_linux_proc_info(char *, char **, off_t, int, int, int); + +/*************************** Domain Validation ********************************/ +#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete) +#define AHC_DV_SIMQ_FROZEN(ahc) \ + ((((ahc)->platform_data->flags & AHC_DV_ACTIVE) != 0) \ + && (ahc)->platform_data->qfrozen == 1) + +/*********************** Transaction Access Wrappers *************************/ +static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); static __inline void ahc_set_transaction_status(struct scb *, uint32_t); +static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); +static __inline void ahc_set_scsi_status(struct scb *, uint32_t); +static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahc_get_transaction_status(struct scb *); +static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahc_get_scsi_status(struct scb *); +static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); +static __inline u_long ahc_get_transfer_length(struct scb *); +static __inline int ahc_get_transfer_dir(struct scb *); +static __inline void ahc_set_residual(struct scb *, u_long); +static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid); +static __inline u_long ahc_get_residual(struct scb *); +static __inline u_long ahc_get_sense_residual(struct scb *); +static __inline int ahc_perform_autosense(struct scb *); +static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *, + struct scb *); +static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *, + struct ahc_devinfo *); +static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, + struct scb *scb); +static __inline void ahc_freeze_scb(struct scb *scb); + +static __inline +void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~(CAM_STATUS_MASK << 16); + cmd->result |= status << 16; +} + static __inline void ahc_set_transaction_status(struct scb *scb, uint32_t status) { - scb->io_ctx->result &= ~(CAM_STATUS_MASK << 16); - scb->io_ctx->result |= status << 16; + ahc_cmd_set_transaction_status(scb->io_ctx,status); +} + +static __inline +void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~0xFFFF; + cmd->result |= status; } -static __inline void ahc_set_scsi_status(struct scb *, uint32_t); static __inline void ahc_set_scsi_status(struct scb *scb, uint32_t status) { - scb->io_ctx->result &= ~0xFFFF; - scb->io_ctx->result |= status; + ahc_cmd_set_scsi_status(scb->io_ctx, status); +} + +static __inline +uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd) +{ + return ((cmd->result >> 16) & CAM_STATUS_MASK); } -static __inline uint32_t ahc_get_transaction_status(struct scb *); static __inline uint32_t ahc_get_transaction_status(struct scb *scb) { - return ((scb->io_ctx->result >> 16) & CAM_STATUS_MASK); + return (ahc_cmd_get_transaction_status(scb->io_ctx)); +} + +static __inline +uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd) +{ + return (cmd->result & 0xFFFF); } -static __inline uint32_t ahc_get_scsi_status(struct scb *); static __inline uint32_t ahc_get_scsi_status(struct scb *scb) { - return (scb->io_ctx->result & 0xFFFF); + return (ahc_cmd_get_scsi_status(scb->io_ctx)); } -static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); static __inline void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type) { @@ -1060,14 +1116,12 @@ */ } -static __inline u_long ahc_get_transfer_length(struct scb *); static __inline u_long ahc_get_transfer_length(struct scb *scb) { return (scb->platform_data->xfer_len); } -static __inline int ahc_get_transfer_dir(struct scb *); static __inline int ahc_get_transfer_dir(struct scb *scb) { @@ -1092,7 +1146,6 @@ #endif } -static __inline void ahc_set_residual(struct scb *, u_long); static __inline void ahc_set_residual(struct scb *scb, u_long resid) { @@ -1103,14 +1156,12 @@ #endif } -static __inline void ahc_set_sense_residual(struct scb *, u_long); static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid) { - /* This can't be reported in Linux */ + scb->platform_data->sense_resid = resid; } -static __inline u_long ahc_get_residual(struct scb *); static __inline u_long ahc_get_residual(struct scb *scb) { @@ -1121,7 +1172,12 @@ #endif } -static __inline int ahc_perform_autosense(struct scb *); +static __inline +u_long ahc_get_sense_residual(struct scb *scb) +{ + return (scb->platform_data->sense_resid); +} + static __inline int ahc_perform_autosense(struct scb *scb) { @@ -1139,8 +1195,6 @@ return (sizeof(struct scsi_sense_data)); } -static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *, - struct ahc_devinfo *); static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) @@ -1148,8 +1202,6 @@ /* Nothing to do here for linux */ } -static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, - struct scb *scb); static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb) { @@ -1159,11 +1211,14 @@ int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg); void ahc_platform_free(struct ahc_softc *ahc); void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb); -static __inline void ahc_freeze_scb(struct scb *scb); + static __inline void ahc_freeze_scb(struct scb *scb) { - /* Noting to do here for linux */ + if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { + scb->io_ctx->result |= CAM_DEV_QFRZN << 16; + scb->platform_data->dev->qfrozen++; + } } void ahc_platform_set_tags(struct ahc_softc *ahc, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2003-01-22 22:10:29.000000000 +0000 @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#32 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#43 $ */ #include "aic7xxx_osm.h" @@ -93,7 +93,7 @@ * list for extra sanity. */ ahc_list_lock(&l); - ahc = ahc_find_softc((struct ahc_softc *)pdev->driver_data); + ahc = ahc_find_softc((struct ahc_softc *)pci_get_drvdata(pdev)); if (ahc != NULL) { u_long s; @@ -161,18 +161,14 @@ pci_set_master(pdev); if (sizeof(bus_addr_t) > 4 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) && ahc_linux_get_memsize() > 0x80000000 - && pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) { -#else - && ahc_linux_get_memsize() > 0x80000000) { - - ahc->dev_softc->dma_mask = - (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); -#endif + && ahc_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) { ahc->flags |= AHC_39BIT_ADDRESSING; ahc->platform_data->hw_dma_mask = (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); + } else { + ahc_pci_set_dma_mask(pdev, 0xFFFFFFFF); + ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; } #endif ahc->dev_softc = pci; @@ -184,7 +180,7 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_drvdata(pdev, ahc); if (aic7xxx_detect_complete) - ahc_linux_register_host(ahc, aic7xxx_driver_template); + ahc_linux_register_host(ahc, &aic7xxx_driver_template); #endif return (0); } @@ -222,6 +218,9 @@ static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base) { + if (aic7xxx_allow_memio == 0) + return (ENOMEM); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) *base = pci_resource_start(ahc->dev_softc, 0); #else @@ -233,8 +232,7 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) if (check_region(*base, 256) != 0) return (ENOMEM); - else - request_region(*base, 256, "aic7xxx"); + request_region(*base, 256, "aic7xxx"); #else if (request_region(*base, 256, "aic7xxx") == 0) return (ENOMEM); @@ -314,10 +312,10 @@ * Do a quick test to see if memory mapped * I/O is functioning correctly. */ - if (ahc_inb(ahc, HCNTRL) == 0xFF) { + if (ahc_pci_test_register_access(ahc) != 0) { printf("aic7xxx: PCI Device %d:%d:%d " - "failed memory mapped test\n", + "failed memory mapped test. Using PIO.\n", ahc_get_pci_bus(ahc->dev_softc), ahc_get_pci_slot(ahc->dev_softc), ahc_get_pci_function(ahc->dev_softc)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_pci.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_pci.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_pci.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_pci.c 2003-01-22 22:10:29.000000000 +0000 @@ -39,9 +39,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#46 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.2.2.14 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -641,6 +641,7 @@ #define AHC_494X_SLOT_CHANNEL_D 7 #define DEVCONFIG 0x40 +#define PCIERRGENDIS 0x80000000ul #define SCBSIZE32 0x00010000ul /* aic789X only */ #define REXTVALID 0x00001000ul /* ultra cards only */ #define MPORTMODE 0x00000400ul /* aic7870+ only */ @@ -660,6 +661,14 @@ #define CACHESIZE 0x0000003ful /* only 5 bits */ #define LATTIME 0x0000ff00ul +/* PCI STATUS definitions */ +#define DPE 0x80 +#define SSE 0x40 +#define RMA 0x20 +#define RTA 0x10 +#define STA 0x08 +#define DPR 0x01 + static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device, uint16_t subvendor, uint16_t subdevice); static int ahc_ext_scbram_present(struct ahc_softc *ahc); @@ -771,18 +780,17 @@ int ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) { - struct scb_data *shared_scb_data; - u_long l; - u_long s; - u_int command; - u_int our_id = 0; - u_int sxfrctl1; - u_int scsiseq; - u_int dscommand0; - int error; - uint8_t sblkctl; + u_long l; + u_int command; + u_int our_id; + u_int sxfrctl1; + u_int scsiseq; + u_int dscommand0; + uint32_t devconfig; + int error; + uint8_t sblkctl; - shared_scb_data = NULL; + our_id = 0; error = entry->setup(ahc); if (error != 0) return (error); @@ -803,6 +811,8 @@ */ ahc_intr_enable(ahc, FALSE); + devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); + /* * If we need to support high memory, enable dual * address cycles. This bit must be set to enable @@ -810,21 +820,30 @@ * 64bit bus (PCI64BIT set in devconfig). */ if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { - uint32_t devconfig; if (bootverbose) printf("%s: Enabling 39Bit Addressing\n", ahc_name(ahc)); - devconfig = ahc_pci_read_config(ahc->dev_softc, - DEVCONFIG, /*bytes*/4); devconfig |= DACEN; - ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, - devconfig, /*bytes*/4); } + /* Ensure that pci error generation, a test feature, is disabled. */ + devconfig |= PCIERRGENDIS; + + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); + /* Ensure busmastering is enabled */ command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); command |= PCIM_CMD_BUSMASTEREN; + + /* + * Disable PCI parity error reporting. Users typically + * do this to work around broken PCI chipsets that get + * the parity timing wrong and thus generate lots of spurious + * errors. + */ + if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) + command &= ~PCIM_CMD_PERRESPEN; ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); /* On all PCI adapters, we allow SCB paging */ @@ -941,7 +960,8 @@ * a SEEPROM. */ /* See if someone else set us up already */ - if (scsiseq != 0) { + if ((ahc->flags & AHC_NO_BIOS_INIT) == 0 + && scsiseq != 0) { printf("%s: Using left over BIOS settings\n", ahc_name(ahc)); ahc->flags &= ~AHC_USEDEFAULTS; @@ -990,11 +1010,6 @@ * Link this softc in with all other ahc instances. */ ahc_softc_insert(ahc); - - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, TRUE); - ahc_unlock(ahc, &s); - ahc_list_unlock(&l); return (0); } @@ -1195,6 +1210,75 @@ } /* + * Perform some simple tests that should catch situations where + * our registers are invalidly mapped. + */ +int +ahc_pci_test_register_access(struct ahc_softc *ahc) +{ + int error; + u_int status1; + uint32_t cmd; + uint8_t hcntrl; + + error = EIO; + + /* + * Enable PCI error interrupt status, but suppress NMIs + * generated by SERR raised due to target aborts. + */ + cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, + cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); + + /* + * First a simple test to see if any + * registers can be read. Reading + * HCNTRL has no side effects and has + * at least one bit that is guaranteed to + * be zero so it is a good register to + * use for this test. + */ + hcntrl = ahc_inb(ahc, HCNTRL); + if (hcntrl == 0xFF) + goto fail; + + /* + * Next create a situation where write combining + * or read prefetching could be initiated by the + * CPU or host bridge. Our device does not support + * either, so look for data corruption and/or flagged + * PCI errors. + */ + ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); + while (ahc_is_paused(ahc) == 0) + ; + ahc_outb(ahc, SEQCTL, PERRORDIS); + ahc_outb(ahc, SCBPTR, 0); + ahc_outl(ahc, SCB_BASE, 0x5aa555aa); + if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa) + goto fail; + + status1 = ahc_pci_read_config(ahc->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + if ((status1 & STA) != 0) + goto fail; + + error = 0; + +fail: + /* Silently clear any latched errors. */ + status1 = ahc_pci_read_config(ahc->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, + status1, /*bytes*/1); + ahc_outb(ahc, CLRINT, CLRPARERR); + ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); + return (error); +} + +/* * Check the external port logic for a serial eeprom * and termination/cable detection contrls. */ @@ -1279,13 +1363,12 @@ int i; sc_data = (uint16_t *)sc; - for (i = 0; i < 32; i++) { - uint16_t val; - int j; + for (i = 0; i < 32; i++, sc_data++) { + int j; j = i * 2; - val = ahc_inb(ahc, SRAM_BASE + j) - | ahc_inb(ahc, SRAM_BASE + j + 1) << 8; + *sc_data = ahc_inb(ahc, SRAM_BASE + j) + | ahc_inb(ahc, SRAM_BASE + j + 1) << 8; } have_seeprom = ahc_verify_cksum(sc); if (have_seeprom) @@ -1528,6 +1611,8 @@ aic785X_cable_detect(ahc, &internal50_present, &externalcable_present, &eeprom_present); + /* Can never support a wide connector. */ + internal68_present = 0; } else { aic787X_cable_detect(ahc, &internal50_present, &internal68_present, @@ -1768,6 +1853,41 @@ *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0; } +int +ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) +{ + int wait; + + if ((ahc->features & AHC_SPIOCAP) != 0 + && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) + return (0); + + /* + * Request access of the memory port. When access is + * granted, SEERDY will go high. We use a 1 second + * timeout which should be near 1 second more than + * is needed. Reason: after the chip reset, there + * should be no contention. + */ + SEEPROM_OUTB(sd, sd->sd_MS); + wait = 1000; /* 1 second timeout in msec */ + while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { + ahc_delay(1000); /* delay 1 msec */ + } + if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { + SEEPROM_OUTB(sd, 0); + return (0); + } + return(1); +} + +void +ahc_release_seeprom(struct seeprom_descriptor *sd) +{ + /* Release access to the memory port and the serial EEPROM. */ + SEEPROM_OUTB(sd, 0); +} + static void write_brdctl(struct ahc_softc *ahc, uint8_t value) { @@ -1823,13 +1943,6 @@ return (value); } -#define DPE 0x80 -#define SSE 0x40 -#define RMA 0x20 -#define RTA 0x10 -#define STA 0x08 -#define DPR 0x01 - void ahc_pci_intr(struct ahc_softc *ahc) { @@ -1919,10 +2032,8 @@ static int ahc_apa1480_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; int error; - pci = ahc->dev_softc; error = ahc_aic7860_setup(ahc); if (error != 0) return (error); @@ -1933,9 +2044,7 @@ static int ahc_aic7870_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; - pci = ahc->dev_softc; ahc->channel = 'A'; ahc->chip = AHC_AIC7870; ahc->features = AHC_AIC7870_FE; @@ -1999,13 +2108,9 @@ static int ahc_aha2940Pro_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; - int error; - pci = ahc->dev_softc; ahc->flags |= AHC_INT50_SPEEDFLEX; - error = ahc_aic7880_setup(ahc); - return (0); + return (ahc_aic7880_setup(ahc)); } static int @@ -2050,9 +2155,7 @@ static int ahc_aic7892_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; - pci = ahc->dev_softc; ahc->channel = 'A'; ahc->chip = AHC_AIC7892; ahc->features = AHC_AIC7892_FE; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_proc.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_proc.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_proc.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_proc.c 2003-01-22 22:10:29.000000000 +0000 @@ -37,7 +37,7 @@ * String handling code courtesy of Gerard Roudier's * sym driver. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#19 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#23 $ */ #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" @@ -45,7 +45,6 @@ static void copy_mem_info(struct info_str *info, char *data, int len); static int copy_info(struct info_str *info, char *fmt, ...); -static u_int scsi_calc_syncsrate(u_int period_factor); static void ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, u_int our_id, char channel, @@ -54,44 +53,6 @@ struct ahc_linux_device *dev); static int ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length); - - -int -ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) -{ - int wait; - - if ((ahc->features & AHC_SPIOCAP) != 0 - && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) - return (0); - - /* - * Request access of the memory port. When access is - * granted, SEERDY will go high. We use a 1 second - * timeout which should be near 1 second more than - * is needed. Reason: after the chip reset, there - * should be no contention. - */ - SEEPROM_OUTB(sd, sd->sd_MS); - wait = 1000; /* 1 second timeout in msec */ - while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { - ahc_delay(1000); /* delay 1 msec */ - } - if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { - SEEPROM_OUTB(sd, 0); - return (0); - } - return(1); -} - - -void -ahc_release_seeprom(struct seeprom_descriptor *sd) -{ - /* Release access to the memory port and the serial EEPROM. */ - SEEPROM_OUTB(sd, 0); -} - static void copy_mem_info(struct info_str *info, char *data, int len) @@ -135,47 +96,6 @@ return (len); } -/* - * Table of syncrates that don't follow the "divisible by 4" - * rule. This table will be expanded in future SCSI specs. - */ -static struct { - u_int period_factor; - u_int period; /* in 10ths of ns */ -} scsi_syncrates[] = { - { 0x09, 125 }, /* FAST-80 */ - { 0x0a, 250 }, /* FAST-40 40MHz */ - { 0x0b, 303 }, /* FAST-40 33MHz */ - { 0x0c, 500 } /* FAST-20 */ -}; - -/* - * Return the frequency in kHz corresponding to the given - * sync period factor. - */ -static u_int -scsi_calc_syncsrate(u_int period_factor) -{ - int i; - int num_syncrates; - - num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); - /* See if the period is in the "exception" table */ - for (i = 0; i < num_syncrates; i++) { - - if (period_factor == scsi_syncrates[i].period_factor) { - /* Period in kHz */ - return (10000000 / scsi_syncrates[i].period); - } - } - - /* - * Wasn't in the table, so use the standard - * 4 times conversion. - */ - return (10000000 / (period_factor * 4 * 10)); -} - void ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo) { @@ -186,7 +106,7 @@ speed = 3300; freq = 0; if (tinfo->offset != 0) { - freq = scsi_calc_syncsrate(tinfo->period); + freq = aic_calc_syncsrate(tinfo->period); speed = freq; } speed *= (0x01 << tinfo->width); @@ -294,19 +214,8 @@ } sd.sd_ahc = ahc; - if ((ahc->chip & AHC_VL) != 0) { - sd.sd_control_offset = SEECTL_2840; - sd.sd_status_offset = STATUS_2840; - sd.sd_dataout_offset = STATUS_2840; - sd.sd_chip = C46; - sd.sd_MS = 0; - sd.sd_RDY = EEPROM_TF; - sd.sd_CS = CS_2840; - sd.sd_CK = CK_2840; - sd.sd_DO = DO_2840; - sd.sd_DI = DI_2840; - have_seeprom = TRUE; - } else { +#if AHC_PCI_CONFIG > 0 + if ((ahc->chip & AHC_PCI) != 0) { sd.sd_control_offset = SEECTL; sd.sd_status_offset = SEECTL; sd.sd_dataout_offset = SEECTL; @@ -321,6 +230,23 @@ sd.sd_DO = SEEDO; sd.sd_DI = SEEDI; have_seeprom = ahc_acquire_seeprom(ahc, &sd); + } else +#endif + if ((ahc->chip & AHC_VL) != 0) { + sd.sd_control_offset = SEECTL_2840; + sd.sd_status_offset = STATUS_2840; + sd.sd_dataout_offset = STATUS_2840; + sd.sd_chip = C46; + sd.sd_MS = 0; + sd.sd_RDY = EEPROM_TF; + sd.sd_CS = CS_2840; + sd.sd_CK = CK_2840; + sd.sd_DO = DO_2840; + sd.sd_DI = DI_2840; + have_seeprom = TRUE; + } else { + printf("ahc_proc_write_seeprom: unsupported adapter type\n"); + goto done; } if (!have_seeprom) { @@ -344,8 +270,10 @@ sizeof(struct seeprom_config)/2); ahc_read_seeprom(&sd, (uint16_t *)ahc->seep_config, start_addr, sizeof(struct seeprom_config)/2); +#if AHC_PCI_CONFIG > 0 if ((ahc->chip & AHC_VL) == 0) ahc_release_seeprom(&sd); +#endif written = length; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx.reg linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx.reg --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx.reg 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx.reg 2003-01-22 22:10:29.000000000 +0000 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.20.2.11 2002/04/29 19:36:30 gibbs Exp $ + * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $" /* * This file is processed by the aic7xxx_asm utility for use in assembling @@ -57,14 +57,14 @@ register SCSISEQ { address 0x000 access_mode RW - bit TEMODE 0x80 - bit ENSELO 0x40 - bit ENSELI 0x20 - bit ENRSELI 0x10 - bit ENAUTOATNO 0x08 - bit ENAUTOATNI 0x04 - bit ENAUTOATNP 0x02 - bit SCSIRSTO 0x01 + field TEMODE 0x80 + field ENSELO 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field ENAUTOATNO 0x08 + field ENAUTOATNI 0x04 + field ENAUTOATNP 0x02 + field SCSIRSTO 0x01 } /* @@ -74,13 +74,13 @@ register SXFRCTL0 { address 0x001 access_mode RW - bit DFON 0x80 - bit DFPEXP 0x40 - bit FAST20 0x20 - bit CLRSTCNT 0x10 - bit SPIOEN 0x08 - bit SCAMEN 0x04 - bit CLRCHN 0x02 + field DFON 0x80 + field DFPEXP 0x40 + field FAST20 0x20 + field CLRSTCNT 0x10 + field SPIOEN 0x08 + field SCAMEN 0x04 + field CLRCHN 0x02 } /* @@ -90,13 +90,13 @@ register SXFRCTL1 { address 0x002 access_mode RW - bit BITBUCKET 0x80 - bit SWRAPEN 0x40 - bit ENSPCHK 0x20 + field BITBUCKET 0x80 + field SWRAPEN 0x40 + field ENSPCHK 0x20 mask STIMESEL 0x18 - bit ENSTIMER 0x04 - bit ACTNEGEN 0x02 - bit STPWEN 0x01 /* Powered Termination */ + field ENSTIMER 0x04 + field ACTNEGEN 0x02 + field STPWEN 0x01 /* Powered Termination */ } /* @@ -106,14 +106,14 @@ register SCSISIGI { address 0x003 access_mode RO - bit CDI 0x80 - bit IOI 0x40 - bit MSGI 0x20 - bit ATNI 0x10 - bit SELI 0x08 - bit BSYI 0x04 - bit REQI 0x02 - bit ACKI 0x01 + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 + field ATNI 0x10 + field SELI 0x08 + field BSYI 0x04 + field REQI 0x02 + field ACKI 0x01 /* * Possible phases in SCSISIGI */ @@ -137,14 +137,14 @@ register SCSISIGO { address 0x003 access_mode WO - bit CDO 0x80 - bit IOO 0x40 - bit MSGO 0x20 - bit ATNO 0x10 - bit SELO 0x08 - bit BSYO 0x04 - bit REQO 0x02 - bit ACKO 0x01 + field CDO 0x80 + field IOO 0x40 + field MSGO 0x20 + field ATNO 0x10 + field SELO 0x08 + field BSYO 0x04 + field REQO 0x02 + field ACKO 0x01 /* * Possible phases to write into SCSISIG0 */ @@ -167,9 +167,9 @@ register SCSIRATE { address 0x004 access_mode RW - bit WIDEXFER 0x80 /* Wide transfer control */ - bit ENABLE_CRC 0x40 /* CRC for D-Phases */ - bit SINGLE_EDGE 0x10 /* Disable DT Transfers */ + field WIDEXFER 0x80 /* Wide transfer control */ + field ENABLE_CRC 0x40 /* CRC for D-Phases */ + field SINGLE_EDGE 0x10 /* Disable DT Transfers */ mask SXFR 0x70 /* Sync transfer rate */ mask SXFR_ULTRA2 0x0f /* Sync transfer rate */ mask SOFS 0x0f /* Sync offset */ @@ -185,7 +185,7 @@ access_mode RW mask TID 0xf0 /* Target ID mask */ mask TWIN_TID 0x70 - bit TWIN_CHNLB 0x80 + field TWIN_CHNLB 0x80 mask OID 0x0f /* Our ID mask */ /* * SCSI Maximum Offset (p. 4-61 aic7890/91 Data Book) @@ -225,18 +225,27 @@ access_mode RW } +/* ALT_MODE registers (Ultra2 and Ultra160 chips) */ +register SXFRCTL2 { + address 0x013 + access_mode RW + field AUTORSTDIS 0x10 + field CMDDMAEN 0x08 + mask ASYNC_SETUP 0x07 +} + /* ALT_MODE register on Ultra160 chips */ register OPTIONMODE { address 0x008 access_mode RW - bit AUTORATEEN 0x80 - bit AUTOACKEN 0x40 - bit ATNMGMNTEN 0x20 - bit BUSFREEREV 0x10 - bit EXPPHASEDIS 0x08 - bit SCSIDATL_IMGEN 0x04 - bit AUTO_MSGOUT_DE 0x02 - bit DIS_MSGIN_DUALEDGE 0x01 + field AUTORATEEN 0x80 + field AUTOACKEN 0x40 + field ATNMGMNTEN 0x20 + field BUSFREEREV 0x10 + field EXPPHASEDIS 0x08 + field SCSIDATL_IMGEN 0x04 + field AUTO_MSGOUT_DE 0x02 + field DIS_MSGIN_DUALEDGE 0x01 mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE|DIS_MSGIN_DUALEDGE } @@ -254,12 +263,12 @@ register CLRSINT0 { address 0x00b access_mode WO - bit CLRSELDO 0x40 - bit CLRSELDI 0x20 - bit CLRSELINGO 0x10 - bit CLRSWRAP 0x08 - bit CLRIOERR 0x08 /* Ultra2 Only */ - bit CLRSPIORDY 0x02 + field CLRSELDO 0x40 + field CLRSELDI 0x20 + field CLRSELINGO 0x10 + field CLRSWRAP 0x08 + field CLRIOERR 0x08 /* Ultra2 Only */ + field CLRSPIORDY 0x02 } /* @@ -270,15 +279,15 @@ register SSTAT0 { address 0x00b access_mode RO - bit TARGET 0x80 /* Board acting as target */ - bit SELDO 0x40 /* Selection Done */ - bit SELDI 0x20 /* Board has been selected */ - bit SELINGO 0x10 /* Selection In Progress */ - bit SWRAP 0x08 /* 24bit counter wrap */ - bit IOERR 0x08 /* LVD Tranceiver mode changed */ - bit SDONE 0x04 /* STCNT = 0x000000 */ - bit SPIORDY 0x02 /* SCSI PIO Ready */ - bit DMADONE 0x01 /* DMA transfer completed */ + field TARGET 0x80 /* Board acting as target */ + field SELDO 0x40 /* Selection Done */ + field SELDI 0x20 /* Board has been selected */ + field SELINGO 0x10 /* Selection In Progress */ + field SWRAP 0x08 /* 24bit counter wrap */ + field IOERR 0x08 /* LVD Tranceiver mode changed */ + field SDONE 0x04 /* STCNT = 0x000000 */ + field SPIORDY 0x02 /* SCSI PIO Ready */ + field DMADONE 0x01 /* DMA transfer completed */ } /* @@ -288,13 +297,13 @@ register CLRSINT1 { address 0x00c access_mode WO - bit CLRSELTIMEO 0x80 - bit CLRATNO 0x40 - bit CLRSCSIRSTI 0x20 - bit CLRBUSFREE 0x08 - bit CLRSCSIPERR 0x04 - bit CLRPHASECHG 0x02 - bit CLRREQINIT 0x01 + field CLRSELTIMEO 0x80 + field CLRATNO 0x40 + field CLRSCSIRSTI 0x20 + field CLRBUSFREE 0x08 + field CLRSCSIPERR 0x04 + field CLRPHASECHG 0x02 + field CLRREQINIT 0x01 } /* @@ -303,14 +312,14 @@ register SSTAT1 { address 0x00c access_mode RO - bit SELTO 0x80 - bit ATNTARG 0x40 - bit SCSIRSTI 0x20 - bit PHASEMIS 0x10 - bit BUSFREE 0x08 - bit SCSIPERR 0x04 - bit PHASECHG 0x02 - bit REQINIT 0x01 + field SELTO 0x80 + field ATNTARG 0x40 + field SCSIRSTI 0x20 + field PHASEMIS 0x10 + field BUSFREE 0x08 + field SCSIPERR 0x04 + field PHASECHG 0x02 + field REQINIT 0x01 } /* @@ -319,13 +328,13 @@ register SSTAT2 { address 0x00d access_mode RO - bit OVERRUN 0x80 - bit SHVALID 0x40 /* Shaddow Layer non-zero */ - bit EXP_ACTIVE 0x10 /* SCSI Expander Active */ - bit CRCVALERR 0x08 /* CRC doesn't match (U3 only) */ - bit CRCENDERR 0x04 /* No terminal CRC packet (U3 only) */ - bit CRCREQERR 0x02 /* Illegal CRC packet req (U3 only) */ - bit DUAL_EDGE_ERR 0x01 /* Incorrect data phase (U3 only) */ + field OVERRUN 0x80 + field SHVALID 0x40 /* Shaddow Layer non-zero */ + field EXP_ACTIVE 0x10 /* SCSI Expander Active */ + field CRCVALERR 0x08 /* CRC doesn't match (U3 only) */ + field CRCENDERR 0x04 /* No terminal CRC packet (U3 only) */ + field CRCREQERR 0x02 /* Illegal CRC packet req (U3 only) */ + field DUAL_EDGE_ERR 0x01 /* Incorrect data phase (U3 only) */ mask SFCNT 0x1f } @@ -358,14 +367,14 @@ register SIMODE0 { address 0x010 access_mode RW - bit ENSELDO 0x40 - bit ENSELDI 0x20 - bit ENSELINGO 0x10 - bit ENSWRAP 0x08 - bit ENIOERR 0x08 /* LVD Tranceiver mode changes */ - bit ENSDONE 0x04 - bit ENSPIORDY 0x02 - bit ENDMADONE 0x01 + field ENSELDO 0x40 + field ENSELDI 0x20 + field ENSELINGO 0x10 + field ENSWRAP 0x08 + field ENIOERR 0x08 /* LVD Tranceiver mode changes */ + field ENSDONE 0x04 + field ENSPIORDY 0x02 + field ENDMADONE 0x01 } /* @@ -376,14 +385,14 @@ register SIMODE1 { address 0x011 access_mode RW - bit ENSELTIMO 0x80 - bit ENATNTARG 0x40 - bit ENSCSIRST 0x20 - bit ENPHASEMIS 0x10 - bit ENBUSFREE 0x08 - bit ENSCSIPERR 0x04 - bit ENPHASECHG 0x02 - bit ENREQINIT 0x01 + field ENSELTIMO 0x80 + field ENATNTARG 0x40 + field ENSCSIRST 0x20 + field ENPHASEMIS 0x10 + field ENBUSFREE 0x08 + field ENSCSIPERR 0x04 + field ENPHASECHG 0x02 + field ENREQINIT 0x01 } /* @@ -420,12 +429,12 @@ register SELTIMER { address 0x018 access_mode RW - bit STAGE6 0x20 - bit STAGE5 0x10 - bit STAGE4 0x08 - bit STAGE3 0x04 - bit STAGE2 0x02 - bit STAGE1 0x01 + field STAGE6 0x20 + field STAGE5 0x10 + field STAGE4 0x08 + field STAGE3 0x04 + field STAGE2 0x02 + field STAGE1 0x01 alias TARGIDIN } @@ -438,16 +447,16 @@ address 0x019 access_mode RW mask SELID_MASK 0xf0 - bit ONEBIT 0x08 + field ONEBIT 0x08 } register SCAMCTL { address 0x01a access_mode RW - bit ENSCAMSELO 0x80 - bit CLRSCAMSELID 0x40 - bit ALTSTIM 0x20 - bit DFLTTID 0x10 + field ENSCAMSELO 0x80 + field CLRSCAMSELID 0x40 + field ALTSTIM 0x20 + field DFLTTID 0x10 mask SCAMLVL 0x03 } @@ -471,32 +480,32 @@ register SPIOCAP { address 0x01b access_mode RW - bit SOFT1 0x80 - bit SOFT0 0x40 - bit SOFTCMDEN 0x20 - bit EXT_BRDCTL 0x10 /* External Board control */ - bit SEEPROM 0x08 /* External serial eeprom logic */ - bit EEPROM 0x04 /* Writable external BIOS ROM */ - bit ROM 0x02 /* Logic for accessing external ROM */ - bit SSPIOCPS 0x01 /* Termination and cable detection */ + field SOFT1 0x80 + field SOFT0 0x40 + field SOFTCMDEN 0x20 + field EXT_BRDCTL 0x10 /* External Board control */ + field SEEPROM 0x08 /* External serial eeprom logic */ + field EEPROM 0x04 /* Writable external BIOS ROM */ + field ROM 0x02 /* Logic for accessing external ROM */ + field SSPIOCPS 0x01 /* Termination and cable detection */ } register BRDCTL { address 0x01d - bit BRDDAT7 0x80 - bit BRDDAT6 0x40 - bit BRDDAT5 0x20 - bit BRDSTB 0x10 - bit BRDCS 0x08 - bit BRDRW 0x04 - bit BRDCTL1 0x02 - bit BRDCTL0 0x01 + field BRDDAT7 0x80 + field BRDDAT6 0x40 + field BRDDAT5 0x20 + field BRDSTB 0x10 + field BRDCS 0x08 + field BRDRW 0x04 + field BRDCTL1 0x02 + field BRDCTL0 0x01 /* 7890 Definitions */ - bit BRDDAT4 0x10 - bit BRDDAT3 0x08 - bit BRDDAT2 0x04 - bit BRDRW_ULTRA2 0x02 - bit BRDSTB_ULTRA2 0x01 + field BRDDAT4 0x10 + field BRDDAT3 0x08 + field BRDDAT2 0x04 + field BRDRW_ULTRA2 0x02 + field BRDSTB_ULTRA2 0x01 } /* @@ -525,14 +534,14 @@ */ register SEECTL { address 0x01e - bit EXTARBACK 0x80 - bit EXTARBREQ 0x40 - bit SEEMS 0x20 - bit SEERDY 0x10 - bit SEECS 0x08 - bit SEECK 0x04 - bit SEEDO 0x02 - bit SEEDI 0x01 + field EXTARBACK 0x80 + field EXTARBREQ 0x40 + field SEEMS 0x20 + field SEERDY 0x10 + field SEECS 0x08 + field SEECK 0x04 + field SEEDO 0x02 + field SEEDI 0x01 } /* * SCSI Block Control (p. 3-32) @@ -544,14 +553,14 @@ register SBLKCTL { address 0x01f access_mode RW - bit DIAGLEDEN 0x80 /* Aic78X0 only */ - bit DIAGLEDON 0x40 /* Aic78X0 only */ - bit AUTOFLUSHDIS 0x20 - bit SELBUSB 0x08 - bit ENAB40 0x08 /* LVD transceiver active */ - bit ENAB20 0x04 /* SE/HVD transceiver active */ - bit SELWIDE 0x02 - bit XCVR 0x01 /* External transceiver active */ + field DIAGLEDEN 0x80 /* Aic78X0 only */ + field DIAGLEDON 0x40 /* Aic78X0 only */ + field AUTOFLUSHDIS 0x20 + field SELBUSB 0x08 + field ENAB40 0x08 /* LVD transceiver active */ + field ENAB20 0x04 /* SE/HVD transceiver active */ + field SELWIDE 0x02 + field XCVR 0x01 /* External transceiver active */ } /* @@ -561,14 +570,14 @@ register SEQCTL { address 0x060 access_mode RW - bit PERRORDIS 0x80 - bit PAUSEDIS 0x40 - bit FAILDIS 0x20 - bit FASTMODE 0x10 - bit BRKADRINTEN 0x08 - bit STEP 0x04 - bit SEQRESET 0x02 - bit LOADRAM 0x01 + field PERRORDIS 0x80 + field PAUSEDIS 0x40 + field FAILDIS 0x20 + field FASTMODE 0x10 + field BRKADRINTEN 0x08 + field STEP 0x04 + field SEQRESET 0x02 + field LOADRAM 0x01 } /* @@ -640,8 +649,8 @@ register FLAGS { address 0x06b access_mode RO - bit ZERO 0x02 - bit CARRY 0x01 + field ZERO 0x02 + field CARRY 0x01 } register SINDIR { @@ -664,14 +673,16 @@ access_mode RO } +const STACK_SIZE 4 + /* * Board Control (p. 3-43) */ register BCTL { address 0x084 access_mode RW - bit ACE 0x08 - bit ENABLE 0x01 + field ACE 0x08 + field ENABLE 0x01 } /* @@ -681,23 +692,23 @@ register DSCOMMAND0 { address 0x084 access_mode RW - bit CACHETHEN 0x80 /* Cache Threshold enable */ - bit DPARCKEN 0x40 /* Data Parity Check Enable */ - bit MPARCKEN 0x20 /* Memory Parity Check Enable */ - bit EXTREQLCK 0x10 /* External Request Lock */ + field CACHETHEN 0x80 /* Cache Threshold enable */ + field DPARCKEN 0x40 /* Data Parity Check Enable */ + field MPARCKEN 0x20 /* Memory Parity Check Enable */ + field EXTREQLCK 0x10 /* External Request Lock */ /* aic7890/91/96/97 only */ - bit INTSCBRAMSEL 0x08 /* Internal SCB RAM Select */ - bit RAMPS 0x04 /* External SCB RAM Present */ - bit USCBSIZE32 0x02 /* Use 32byte SCB Page Size */ - bit CIOPARCKEN 0x01 /* Internal bus parity error enable */ + field INTSCBRAMSEL 0x08 /* Internal SCB RAM Select */ + field RAMPS 0x04 /* External SCB RAM Present */ + field USCBSIZE32 0x02 /* Use 32byte SCB Page Size */ + field CIOPARCKEN 0x01 /* Internal bus parity error enable */ } register DSCOMMAND1 { address 0x085 access_mode RW mask DSLATT 0xfc /* PCI latency timer (non-ultra2) */ - bit HADDLDSEL1 0x02 /* Host Address Load Select Bits */ - bit HADDLDSEL0 0x01 + field HADDLDSEL1 0x02 /* Host Address Load Select Bits */ + field HADDLDSEL0 0x01 } /* @@ -747,13 +758,13 @@ register HCNTRL { address 0x087 access_mode RW - bit POWRDN 0x40 - bit SWINT 0x10 - bit IRQMS 0x08 - bit PAUSE 0x04 - bit INTEN 0x02 - bit CHIPRST 0x01 - bit CHIPRSTACK 0x01 + field POWRDN 0x40 + field SWINT 0x10 + field IRQMS 0x08 + field PAUSE 0x04 + field INTEN 0x02 + field CHIPRST 0x01 + field CHIPRSTACK 0x01 } /* @@ -789,13 +800,13 @@ register INTSTAT { address 0x091 access_mode RW - bit BRKADRINT 0x08 - bit SCSIINT 0x04 - bit CMDCMPLT 0x02 - bit SEQINT 0x01 + field BRKADRINT 0x08 + field SCSIINT 0x04 + field CMDCMPLT 0x02 + field SEQINT 0x01 mask BAD_PHASE SEQINT /* unknown scsi bus phase */ mask SEND_REJECT 0x10|SEQINT /* sending a message reject */ - mask NO_IDENT 0x20|SEQINT /* no IDENTIFY after reconnect*/ + mask PROTO_VIOLATION 0x20|SEQINT /* SCSI protocol violation */ mask NO_MATCH 0x30|SEQINT /* no cmd match for reconnect */ mask IGN_WIDE_RES 0x40|SEQINT /* Complex IGN Wide Res Msg */ mask PDATA_REINIT 0x50|SEQINT /* @@ -858,14 +869,14 @@ register ERROR { address 0x092 access_mode RO - bit CIOPARERR 0x80 /* Ultra2 only */ - bit PCIERRSTAT 0x40 /* PCI only */ - bit MPARERR 0x20 /* PCI only */ - bit DPARERR 0x10 /* PCI only */ - bit SQPARERR 0x08 - bit ILLOPCODE 0x04 - bit ILLSADDR 0x02 - bit ILLHADDR 0x01 + field CIOPARERR 0x80 /* Ultra2 only */ + field PCIERRSTAT 0x40 /* PCI only */ + field MPARERR 0x20 /* PCI only */ + field DPARERR 0x10 /* PCI only */ + field SQPARERR 0x08 + field ILLOPCODE 0x04 + field ILLSADDR 0x02 + field ILLHADDR 0x01 } /* @@ -874,39 +885,39 @@ register CLRINT { address 0x092 access_mode WO - bit CLRPARERR 0x10 /* PCI only */ - bit CLRBRKADRINT 0x08 - bit CLRSCSIINT 0x04 - bit CLRCMDINT 0x02 - bit CLRSEQINT 0x01 + field CLRPARERR 0x10 /* PCI only */ + field CLRBRKADRINT 0x08 + field CLRSCSIINT 0x04 + field CLRCMDINT 0x02 + field CLRSEQINT 0x01 } register DFCNTRL { address 0x093 access_mode RW - bit PRELOADEN 0x80 /* aic7890 only */ - bit WIDEODD 0x40 - bit SCSIEN 0x20 - bit SDMAEN 0x10 - bit SDMAENACK 0x10 - bit HDMAEN 0x08 - bit HDMAENACK 0x08 - bit DIRECTION 0x04 - bit FIFOFLUSH 0x02 - bit FIFORESET 0x01 + field PRELOADEN 0x80 /* aic7890 only */ + field WIDEODD 0x40 + field SCSIEN 0x20 + field SDMAEN 0x10 + field SDMAENACK 0x10 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 + field FIFOFLUSH 0x02 + field FIFORESET 0x01 } register DFSTATUS { address 0x094 access_mode RO - bit PRELOAD_AVAIL 0x80 - bit DFCACHETH 0x40 - bit FIFOQWDEMP 0x20 - bit MREQPEND 0x10 - bit HDONE 0x08 - bit DFTHRESH 0x04 - bit FIFOFULL 0x02 - bit FIFOEMP 0x01 + field PRELOAD_AVAIL 0x80 + field DFCACHETH 0x40 + field FIFOQWDEMP 0x20 + field MREQPEND 0x10 + field HDONE 0x08 + field DFTHRESH 0x04 + field FIFOFULL 0x02 + field FIFOEMP 0x01 } register DFWADDR { @@ -932,7 +943,7 @@ register SCBCNT { address 0x09a access_mode RW - bit SCBAUTO 0x80 + field SCBAUTO 0x80 mask SCBCNT_MASK 0x1f } @@ -966,12 +977,12 @@ register CRCCONTROL1 { address 0x09d access_mode RW - bit CRCONSEEN 0x80 - bit CRCVALCHKEN 0x40 - bit CRCENDCHKEN 0x20 - bit CRCREQCHKEN 0x10 - bit TARGCRCENDEN 0x08 - bit TARGCRCCNTEN 0x04 + field CRCONSEEN 0x80 + field CRCVALCHKEN 0x40 + field CRCENDCHKEN 0x20 + field CRCREQCHKEN 0x10 + field TARGCRCENDEN 0x08 + field TARGCRCCNTEN 0x04 } @@ -987,12 +998,12 @@ register SCSIPHASE { address 0x09e access_mode RO - bit STATUS_PHASE 0x20 - bit COMMAND_PHASE 0x10 - bit MSG_IN_PHASE 0x08 - bit MSG_OUT_PHASE 0x04 - bit DATA_IN_PHASE 0x02 - bit DATA_OUT_PHASE 0x01 + field STATUS_PHASE 0x20 + field COMMAND_PHASE 0x10 + field MSG_IN_PHASE 0x08 + field MSG_OUT_PHASE 0x04 + field DATA_IN_PHASE 0x02 + field DATA_OUT_PHASE 0x01 mask DATA_PHASE_MASK 0x03 } @@ -1002,7 +1013,7 @@ register SFUNCT { address 0x09f access_mode RW - bit ALT_MODE 0x80 + field ALT_MODE 0x80 } /* @@ -1041,28 +1052,29 @@ * the data address. */ size 4 - bit SG_LAST_SEG 0x80 /* In the fourth byte */ + field SG_LAST_SEG 0x80 /* In the fourth byte */ mask SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */ } SCB_SGPTR { size 4 - bit SG_RESID_VALID 0x04 /* In the first byte */ - bit SG_FULL_RESID 0x02 /* In the first byte */ - bit SG_LIST_NULL 0x01 /* In the first byte */ + field SG_RESID_VALID 0x04 /* In the first byte */ + field SG_FULL_RESID 0x02 /* In the first byte */ + field SG_LIST_NULL 0x01 /* In the first byte */ } SCB_CONTROL { size 1 - bit TARGET_SCB 0x80 - bit DISCENB 0x40 - bit TAG_ENB 0x20 - bit MK_MESSAGE 0x10 - bit ULTRAENB 0x08 - bit DISCONNECTED 0x04 + field TARGET_SCB 0x80 + field STATUS_RCVD 0x80 + field DISCENB 0x40 + field TAG_ENB 0x20 + field MK_MESSAGE 0x10 + field ULTRAENB 0x08 + field DISCONNECTED 0x04 mask SCB_TAG_TYPE 0x03 } SCB_SCSIID { size 1 - bit TWIN_CHNLB 0x80 + field TWIN_CHNLB 0x80 mask TWIN_TID 0x70 mask TID 0xf0 mask OID 0x0f @@ -1105,18 +1117,18 @@ register SEECTL_2840 { address 0x0c0 access_mode RW - bit CS_2840 0x04 - bit CK_2840 0x02 - bit DO_2840 0x01 + field CS_2840 0x04 + field CK_2840 0x02 + field DO_2840 0x01 } register STATUS_2840 { address 0x0c1 access_mode RW - bit EEPROM_TF 0x80 + field EEPROM_TF 0x80 mask BIOS_SEL 0x60 mask ADSEL 0x1e - bit DI_2840 0x01 + field DI_2840 0x01 } /* --------------------- AIC-7870-only definitions -------------------- */ @@ -1140,10 +1152,10 @@ register CCSGCTL { address 0x0EB - bit CCSGDONE 0x80 - bit CCSGEN 0x08 - bit SG_FETCH_NEEDED 0x02 /* Bit used for software state */ - bit CCSGRESET 0x01 + field CCSGDONE 0x80 + field CCSGEN 0x08 + field SG_FETCH_NEEDED 0x02 /* Bit used for software state */ + field CCSGRESET 0x01 } register CCSCBCNT { @@ -1152,12 +1164,12 @@ register CCSCBCTL { address 0x0EE - bit CCSCBDONE 0x80 - bit ARRDONE 0x40 /* SCB Array prefetch done */ - bit CCARREN 0x10 - bit CCSCBEN 0x08 - bit CCSCBDIR 0x04 - bit CCSCBRESET 0x01 + field CCSCBDONE 0x80 + field ARRDONE 0x40 /* SCB Array prefetch done */ + field CCARREN 0x10 + field CCSCBEN 0x08 + field CCSCBDIR 0x04 + field CCSCBRESET 0x01 } register CCSCBADDR { @@ -1194,9 +1206,9 @@ register QOFF_CTLSTA { address 0x0FA - bit SCB_AVAIL 0x40 - bit SNSCB_ROLLOVER 0x20 - bit SDSCB_ROLLOVER 0x10 + field SCB_AVAIL 0x40 + field SNSCB_ROLLOVER 0x20 + field SDSCB_ROLLOVER 0x10 mask SCB_QSIZE 0x07 mask SCB_QSIZE_256 0x06 } @@ -1227,18 +1239,18 @@ access_mode WO address 0x0fc mask SG_ADDR_MASK 0xf8 - bit ODD_SEG 0x04 - bit LAST_SEG 0x02 - bit LAST_SEG_DONE 0x01 + field ODD_SEG 0x04 + field LAST_SEG 0x02 + field LAST_SEG_DONE 0x01 } register SG_CACHE_SHADOW { access_mode RO address 0x0fc mask SG_ADDR_MASK 0xf8 - bit ODD_SEG 0x04 - bit LAST_SEG 0x02 - bit LAST_SEG_DONE 0x01 + field ODD_SEG 0x04 + field LAST_SEG 0x02 + field LAST_SEG_DONE 0x01 } /* ---------------------- Scratch RAM Offsets ------------------------- */ /* These offsets are either to values that are initialized by the board's @@ -1295,6 +1307,7 @@ */ MWI_RESIDUAL { size 1 + alias TARG_IMMEDIATE_SCB } /* * SCBID of the next SCB to be started by the controller. @@ -1312,28 +1325,29 @@ /* Parameters for DMA Logic */ DMAPARAMS { size 1 - bit PRELOADEN 0x80 - bit WIDEODD 0x40 - bit SCSIEN 0x20 - bit SDMAEN 0x10 - bit SDMAENACK 0x10 - bit HDMAEN 0x08 - bit HDMAENACK 0x08 - bit DIRECTION 0x04 /* Set indicates PCI->SCSI */ - bit FIFOFLUSH 0x02 - bit FIFORESET 0x01 + field PRELOADEN 0x80 + field WIDEODD 0x40 + field SCSIEN 0x20 + field SDMAEN 0x10 + field SDMAENACK 0x10 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 /* Set indicates PCI->SCSI */ + field FIFOFLUSH 0x02 + field FIFORESET 0x01 } SEQ_FLAGS { size 1 - bit IDENTIFY_SEEN 0x80 - bit TARGET_CMD_IS_TAGGED 0x40 - bit DPHASE 0x20 + field NOT_IDENTIFIED 0x80 + field NO_CDB_SENT 0x40 + field TARGET_CMD_IS_TAGGED 0x40 + field DPHASE 0x20 /* Target flags */ - bit TARG_CMD_PENDING 0x10 - bit CMDPHASE_PENDING 0x08 - bit DPHASE_PENDING 0x04 - bit SPHASE_PENDING 0x02 - bit NO_DISCONNECT 0x01 + field TARG_CMD_PENDING 0x10 + field CMDPHASE_PENDING 0x08 + field DPHASE_PENDING 0x04 + field SPHASE_PENDING 0x02 + field NO_DISCONNECT 0x01 } /* * Temporary storage for the @@ -1351,9 +1365,9 @@ */ LASTPHASE { size 1 - bit CDI 0x80 - bit IOI 0x40 - bit MSGI 0x20 + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 mask PHASE_MASK CDI|IOI|MSGI mask P_DATAOUT 0x00 mask P_DATAIN IOI @@ -1457,12 +1471,12 @@ */ SCSISEQ_TEMPLATE { size 1 - bit ENSELO 0x40 - bit ENSELI 0x20 - bit ENRSELI 0x10 - bit ENAUTOATNO 0x08 - bit ENAUTOATNI 0x04 - bit ENAUTOATNP 0x02 + field ENSELO 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field ENAUTOATNO 0x08 + field ENAUTOATNI 0x04 + field ENAUTOATNP 0x02 } /* @@ -1488,14 +1502,14 @@ */ HA_274_BIOSGLOBAL { size 1 - bit HA_274_EXTENDED_TRANS 0x01 + field HA_274_EXTENDED_TRANS 0x01 alias INITIATOR_TAG } SEQ_FLAGS2 { size 1 - bit SCB_DMA 0x01 - bit TARGET_MSG_PENDING 0x02 + field SCB_DMA 0x01 + field TARGET_MSG_PENDING 0x02 } } @@ -1513,16 +1527,16 @@ */ SCSICONF { size 1 - bit TERM_ENB 0x80 - bit RESET_SCSI 0x40 - bit ENSPCHK 0x20 + field TERM_ENB 0x80 + field RESET_SCSI 0x40 + field ENSPCHK 0x20 mask HSCSIID 0x07 /* our SCSI ID */ mask HWSCSIID 0x0f /* our SCSI ID if Wide Bus */ } INTDEF { address 0x05c size 1 - bit EDGE_TRIG 0x80 + field EDGE_TRIG 0x80 mask VECTOR 0x0f } HOSTCONF { @@ -1534,7 +1548,7 @@ size 1 mask BIOSMODE 0x30 mask BIOSDISABLED 0x30 - bit CHANNEL_B_PRIMARY 0x08 + field CHANNEL_B_PRIMARY 0x08 } } @@ -1566,6 +1580,7 @@ const MAX_OFFSET_8BIT 0x0f const MAX_OFFSET_16BIT 0x08 const MAX_OFFSET_ULTRA2 0x7f +const MAX_OFFSET 0xff const HOST_MSG 0xff /* Target mode command processing constants */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_reg.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_reg.h --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_reg.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_reg.h 2003-01-22 22:10:29.000000000 +0000 @@ -2,9 +2,1073 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $ - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ */ +typedef int (ahc_reg_print_t)(u_int, u_int *, u_int); +typedef struct ahc_reg_parse_entry { + char *name; + uint8_t value; + uint8_t mask; +} ahc_reg_parse_entry_t; + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiseq_print; +#else +#define ahc_scsiseq_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISEQ", 0x00, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sxfrctl0_print; +#else +#define ahc_sxfrctl0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SXFRCTL0", 0x01, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sxfrctl1_print; +#else +#define ahc_sxfrctl1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SXFRCTL1", 0x02, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsisigo_print; +#else +#define ahc_scsisigo_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISIGO", 0x03, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsisigi_print; +#else +#define ahc_scsisigi_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISIGI", 0x03, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsirate_print; +#else +#define ahc_scsirate_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIRATE", 0x04, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiid_print; +#else +#define ahc_scsiid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIID", 0x05, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsidatl_print; +#else +#define ahc_scsidatl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIDATL", 0x06, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsidath_print; +#else +#define ahc_scsidath_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIDATH", 0x07, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_stcnt_print; +#else +#define ahc_stcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "STCNT", 0x08, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_optionmode_print; +#else +#define ahc_optionmode_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "OPTIONMODE", 0x08, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_targcrccnt_print; +#else +#define ahc_targcrccnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TARGCRCCNT", 0x0a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_clrsint0_print; +#else +#define ahc_clrsint0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CLRSINT0", 0x0b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat0_print; +#else +#define ahc_sstat0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT0", 0x0b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_clrsint1_print; +#else +#define ahc_clrsint1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CLRSINT1", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat1_print; +#else +#define ahc_sstat1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT1", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat2_print; +#else +#define ahc_sstat2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT2", 0x0d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat3_print; +#else +#define ahc_sstat3_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT3", 0x0e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiid_ultra2_print; +#else +#define ahc_scsiid_ultra2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIID_ULTRA2", 0x0f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_simode0_print; +#else +#define ahc_simode0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SIMODE0", 0x10, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_simode1_print; +#else +#define ahc_simode1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SIMODE1", 0x11, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsibusl_print; +#else +#define ahc_scsibusl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIBUSL", 0x12, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsibush_print; +#else +#define ahc_scsibush_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIBUSH", 0x13, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sxfrctl2_print; +#else +#define ahc_sxfrctl2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SXFRCTL2", 0x13, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_shaddr_print; +#else +#define ahc_shaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SHADDR", 0x14, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seltimer_print; +#else +#define ahc_seltimer_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SELTIMER", 0x18, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_selid_print; +#else +#define ahc_selid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SELID", 0x19, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scamctl_print; +#else +#define ahc_scamctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCAMCTL", 0x1a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_targid_print; +#else +#define ahc_targid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TARGID", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_spiocap_print; +#else +#define ahc_spiocap_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SPIOCAP", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_brdctl_print; +#else +#define ahc_brdctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BRDCTL", 0x1d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seectl_print; +#else +#define ahc_seectl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEECTL", 0x1e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sblkctl_print; +#else +#define ahc_sblkctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SBLKCTL", 0x1f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_busy_targets_print; +#else +#define ahc_busy_targets_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BUSY_TARGETS", 0x20, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ultra_enb_print; +#else +#define ahc_ultra_enb_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ULTRA_ENB", 0x30, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_disc_dsb_print; +#else +#define ahc_disc_dsb_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DISC_DSB", 0x32, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_cmdsize_table_tail_print; +#else +#define ahc_cmdsize_table_tail_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL", 0x34, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_mwi_residual_print; +#else +#define ahc_mwi_residual_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "MWI_RESIDUAL", 0x38, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_next_queued_scb_print; +#else +#define ahc_next_queued_scb_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB", 0x39, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_msg_out_print; +#else +#define ahc_msg_out_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "MSG_OUT", 0x3a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dmaparams_print; +#else +#define ahc_dmaparams_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DMAPARAMS", 0x3b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seq_flags_print; +#else +#define ahc_seq_flags_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQ_FLAGS", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_saved_scsiid_print; +#else +#define ahc_saved_scsiid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SAVED_SCSIID", 0x3d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_saved_lun_print; +#else +#define ahc_saved_lun_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SAVED_LUN", 0x3e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_lastphase_print; +#else +#define ahc_lastphase_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "LASTPHASE", 0x3f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_waiting_scbh_print; +#else +#define ahc_waiting_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "WAITING_SCBH", 0x40, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_disconnected_scbh_print; +#else +#define ahc_disconnected_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DISCONNECTED_SCBH", 0x41, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_free_scbh_print; +#else +#define ahc_free_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "FREE_SCBH", 0x42, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_complete_scbh_print; +#else +#define ahc_complete_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "COMPLETE_SCBH", 0x43, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hscb_addr_print; +#else +#define ahc_hscb_addr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HSCB_ADDR", 0x44, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_shared_data_addr_print; +#else +#define ahc_shared_data_addr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x48, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_kernel_qinpos_print; +#else +#define ahc_kernel_qinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "KERNEL_QINPOS", 0x4c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qinpos_print; +#else +#define ahc_qinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QINPOS", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoutpos_print; +#else +#define ahc_qoutpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOUTPOS", 0x4e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_kernel_tqinpos_print; +#else +#define ahc_kernel_tqinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "KERNEL_TQINPOS", 0x4f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_tqinpos_print; +#else +#define ahc_tqinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TQINPOS", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_arg_1_print; +#else +#define ahc_arg_1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ARG_1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_arg_2_print; +#else +#define ahc_arg_2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ARG_2", 0x52, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_last_msg_print; +#else +#define ahc_last_msg_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "LAST_MSG", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiseq_template_print; +#else +#define ahc_scsiseq_template_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_data_count_odd_print; +#else +#define ahc_data_count_odd_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DATA_COUNT_ODD", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ha_274_biosglobal_print; +#else +#define ahc_ha_274_biosglobal_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HA_274_BIOSGLOBAL", 0x56, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seq_flags2_print; +#else +#define ahc_seq_flags2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQ_FLAGS2", 0x57, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiconf_print; +#else +#define ahc_scsiconf_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSICONF", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_intdef_print; +#else +#define ahc_intdef_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "INTDEF", 0x5c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hostconf_print; +#else +#define ahc_hostconf_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HOSTCONF", 0x5d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ha_274_biosctrl_print; +#else +#define ahc_ha_274_biosctrl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HA_274_BIOSCTRL", 0x5f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqctl_print; +#else +#define ahc_seqctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQCTL", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqram_print; +#else +#define ahc_seqram_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQRAM", 0x61, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqaddr0_print; +#else +#define ahc_seqaddr0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQADDR0", 0x62, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqaddr1_print; +#else +#define ahc_seqaddr1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQADDR1", 0x63, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_accum_print; +#else +#define ahc_accum_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ACCUM", 0x64, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sindex_print; +#else +#define ahc_sindex_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SINDEX", 0x65, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dindex_print; +#else +#define ahc_dindex_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DINDEX", 0x66, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_allones_print; +#else +#define ahc_allones_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ALLONES", 0x69, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_allzeros_print; +#else +#define ahc_allzeros_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ALLZEROS", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_none_print; +#else +#define ahc_none_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "NONE", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_flags_print; +#else +#define ahc_flags_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "FLAGS", 0x6b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sindir_print; +#else +#define ahc_sindir_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SINDIR", 0x6c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dindir_print; +#else +#define ahc_dindir_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DINDIR", 0x6d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_function1_print; +#else +#define ahc_function1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "FUNCTION1", 0x6e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_stack_print; +#else +#define ahc_stack_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "STACK", 0x6f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_targ_offset_print; +#else +#define ahc_targ_offset_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TARG_OFFSET", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sram_base_print; +#else +#define ahc_sram_base_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SRAM_BASE", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_bctl_print; +#else +#define ahc_bctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BCTL", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dscommand0_print; +#else +#define ahc_dscommand0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DSCOMMAND0", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_bustime_print; +#else +#define ahc_bustime_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BUSTIME", 0x85, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dscommand1_print; +#else +#define ahc_dscommand1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DSCOMMAND1", 0x85, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_busspd_print; +#else +#define ahc_busspd_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BUSSPD", 0x86, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hs_mailbox_print; +#else +#define ahc_hs_mailbox_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HS_MAILBOX", 0x86, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dspcistatus_print; +#else +#define ahc_dspcistatus_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DSPCISTATUS", 0x86, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hcntrl_print; +#else +#define ahc_hcntrl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HCNTRL", 0x87, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_haddr_print; +#else +#define ahc_haddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HADDR", 0x88, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hcnt_print; +#else +#define ahc_hcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HCNT", 0x8c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scbptr_print; +#else +#define ahc_scbptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCBPTR", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_intstat_print; +#else +#define ahc_intstat_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "INTSTAT", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_clrint_print; +#else +#define ahc_clrint_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CLRINT", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_error_print; +#else +#define ahc_error_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ERROR", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfcntrl_print; +#else +#define ahc_dfcntrl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFCNTRL", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfstatus_print; +#else +#define ahc_dfstatus_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFSTATUS", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfwaddr_print; +#else +#define ahc_dfwaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFWADDR", 0x95, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfraddr_print; +#else +#define ahc_dfraddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFRADDR", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfdat_print; +#else +#define ahc_dfdat_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFDAT", 0x99, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scbcnt_print; +#else +#define ahc_scbcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCBCNT", 0x9a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qinfifo_print; +#else +#define ahc_qinfifo_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QINFIFO", 0x9b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qincnt_print; +#else +#define ahc_qincnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QINCNT", 0x9c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoutfifo_print; +#else +#define ahc_qoutfifo_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOUTFIFO", 0x9d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_crccontrol1_print; +#else +#define ahc_crccontrol1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CRCCONTROL1", 0x9d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoutcnt_print; +#else +#define ahc_qoutcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOUTCNT", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiphase_print; +#else +#define ahc_scsiphase_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIPHASE", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sfunct_print; +#else +#define ahc_sfunct_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_base_print; +#else +#define ahc_scb_base_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_BASE", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_cdb_ptr_print; +#else +#define ahc_scb_cdb_ptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_CDB_PTR", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_residual_sgptr_print; +#else +#define ahc_scb_residual_sgptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0xa4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsi_status_print; +#else +#define ahc_scb_scsi_status_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSI_STATUS", 0xa8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_target_phases_print; +#else +#define ahc_scb_target_phases_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TARGET_PHASES", 0xa9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_target_data_dir_print; +#else +#define ahc_scb_target_data_dir_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0xaa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_target_itag_print; +#else +#define ahc_scb_target_itag_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TARGET_ITAG", 0xab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_dataptr_print; +#else +#define ahc_scb_dataptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_DATAPTR", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_datacnt_print; +#else +#define ahc_scb_datacnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_DATACNT", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_sgptr_print; +#else +#define ahc_scb_sgptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SGPTR", 0xb4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_control_print; +#else +#define ahc_scb_control_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_CONTROL", 0xb8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsiid_print; +#else +#define ahc_scb_scsiid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSIID", 0xb9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_lun_print; +#else +#define ahc_scb_lun_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_LUN", 0xba, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_tag_print; +#else +#define ahc_scb_tag_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TAG", 0xbb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_cdb_len_print; +#else +#define ahc_scb_cdb_len_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_CDB_LEN", 0xbc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsirate_print; +#else +#define ahc_scb_scsirate_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSIRATE", 0xbd, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsioffset_print; +#else +#define ahc_scb_scsioffset_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSIOFFSET", 0xbe, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_next_print; +#else +#define ahc_scb_next_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_NEXT", 0xbf, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_64_spare_print; +#else +#define ahc_scb_64_spare_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_64_SPARE", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seectl_2840_print; +#else +#define ahc_seectl_2840_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEECTL_2840", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_status_2840_print; +#else +#define ahc_status_2840_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "STATUS_2840", 0xc1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_64_btt_print; +#else +#define ahc_scb_64_btt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_64_BTT", 0xd0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_cchaddr_print; +#else +#define ahc_cchaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCHADDR", 0xe0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_cchcnt_print; +#else +#define ahc_cchcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCHCNT", 0xe8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccsgram_print; +#else +#define ahc_ccsgram_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSGRAM", 0xe9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccsgaddr_print; +#else +#define ahc_ccsgaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSGADDR", 0xea, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccsgctl_print; +#else +#define ahc_ccsgctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSGCTL", 0xeb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbram_print; +#else +#define ahc_ccscbram_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBRAM", 0xec, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbaddr_print; +#else +#define ahc_ccscbaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBADDR", 0xed, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbctl_print; +#else +#define ahc_ccscbctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBCTL", 0xee, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbcnt_print; +#else +#define ahc_ccscbcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBCNT", 0xef, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scbbaddr_print; +#else +#define ahc_scbbaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCBBADDR", 0xf0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbptr_print; +#else +#define ahc_ccscbptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBPTR", 0xf1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hnscb_qoff_print; +#else +#define ahc_hnscb_qoff_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HNSCB_QOFF", 0xf4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_snscb_qoff_print; +#else +#define ahc_snscb_qoff_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SNSCB_QOFF", 0xf6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sdscb_qoff_print; +#else +#define ahc_sdscb_qoff_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SDSCB_QOFF", 0xf8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoff_ctlsta_print; +#else +#define ahc_qoff_ctlsta_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOFF_CTLSTA", 0xfa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dff_thrsh_print; +#else +#define ahc_dff_thrsh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFF_THRSH", 0xfb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sg_cache_shadow_print; +#else +#define ahc_sg_cache_shadow_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SG_CACHE_SHADOW", 0xfc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sg_cache_pre_print; +#else +#define ahc_sg_cache_pre_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SG_CACHE_PRE", 0xfc, regvalue, cur_col, wrap) +#endif + #define SCSISEQ 0x00 #define TEMODE 0x80 @@ -20,9 +1084,9 @@ #define CLRCHN 0x02 #define SXFRCTL1 0x02 +#define STIMESEL 0x18 #define BITBUCKET 0x80 #define SWRAPEN 0x40 -#define STIMESEL 0x18 #define ENSTIMER 0x04 #define ACTNEGEN 0x02 #define STPWEN 0x01 @@ -47,12 +1111,12 @@ #define ACKI 0x01 #define SCSIRATE 0x04 -#define WIDEXFER 0x80 #define SXFR 0x70 -#define ENABLE_CRC 0x40 -#define SINGLE_EDGE 0x10 #define SOFS 0x0f #define SXFR_ULTRA2 0x0f +#define WIDEXFER 0x80 +#define ENABLE_CRC 0x40 +#define SINGLE_EDGE 0x10 #define SCSIID 0x05 #define SCSIOFFSET 0x05 @@ -65,13 +1129,13 @@ #define STCNT 0x08 #define OPTIONMODE 0x08 +#define OPTIONMODE_DEFAULTS 0x03 #define AUTORATEEN 0x80 #define AUTOACKEN 0x40 #define ATNMGMNTEN 0x20 #define BUSFREEREV 0x10 #define EXPPHASEDIS 0x08 #define SCSIDATL_IMGEN 0x04 -#define OPTIONMODE_DEFAULTS 0x03 #define AUTO_MSGOUT_DE 0x02 #define DIS_MSGIN_DUALEDGE 0x01 @@ -116,9 +1180,9 @@ #define REQINIT 0x01 #define SSTAT2 0x0d +#define SFCNT 0x1f #define OVERRUN 0x80 #define SHVALID 0x40 -#define SFCNT 0x1f #define EXP_ACTIVE 0x10 #define CRCVALERR 0x08 #define CRCENDERR 0x04 @@ -156,6 +1220,11 @@ #define SCSIBUSH 0x13 +#define SXFRCTL2 0x13 +#define ASYNC_SETUP 0x07 +#define AUTORSTDIS 0x10 +#define CMDDMAEN 0x08 + #define SHADDR 0x14 #define SELTIMER 0x18 @@ -172,11 +1241,11 @@ #define ONEBIT 0x08 #define SCAMCTL 0x1a +#define SCAMLVL 0x03 #define ENSCAMSELO 0x80 #define CLRSCAMSELID 0x40 #define ALTSTIM 0x20 #define DFLTTID 0x10 -#define SCAMLVL 0x03 #define TARGID 0x1b @@ -236,6 +1305,7 @@ #define CMDSIZE_TABLE_TAIL 0x34 #define MWI_RESIDUAL 0x38 +#define TARG_IMMEDIATE_SCB 0x38 #define NEXT_QUEUED_SCB 0x39 @@ -254,7 +1324,8 @@ #define FIFORESET 0x01 #define SEQ_FLAGS 0x3c -#define IDENTIFY_SEEN 0x80 +#define NOT_IDENTIFIED 0x80 +#define NO_CDB_SENT 0x40 #define TARGET_CMD_IS_TAGGED 0x40 #define DPHASE 0x20 #define TARG_CMD_PENDING 0x10 @@ -273,12 +1344,12 @@ #define P_STATUS 0xc0 #define P_MESGOUT 0xa0 #define P_COMMAND 0x80 -#define CDI 0x80 #define P_DATAIN 0x40 -#define IOI 0x40 -#define MSGI 0x20 #define P_BUSFREE 0x01 #define P_DATAOUT 0x00 +#define CDI 0x80 +#define IOI 0x40 +#define MSGI 0x20 #define WAITING_SCBH 0x40 @@ -336,15 +1407,15 @@ #define SCB_DMA 0x01 #define SCSICONF 0x5a +#define HWSCSIID 0x0f +#define HSCSIID 0x07 #define TERM_ENB 0x80 #define RESET_SCSI 0x40 #define ENSPCHK 0x20 -#define HWSCSIID 0x0f -#define HSCSIID 0x07 #define INTDEF 0x5c -#define EDGE_TRIG 0x80 #define VECTOR 0x0f +#define EDGE_TRIG 0x80 #define HOSTCONF 0x5d @@ -464,13 +1535,13 @@ #define PDATA_REINIT 0x51 #define IGN_WIDE_RES 0x41 #define NO_MATCH 0x31 -#define NO_IDENT 0x21 +#define PROTO_VIOLATION 0x21 #define SEND_REJECT 0x11 #define INT_PEND 0x0f +#define BAD_PHASE 0x01 #define BRKADRINT 0x08 #define SCSIINT 0x04 #define CMDCMPLT 0x02 -#define BAD_PHASE 0x01 #define SEQINT 0x01 #define CLRINT 0x92 @@ -509,8 +1580,8 @@ #define DFDAT 0x99 #define SCBCNT 0x9a -#define SCBAUTO 0x80 #define SCBCNT_MASK 0x1f +#define SCBAUTO 0x80 #define QINFIFO 0x9b @@ -529,11 +1600,11 @@ #define QOUTCNT 0x9e #define SCSIPHASE 0x9e +#define DATA_PHASE_MASK 0x03 #define STATUS_PHASE 0x20 #define COMMAND_PHASE 0x10 #define MSG_IN_PHASE 0x08 #define MSG_OUT_PHASE 0x04 -#define DATA_PHASE_MASK 0x03 #define DATA_IN_PHASE 0x02 #define DATA_OUT_PHASE 0x01 @@ -559,8 +1630,8 @@ #define SCB_DATAPTR 0xac #define SCB_DATACNT 0xb0 -#define SG_LAST_SEG 0x80 #define SG_HIGH_ADDR_BITS 0x7f +#define SG_LAST_SEG 0x80 #define SCB_SGPTR 0xb4 #define SG_RESID_VALID 0x04 @@ -568,19 +1639,20 @@ #define SG_LIST_NULL 0x01 #define SCB_CONTROL 0xb8 +#define SCB_TAG_TYPE 0x03 +#define STATUS_RCVD 0x80 #define TARGET_SCB 0x80 #define DISCENB 0x40 #define TAG_ENB 0x20 #define MK_MESSAGE 0x10 #define ULTRAENB 0x08 #define DISCONNECTED 0x04 -#define SCB_TAG_TYPE 0x03 #define SCB_SCSIID 0xb9 #define TID 0xf0 -#define TWIN_CHNLB 0x80 #define TWIN_TID 0x70 #define OID 0x0f +#define TWIN_CHNLB 0x80 #define SCB_LUN 0xba #define LID 0xff @@ -603,9 +1675,9 @@ #define DO_2840 0x01 #define STATUS_2840 0xc1 -#define EEPROM_TF 0x80 #define BIOS_SEL 0x60 #define ADSEL 0x1e +#define EEPROM_TF 0x80 #define DI_2840 0x01 #define SCB_64_BTT 0xd0 @@ -649,11 +1721,11 @@ #define SDSCB_QOFF 0xf8 #define QOFF_CTLSTA 0xfa +#define SCB_QSIZE 0x07 +#define SCB_QSIZE_256 0x06 #define SCB_AVAIL 0x40 #define SNSCB_ROLLOVER 0x20 #define SDSCB_ROLLOVER 0x10 -#define SCB_QSIZE 0x07 -#define SCB_QSIZE_256 0x06 #define DFF_THRSH 0xfb #define WR_DFTHRSH 0x70 @@ -704,8 +1776,10 @@ #define SEQ_MAILBOX_SHIFT 0x00 #define TARGET_DATA_IN 0x01 #define HOST_MSG 0xff +#define MAX_OFFSET 0xff #define BUS_16_BIT 0x01 #define SCB_UPLOAD_SIZE 0x20 +#define STACK_SIZE 0x04 /* Downloaded Constant Definitions */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_reg_print.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_reg_print.c --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_reg_print.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_reg_print.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,1689 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ + */ + +#include "aic7xxx_osm.h" + +static ahc_reg_parse_entry_t SCSISEQ_parse_table[] = { + { "SCSIRSTO", 0x01, 0x01 }, + { "ENAUTOATNP", 0x02, 0x02 }, + { "ENAUTOATNI", 0x04, 0x04 }, + { "ENAUTOATNO", 0x08, 0x08 }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "ENSELO", 0x40, 0x40 }, + { "TEMODE", 0x80, 0x80 } +}; + +int +ahc_scsiseq_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISEQ_parse_table, 8, "SCSISEQ", + 0x00, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SXFRCTL0_parse_table[] = { + { "CLRCHN", 0x02, 0x02 }, + { "SCAMEN", 0x04, 0x04 }, + { "SPIOEN", 0x08, 0x08 }, + { "CLRSTCNT", 0x10, 0x10 }, + { "FAST20", 0x20, 0x20 }, + { "DFPEXP", 0x40, 0x40 }, + { "DFON", 0x80, 0x80 } +}; + +int +ahc_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SXFRCTL0_parse_table, 7, "SXFRCTL0", + 0x01, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SXFRCTL1_parse_table[] = { + { "STPWEN", 0x01, 0x01 }, + { "ACTNEGEN", 0x02, 0x02 }, + { "ENSTIMER", 0x04, 0x04 }, + { "ENSPCHK", 0x20, 0x20 }, + { "SWRAPEN", 0x40, 0x40 }, + { "BITBUCKET", 0x80, 0x80 }, + { "STIMESEL", 0x18, 0x18 } +}; + +int +ahc_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1", + 0x02, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSISIGO_parse_table[] = { + { "ACKO", 0x01, 0x01 }, + { "REQO", 0x02, 0x02 }, + { "BSYO", 0x04, 0x04 }, + { "SELO", 0x08, 0x08 }, + { "ATNO", 0x10, 0x10 }, + { "MSGO", 0x20, 0x20 }, + { "IOO", 0x40, 0x40 }, + { "CDO", 0x80, 0x80 }, + { "P_DATAOUT", 0x00, 0x00 }, + { "P_DATAIN", 0x40, 0x40 }, + { "P_COMMAND", 0x80, 0x80 }, + { "P_MESGOUT", 0xa0, 0xa0 }, + { "P_STATUS", 0xc0, 0xc0 }, + { "PHASE_MASK", 0xe0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 } +}; + +int +ahc_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISIGO_parse_table, 15, "SCSISIGO", + 0x03, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSISIGI_parse_table[] = { + { "ACKI", 0x01, 0x01 }, + { "REQI", 0x02, 0x02 }, + { "BSYI", 0x04, 0x04 }, + { "SELI", 0x08, 0x08 }, + { "ATNI", 0x10, 0x10 }, + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "P_DATAOUT", 0x00, 0x00 }, + { "P_DATAOUT_DT", 0x20, 0x20 }, + { "P_DATAIN", 0x40, 0x40 }, + { "P_DATAIN_DT", 0x60, 0x60 }, + { "P_COMMAND", 0x80, 0x80 }, + { "P_MESGOUT", 0xa0, 0xa0 }, + { "P_STATUS", 0xc0, 0xc0 }, + { "PHASE_MASK", 0xe0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 } +}; + +int +ahc_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISIGI_parse_table, 17, "SCSISIGI", + 0x03, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIRATE_parse_table[] = { + { "SINGLE_EDGE", 0x10, 0x10 }, + { "ENABLE_CRC", 0x40, 0x40 }, + { "WIDEXFER", 0x80, 0x80 }, + { "SXFR_ULTRA2", 0x0f, 0x0f }, + { "SOFS", 0x0f, 0x0f }, + { "SXFR", 0x70, 0x70 } +}; + +int +ahc_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIRATE_parse_table, 6, "SCSIRATE", + 0x04, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIID_parse_table[] = { + { "TWIN_CHNLB", 0x80, 0x80 }, + { "OID", 0x0f, 0x0f }, + { "TWIN_TID", 0x70, 0x70 }, + { "SOFS_ULTRA2", 0x7f, 0x7f }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahc_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIID_parse_table, 5, "SCSIID", + 0x05, regvalue, cur_col, wrap)); +} + +int +ahc_scsidatl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIDATL", + 0x06, regvalue, cur_col, wrap)); +} + +int +ahc_scsidath_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIDATH", + 0x07, regvalue, cur_col, wrap)); +} + +int +ahc_stcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "STCNT", + 0x08, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t OPTIONMODE_parse_table[] = { + { "DIS_MSGIN_DUALEDGE", 0x01, 0x01 }, + { "AUTO_MSGOUT_DE", 0x02, 0x02 }, + { "SCSIDATL_IMGEN", 0x04, 0x04 }, + { "EXPPHASEDIS", 0x08, 0x08 }, + { "BUSFREEREV", 0x10, 0x10 }, + { "ATNMGMNTEN", 0x20, 0x20 }, + { "AUTOACKEN", 0x40, 0x40 }, + { "AUTORATEEN", 0x80, 0x80 }, + { "OPTIONMODE_DEFAULTS",0x03, 0x03 } +}; + +int +ahc_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(OPTIONMODE_parse_table, 9, "OPTIONMODE", + 0x08, regvalue, cur_col, wrap)); +} + +int +ahc_targcrccnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TARGCRCCNT", + 0x0a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CLRSINT0_parse_table[] = { + { "CLRSPIORDY", 0x02, 0x02 }, + { "CLRSWRAP", 0x08, 0x08 }, + { "CLRIOERR", 0x08, 0x08 }, + { "CLRSELINGO", 0x10, 0x10 }, + { "CLRSELDI", 0x20, 0x20 }, + { "CLRSELDO", 0x40, 0x40 } +}; + +int +ahc_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CLRSINT0_parse_table, 6, "CLRSINT0", + 0x0b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT0_parse_table[] = { + { "DMADONE", 0x01, 0x01 }, + { "SPIORDY", 0x02, 0x02 }, + { "SDONE", 0x04, 0x04 }, + { "SWRAP", 0x08, 0x08 }, + { "IOERR", 0x08, 0x08 }, + { "SELINGO", 0x10, 0x10 }, + { "SELDI", 0x20, 0x20 }, + { "SELDO", 0x40, 0x40 }, + { "TARGET", 0x80, 0x80 } +}; + +int +ahc_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT0_parse_table, 9, "SSTAT0", + 0x0b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CLRSINT1_parse_table[] = { + { "CLRREQINIT", 0x01, 0x01 }, + { "CLRPHASECHG", 0x02, 0x02 }, + { "CLRSCSIPERR", 0x04, 0x04 }, + { "CLRBUSFREE", 0x08, 0x08 }, + { "CLRSCSIRSTI", 0x20, 0x20 }, + { "CLRATNO", 0x40, 0x40 }, + { "CLRSELTIMEO", 0x80, 0x80 } +}; + +int +ahc_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CLRSINT1_parse_table, 7, "CLRSINT1", + 0x0c, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT1_parse_table[] = { + { "REQINIT", 0x01, 0x01 }, + { "PHASECHG", 0x02, 0x02 }, + { "SCSIPERR", 0x04, 0x04 }, + { "BUSFREE", 0x08, 0x08 }, + { "PHASEMIS", 0x10, 0x10 }, + { "SCSIRSTI", 0x20, 0x20 }, + { "ATNTARG", 0x40, 0x40 }, + { "SELTO", 0x80, 0x80 } +}; + +int +ahc_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT1_parse_table, 8, "SSTAT1", + 0x0c, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT2_parse_table[] = { + { "DUAL_EDGE_ERR", 0x01, 0x01 }, + { "CRCREQERR", 0x02, 0x02 }, + { "CRCENDERR", 0x04, 0x04 }, + { "CRCVALERR", 0x08, 0x08 }, + { "EXP_ACTIVE", 0x10, 0x10 }, + { "SHVALID", 0x40, 0x40 }, + { "OVERRUN", 0x80, 0x80 }, + { "SFCNT", 0x1f, 0x1f } +}; + +int +ahc_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT2_parse_table, 8, "SSTAT2", + 0x0d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT3_parse_table[] = { + { "OFFCNT", 0x0f, 0x0f }, + { "U2OFFCNT", 0x7f, 0x7f }, + { "SCSICNT", 0xf0, 0xf0 } +}; + +int +ahc_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT3_parse_table, 3, "SSTAT3", + 0x0e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIID_ULTRA2_parse_table[] = { + { "OID", 0x0f, 0x0f }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahc_scsiid_ultra2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIID_ULTRA2_parse_table, 2, "SCSIID_ULTRA2", + 0x0f, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SIMODE0_parse_table[] = { + { "ENDMADONE", 0x01, 0x01 }, + { "ENSPIORDY", 0x02, 0x02 }, + { "ENSDONE", 0x04, 0x04 }, + { "ENSWRAP", 0x08, 0x08 }, + { "ENIOERR", 0x08, 0x08 }, + { "ENSELINGO", 0x10, 0x10 }, + { "ENSELDI", 0x20, 0x20 }, + { "ENSELDO", 0x40, 0x40 } +}; + +int +ahc_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SIMODE0_parse_table, 8, "SIMODE0", + 0x10, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SIMODE1_parse_table[] = { + { "ENREQINIT", 0x01, 0x01 }, + { "ENPHASECHG", 0x02, 0x02 }, + { "ENSCSIPERR", 0x04, 0x04 }, + { "ENBUSFREE", 0x08, 0x08 }, + { "ENPHASEMIS", 0x10, 0x10 }, + { "ENSCSIRST", 0x20, 0x20 }, + { "ENATNTARG", 0x40, 0x40 }, + { "ENSELTIMO", 0x80, 0x80 } +}; + +int +ahc_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SIMODE1_parse_table, 8, "SIMODE1", + 0x11, regvalue, cur_col, wrap)); +} + +int +ahc_scsibusl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIBUSL", + 0x12, regvalue, cur_col, wrap)); +} + +int +ahc_scsibush_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIBUSH", + 0x13, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SXFRCTL2_parse_table[] = { + { "CMDDMAEN", 0x08, 0x08 }, + { "AUTORSTDIS", 0x10, 0x10 }, + { "ASYNC_SETUP", 0x07, 0x07 } +}; + +int +ahc_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2", + 0x13, regvalue, cur_col, wrap)); +} + +int +ahc_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SHADDR", + 0x14, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SELTIMER_parse_table[] = { + { "STAGE1", 0x01, 0x01 }, + { "STAGE2", 0x02, 0x02 }, + { "STAGE3", 0x04, 0x04 }, + { "STAGE4", 0x08, 0x08 }, + { "STAGE5", 0x10, 0x10 }, + { "STAGE6", 0x20, 0x20 } +}; + +int +ahc_seltimer_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SELTIMER_parse_table, 6, "SELTIMER", + 0x18, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SELID_parse_table[] = { + { "ONEBIT", 0x08, 0x08 }, + { "SELID_MASK", 0xf0, 0xf0 } +}; + +int +ahc_selid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SELID_parse_table, 2, "SELID", + 0x19, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCAMCTL_parse_table[] = { + { "DFLTTID", 0x10, 0x10 }, + { "ALTSTIM", 0x20, 0x20 }, + { "CLRSCAMSELID", 0x40, 0x40 }, + { "ENSCAMSELO", 0x80, 0x80 }, + { "SCAMLVL", 0x03, 0x03 } +}; + +int +ahc_scamctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCAMCTL_parse_table, 5, "SCAMCTL", + 0x1a, regvalue, cur_col, wrap)); +} + +int +ahc_targid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TARGID", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SPIOCAP_parse_table[] = { + { "SSPIOCPS", 0x01, 0x01 }, + { "ROM", 0x02, 0x02 }, + { "EEPROM", 0x04, 0x04 }, + { "SEEPROM", 0x08, 0x08 }, + { "EXT_BRDCTL", 0x10, 0x10 }, + { "SOFTCMDEN", 0x20, 0x20 }, + { "SOFT0", 0x40, 0x40 }, + { "SOFT1", 0x80, 0x80 } +}; + +int +ahc_spiocap_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SPIOCAP_parse_table, 8, "SPIOCAP", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BRDCTL_parse_table[] = { + { "BRDCTL0", 0x01, 0x01 }, + { "BRDSTB_ULTRA2", 0x01, 0x01 }, + { "BRDCTL1", 0x02, 0x02 }, + { "BRDRW_ULTRA2", 0x02, 0x02 }, + { "BRDRW", 0x04, 0x04 }, + { "BRDDAT2", 0x04, 0x04 }, + { "BRDCS", 0x08, 0x08 }, + { "BRDDAT3", 0x08, 0x08 }, + { "BRDSTB", 0x10, 0x10 }, + { "BRDDAT4", 0x10, 0x10 }, + { "BRDDAT5", 0x20, 0x20 }, + { "BRDDAT6", 0x40, 0x40 }, + { "BRDDAT7", 0x80, 0x80 } +}; + +int +ahc_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BRDCTL_parse_table, 13, "BRDCTL", + 0x1d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEECTL_parse_table[] = { + { "SEEDI", 0x01, 0x01 }, + { "SEEDO", 0x02, 0x02 }, + { "SEECK", 0x04, 0x04 }, + { "SEECS", 0x08, 0x08 }, + { "SEERDY", 0x10, 0x10 }, + { "SEEMS", 0x20, 0x20 }, + { "EXTARBREQ", 0x40, 0x40 }, + { "EXTARBACK", 0x80, 0x80 } +}; + +int +ahc_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEECTL_parse_table, 8, "SEECTL", + 0x1e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SBLKCTL_parse_table[] = { + { "XCVR", 0x01, 0x01 }, + { "SELWIDE", 0x02, 0x02 }, + { "ENAB20", 0x04, 0x04 }, + { "SELBUSB", 0x08, 0x08 }, + { "ENAB40", 0x08, 0x08 }, + { "AUTOFLUSHDIS", 0x20, 0x20 }, + { "DIAGLEDON", 0x40, 0x40 }, + { "DIAGLEDEN", 0x80, 0x80 } +}; + +int +ahc_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SBLKCTL_parse_table, 8, "SBLKCTL", + 0x1f, regvalue, cur_col, wrap)); +} + +int +ahc_busy_targets_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "BUSY_TARGETS", + 0x20, regvalue, cur_col, wrap)); +} + +int +ahc_ultra_enb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ULTRA_ENB", + 0x30, regvalue, cur_col, wrap)); +} + +int +ahc_disc_dsb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DISC_DSB", + 0x32, regvalue, cur_col, wrap)); +} + +int +ahc_cmdsize_table_tail_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL", + 0x34, regvalue, cur_col, wrap)); +} + +int +ahc_mwi_residual_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "MWI_RESIDUAL", + 0x38, regvalue, cur_col, wrap)); +} + +int +ahc_next_queued_scb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB", + 0x39, regvalue, cur_col, wrap)); +} + +int +ahc_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "MSG_OUT", + 0x3a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DMAPARAMS_parse_table[] = { + { "FIFORESET", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SDMAEN", 0x10, 0x10 }, + { "SDMAENACK", 0x10, 0x10 }, + { "SCSIEN", 0x20, 0x20 }, + { "WIDEODD", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahc_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS", + 0x3b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQ_FLAGS_parse_table[] = { + { "NO_DISCONNECT", 0x01, 0x01 }, + { "SPHASE_PENDING", 0x02, 0x02 }, + { "DPHASE_PENDING", 0x04, 0x04 }, + { "CMDPHASE_PENDING", 0x08, 0x08 }, + { "TARG_CMD_PENDING", 0x10, 0x10 }, + { "DPHASE", 0x20, 0x20 }, + { "NO_CDB_SENT", 0x40, 0x40 }, + { "TARGET_CMD_IS_TAGGED",0x40, 0x40 }, + { "NOT_IDENTIFIED", 0x80, 0x80 } +}; + +int +ahc_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS", + 0x3c, regvalue, cur_col, wrap)); +} + +int +ahc_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SAVED_SCSIID", + 0x3d, regvalue, cur_col, wrap)); +} + +int +ahc_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SAVED_LUN", + 0x3e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t LASTPHASE_parse_table[] = { + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "P_DATAOUT", 0x00, 0x00 }, + { "P_BUSFREE", 0x01, 0x01 }, + { "P_DATAIN", 0x40, 0x40 }, + { "P_COMMAND", 0x80, 0x80 }, + { "P_MESGOUT", 0xa0, 0xa0 }, + { "P_STATUS", 0xc0, 0xc0 }, + { "PHASE_MASK", 0xe0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 } +}; + +int +ahc_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(LASTPHASE_parse_table, 11, "LASTPHASE", + 0x3f, regvalue, cur_col, wrap)); +} + +int +ahc_waiting_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "WAITING_SCBH", + 0x40, regvalue, cur_col, wrap)); +} + +int +ahc_disconnected_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DISCONNECTED_SCBH", + 0x41, regvalue, cur_col, wrap)); +} + +int +ahc_free_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "FREE_SCBH", + 0x42, regvalue, cur_col, wrap)); +} + +int +ahc_complete_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "COMPLETE_SCBH", + 0x43, regvalue, cur_col, wrap)); +} + +int +ahc_hscb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HSCB_ADDR", + 0x44, regvalue, cur_col, wrap)); +} + +int +ahc_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SHARED_DATA_ADDR", + 0x48, regvalue, cur_col, wrap)); +} + +int +ahc_kernel_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "KERNEL_QINPOS", + 0x4c, regvalue, cur_col, wrap)); +} + +int +ahc_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QINPOS", + 0x4d, regvalue, cur_col, wrap)); +} + +int +ahc_qoutpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QOUTPOS", + 0x4e, regvalue, cur_col, wrap)); +} + +int +ahc_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "KERNEL_TQINPOS", + 0x4f, regvalue, cur_col, wrap)); +} + +int +ahc_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TQINPOS", + 0x50, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t ARG_1_parse_table[] = { + { "CONT_TARG_SESSION", 0x02, 0x02 }, + { "CONT_MSG_LOOP", 0x04, 0x04 }, + { "EXIT_MSG_LOOP", 0x08, 0x08 }, + { "MSGOUT_PHASEMIS", 0x10, 0x10 }, + { "SEND_REJ", 0x20, 0x20 }, + { "SEND_SENSE", 0x40, 0x40 }, + { "SEND_MSG", 0x80, 0x80 } +}; + +int +ahc_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(ARG_1_parse_table, 7, "ARG_1", + 0x51, regvalue, cur_col, wrap)); +} + +int +ahc_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ARG_2", + 0x52, regvalue, cur_col, wrap)); +} + +int +ahc_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "LAST_MSG", + 0x53, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = { + { "ENAUTOATNP", 0x02, 0x02 }, + { "ENAUTOATNI", 0x04, 0x04 }, + { "ENAUTOATNO", 0x08, 0x08 }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "ENSELO", 0x40, 0x40 } +}; + +int +ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE", + 0x54, regvalue, cur_col, wrap)); +} + +int +ahc_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DATA_COUNT_ODD", + 0x55, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = { + { "HA_274_EXTENDED_TRANS",0x01, 0x01 } +}; + +int +ahc_ha_274_biosglobal_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HA_274_BIOSGLOBAL_parse_table, 1, "HA_274_BIOSGLOBAL", + 0x56, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { + { "SCB_DMA", 0x01, 0x01 }, + { "TARGET_MSG_PENDING", 0x02, 0x02 } +}; + +int +ahc_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2", + 0x57, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSICONF_parse_table[] = { + { "ENSPCHK", 0x20, 0x20 }, + { "RESET_SCSI", 0x40, 0x40 }, + { "TERM_ENB", 0x80, 0x80 }, + { "HSCSIID", 0x07, 0x07 }, + { "HWSCSIID", 0x0f, 0x0f } +}; + +int +ahc_scsiconf_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSICONF_parse_table, 5, "SCSICONF", + 0x5a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t INTDEF_parse_table[] = { + { "EDGE_TRIG", 0x80, 0x80 }, + { "VECTOR", 0x0f, 0x0f } +}; + +int +ahc_intdef_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(INTDEF_parse_table, 2, "INTDEF", + 0x5c, regvalue, cur_col, wrap)); +} + +int +ahc_hostconf_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HOSTCONF", + 0x5d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HA_274_BIOSCTRL_parse_table[] = { + { "CHANNEL_B_PRIMARY", 0x08, 0x08 }, + { "BIOSMODE", 0x30, 0x30 }, + { "BIOSDISABLED", 0x30, 0x30 } +}; + +int +ahc_ha_274_biosctrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HA_274_BIOSCTRL_parse_table, 3, "HA_274_BIOSCTRL", + 0x5f, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQCTL_parse_table[] = { + { "LOADRAM", 0x01, 0x01 }, + { "SEQRESET", 0x02, 0x02 }, + { "STEP", 0x04, 0x04 }, + { "BRKADRINTEN", 0x08, 0x08 }, + { "FASTMODE", 0x10, 0x10 }, + { "FAILDIS", 0x20, 0x20 }, + { "PAUSEDIS", 0x40, 0x40 }, + { "PERRORDIS", 0x80, 0x80 } +}; + +int +ahc_seqctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQCTL_parse_table, 8, "SEQCTL", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahc_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SEQRAM", + 0x61, regvalue, cur_col, wrap)); +} + +int +ahc_seqaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SEQADDR0", + 0x62, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQADDR1_parse_table[] = { + { "SEQADDR1_MASK", 0x01, 0x01 } +}; + +int +ahc_seqaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQADDR1_parse_table, 1, "SEQADDR1", + 0x63, regvalue, cur_col, wrap)); +} + +int +ahc_accum_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ACCUM", + 0x64, regvalue, cur_col, wrap)); +} + +int +ahc_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SINDEX", + 0x65, regvalue, cur_col, wrap)); +} + +int +ahc_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DINDEX", + 0x66, regvalue, cur_col, wrap)); +} + +int +ahc_allones_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ALLONES", + 0x69, regvalue, cur_col, wrap)); +} + +int +ahc_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ALLZEROS", + 0x6a, regvalue, cur_col, wrap)); +} + +int +ahc_none_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "NONE", + 0x6a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t FLAGS_parse_table[] = { + { "CARRY", 0x01, 0x01 }, + { "ZERO", 0x02, 0x02 } +}; + +int +ahc_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(FLAGS_parse_table, 2, "FLAGS", + 0x6b, regvalue, cur_col, wrap)); +} + +int +ahc_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SINDIR", + 0x6c, regvalue, cur_col, wrap)); +} + +int +ahc_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DINDIR", + 0x6d, regvalue, cur_col, wrap)); +} + +int +ahc_function1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "FUNCTION1", + 0x6e, regvalue, cur_col, wrap)); +} + +int +ahc_stack_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "STACK", + 0x6f, regvalue, cur_col, wrap)); +} + +int +ahc_targ_offset_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TARG_OFFSET", + 0x70, regvalue, cur_col, wrap)); +} + +int +ahc_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SRAM_BASE", + 0x70, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BCTL_parse_table[] = { + { "ENABLE", 0x01, 0x01 }, + { "ACE", 0x08, 0x08 } +}; + +int +ahc_bctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BCTL_parse_table, 2, "BCTL", + 0x84, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DSCOMMAND0_parse_table[] = { + { "CIOPARCKEN", 0x01, 0x01 }, + { "USCBSIZE32", 0x02, 0x02 }, + { "RAMPS", 0x04, 0x04 }, + { "INTSCBRAMSEL", 0x08, 0x08 }, + { "EXTREQLCK", 0x10, 0x10 }, + { "MPARCKEN", 0x20, 0x20 }, + { "DPARCKEN", 0x40, 0x40 }, + { "CACHETHEN", 0x80, 0x80 } +}; + +int +ahc_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DSCOMMAND0_parse_table, 8, "DSCOMMAND0", + 0x84, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BUSTIME_parse_table[] = { + { "BON", 0x0f, 0x0f }, + { "BOFF", 0xf0, 0xf0 } +}; + +int +ahc_bustime_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BUSTIME_parse_table, 2, "BUSTIME", + 0x85, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DSCOMMAND1_parse_table[] = { + { "HADDLDSEL0", 0x01, 0x01 }, + { "HADDLDSEL1", 0x02, 0x02 }, + { "DSLATT", 0xfc, 0xfc } +}; + +int +ahc_dscommand1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DSCOMMAND1_parse_table, 3, "DSCOMMAND1", + 0x85, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BUSSPD_parse_table[] = { + { "STBON", 0x07, 0x07 }, + { "STBOFF", 0x38, 0x38 }, + { "DFTHRSH_75", 0x80, 0x80 }, + { "DFTHRSH", 0xc0, 0xc0 }, + { "DFTHRSH_100", 0xc0, 0xc0 } +}; + +int +ahc_busspd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BUSSPD_parse_table, 5, "BUSSPD", + 0x86, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HS_MAILBOX_parse_table[] = { + { "SEQ_MAILBOX", 0x0f, 0x0f }, + { "HOST_TQINPOS", 0x80, 0x80 }, + { "HOST_MAILBOX", 0xf0, 0xf0 } +}; + +int +ahc_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HS_MAILBOX_parse_table, 3, "HS_MAILBOX", + 0x86, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DSPCISTATUS_parse_table[] = { + { "DFTHRSH_100", 0xc0, 0xc0 } +}; + +int +ahc_dspcistatus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DSPCISTATUS_parse_table, 1, "DSPCISTATUS", + 0x86, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HCNTRL_parse_table[] = { + { "CHIPRST", 0x01, 0x01 }, + { "CHIPRSTACK", 0x01, 0x01 }, + { "INTEN", 0x02, 0x02 }, + { "PAUSE", 0x04, 0x04 }, + { "IRQMS", 0x08, 0x08 }, + { "SWINT", 0x10, 0x10 }, + { "POWRDN", 0x40, 0x40 } +}; + +int +ahc_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HCNTRL_parse_table, 7, "HCNTRL", + 0x87, regvalue, cur_col, wrap)); +} + +int +ahc_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HADDR", + 0x88, regvalue, cur_col, wrap)); +} + +int +ahc_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HCNT", + 0x8c, regvalue, cur_col, wrap)); +} + +int +ahc_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCBPTR", + 0x90, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t INTSTAT_parse_table[] = { + { "SEQINT", 0x01, 0x01 }, + { "CMDCMPLT", 0x02, 0x02 }, + { "SCSIINT", 0x04, 0x04 }, + { "BRKADRINT", 0x08, 0x08 }, + { "BAD_PHASE", 0x01, 0x01 }, + { "INT_PEND", 0x0f, 0x0f }, + { "SEND_REJECT", 0x11, 0x11 }, + { "PROTO_VIOLATION", 0x21, 0x21 }, + { "NO_MATCH", 0x31, 0x31 }, + { "IGN_WIDE_RES", 0x41, 0x41 }, + { "PDATA_REINIT", 0x51, 0x51 }, + { "HOST_MSG_LOOP", 0x61, 0x61 }, + { "BAD_STATUS", 0x71, 0x71 }, + { "PERR_DETECTED", 0x81, 0x81 }, + { "DATA_OVERRUN", 0x91, 0x91 }, + { "MKMSG_FAILED", 0xa1, 0xa1 }, + { "MISSED_BUSFREE", 0xb1, 0xb1 }, + { "SCB_MISMATCH", 0xc1, 0xc1 }, + { "NO_FREE_SCB", 0xd1, 0xd1 }, + { "OUT_OF_RANGE", 0xe1, 0xe1 }, + { "SEQINT_MASK", 0xf1, 0xf1 } +}; + +int +ahc_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(INTSTAT_parse_table, 21, "INTSTAT", + 0x91, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CLRINT_parse_table[] = { + { "CLRSEQINT", 0x01, 0x01 }, + { "CLRCMDINT", 0x02, 0x02 }, + { "CLRSCSIINT", 0x04, 0x04 }, + { "CLRBRKADRINT", 0x08, 0x08 }, + { "CLRPARERR", 0x10, 0x10 } +}; + +int +ahc_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CLRINT_parse_table, 5, "CLRINT", + 0x92, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t ERROR_parse_table[] = { + { "ILLHADDR", 0x01, 0x01 }, + { "ILLSADDR", 0x02, 0x02 }, + { "ILLOPCODE", 0x04, 0x04 }, + { "SQPARERR", 0x08, 0x08 }, + { "DPARERR", 0x10, 0x10 }, + { "MPARERR", 0x20, 0x20 }, + { "PCIERRSTAT", 0x40, 0x40 }, + { "CIOPARERR", 0x80, 0x80 } +}; + +int +ahc_error_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(ERROR_parse_table, 8, "ERROR", + 0x92, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DFCNTRL_parse_table[] = { + { "FIFORESET", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SDMAEN", 0x10, 0x10 }, + { "SDMAENACK", 0x10, 0x10 }, + { "SCSIEN", 0x20, 0x20 }, + { "WIDEODD", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahc_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DFCNTRL_parse_table, 10, "DFCNTRL", + 0x93, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DFSTATUS_parse_table[] = { + { "FIFOEMP", 0x01, 0x01 }, + { "FIFOFULL", 0x02, 0x02 }, + { "DFTHRESH", 0x04, 0x04 }, + { "HDONE", 0x08, 0x08 }, + { "MREQPEND", 0x10, 0x10 }, + { "FIFOQWDEMP", 0x20, 0x20 }, + { "DFCACHETH", 0x40, 0x40 }, + { "PRELOAD_AVAIL", 0x80, 0x80 } +}; + +int +ahc_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DFSTATUS_parse_table, 8, "DFSTATUS", + 0x94, regvalue, cur_col, wrap)); +} + +int +ahc_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DFWADDR", + 0x95, regvalue, cur_col, wrap)); +} + +int +ahc_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DFRADDR", + 0x97, regvalue, cur_col, wrap)); +} + +int +ahc_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DFDAT", + 0x99, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCBCNT_parse_table[] = { + { "SCBAUTO", 0x80, 0x80 }, + { "SCBCNT_MASK", 0x1f, 0x1f } +}; + +int +ahc_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCBCNT_parse_table, 2, "SCBCNT", + 0x9a, regvalue, cur_col, wrap)); +} + +int +ahc_qinfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QINFIFO", + 0x9b, regvalue, cur_col, wrap)); +} + +int +ahc_qincnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QINCNT", + 0x9c, regvalue, cur_col, wrap)); +} + +int +ahc_qoutfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QOUTFIFO", + 0x9d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CRCCONTROL1_parse_table[] = { + { "TARGCRCCNTEN", 0x04, 0x04 }, + { "TARGCRCENDEN", 0x08, 0x08 }, + { "CRCREQCHKEN", 0x10, 0x10 }, + { "CRCENDCHKEN", 0x20, 0x20 }, + { "CRCVALCHKEN", 0x40, 0x40 }, + { "CRCONSEEN", 0x80, 0x80 } +}; + +int +ahc_crccontrol1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CRCCONTROL1_parse_table, 6, "CRCCONTROL1", + 0x9d, regvalue, cur_col, wrap)); +} + +int +ahc_qoutcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QOUTCNT", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIPHASE_parse_table[] = { + { "DATA_OUT_PHASE", 0x01, 0x01 }, + { "DATA_IN_PHASE", 0x02, 0x02 }, + { "MSG_OUT_PHASE", 0x04, 0x04 }, + { "MSG_IN_PHASE", 0x08, 0x08 }, + { "COMMAND_PHASE", 0x10, 0x10 }, + { "STATUS_PHASE", 0x20, 0x20 }, + { "DATA_PHASE_MASK", 0x03, 0x03 } +}; + +int +ahc_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SFUNCT_parse_table[] = { + { "ALT_MODE", 0x80, 0x80 } +}; + +int +ahc_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SFUNCT_parse_table, 1, "SFUNCT", + 0x9f, regvalue, cur_col, wrap)); +} + +int +ahc_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_BASE", + 0xa0, regvalue, cur_col, wrap)); +} + +int +ahc_scb_cdb_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_CDB_PTR", + 0xa0, regvalue, cur_col, wrap)); +} + +int +ahc_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", + 0xa4, regvalue, cur_col, wrap)); +} + +int +ahc_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_SCSI_STATUS", + 0xa8, regvalue, cur_col, wrap)); +} + +int +ahc_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TARGET_PHASES", + 0xa9, regvalue, cur_col, wrap)); +} + +int +ahc_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", + 0xaa, regvalue, cur_col, wrap)); +} + +int +ahc_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TARGET_ITAG", + 0xab, regvalue, cur_col, wrap)); +} + +int +ahc_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_DATAPTR", + 0xac, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_DATACNT_parse_table[] = { + { "SG_LAST_SEG", 0x80, 0x80 }, + { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f } +}; + +int +ahc_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT", + 0xb0, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_SGPTR_parse_table[] = { + { "SG_LIST_NULL", 0x01, 0x01 }, + { "SG_FULL_RESID", 0x02, 0x02 }, + { "SG_RESID_VALID", 0x04, 0x04 } +}; + +int +ahc_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR", + 0xb4, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_CONTROL_parse_table[] = { + { "DISCONNECTED", 0x04, 0x04 }, + { "ULTRAENB", 0x08, 0x08 }, + { "MK_MESSAGE", 0x10, 0x10 }, + { "TAG_ENB", 0x20, 0x20 }, + { "DISCENB", 0x40, 0x40 }, + { "TARGET_SCB", 0x80, 0x80 }, + { "STATUS_RCVD", 0x80, 0x80 }, + { "SCB_TAG_TYPE", 0x03, 0x03 } +}; + +int +ahc_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_CONTROL_parse_table, 8, "SCB_CONTROL", + 0xb8, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_SCSIID_parse_table[] = { + { "TWIN_CHNLB", 0x80, 0x80 }, + { "OID", 0x0f, 0x0f }, + { "TWIN_TID", 0x70, 0x70 }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahc_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_SCSIID_parse_table, 4, "SCB_SCSIID", + 0xb9, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_LUN_parse_table[] = { + { "LID", 0xff, 0xff } +}; + +int +ahc_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_LUN_parse_table, 1, "SCB_LUN", + 0xba, regvalue, cur_col, wrap)); +} + +int +ahc_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TAG", + 0xbb, regvalue, cur_col, wrap)); +} + +int +ahc_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_CDB_LEN", + 0xbc, regvalue, cur_col, wrap)); +} + +int +ahc_scb_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_SCSIRATE", + 0xbd, regvalue, cur_col, wrap)); +} + +int +ahc_scb_scsioffset_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_SCSIOFFSET", + 0xbe, regvalue, cur_col, wrap)); +} + +int +ahc_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_NEXT", + 0xbf, regvalue, cur_col, wrap)); +} + +int +ahc_scb_64_spare_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_64_SPARE", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEECTL_2840_parse_table[] = { + { "DO_2840", 0x01, 0x01 }, + { "CK_2840", 0x02, 0x02 }, + { "CS_2840", 0x04, 0x04 } +}; + +int +ahc_seectl_2840_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEECTL_2840_parse_table, 3, "SEECTL_2840", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t STATUS_2840_parse_table[] = { + { "DI_2840", 0x01, 0x01 }, + { "EEPROM_TF", 0x80, 0x80 }, + { "ADSEL", 0x1e, 0x1e }, + { "BIOS_SEL", 0x60, 0x60 } +}; + +int +ahc_status_2840_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(STATUS_2840_parse_table, 4, "STATUS_2840", + 0xc1, regvalue, cur_col, wrap)); +} + +int +ahc_scb_64_btt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_64_BTT", + 0xd0, regvalue, cur_col, wrap)); +} + +int +ahc_cchaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCHADDR", + 0xe0, regvalue, cur_col, wrap)); +} + +int +ahc_cchcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCHCNT", + 0xe8, regvalue, cur_col, wrap)); +} + +int +ahc_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSGRAM", + 0xe9, regvalue, cur_col, wrap)); +} + +int +ahc_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSGADDR", + 0xea, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CCSGCTL_parse_table[] = { + { "CCSGRESET", 0x01, 0x01 }, + { "SG_FETCH_NEEDED", 0x02, 0x02 }, + { "CCSGEN", 0x08, 0x08 }, + { "CCSGDONE", 0x80, 0x80 } +}; + +int +ahc_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CCSGCTL_parse_table, 4, "CCSGCTL", + 0xeb, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBRAM", + 0xec, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBADDR", + 0xed, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CCSCBCTL_parse_table[] = { + { "CCSCBRESET", 0x01, 0x01 }, + { "CCSCBDIR", 0x04, 0x04 }, + { "CCSCBEN", 0x08, 0x08 }, + { "CCARREN", 0x10, 0x10 }, + { "ARRDONE", 0x40, 0x40 }, + { "CCSCBDONE", 0x80, 0x80 } +}; + +int +ahc_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL", + 0xee, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBCNT", + 0xef, regvalue, cur_col, wrap)); +} + +int +ahc_scbbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCBBADDR", + 0xf0, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBPTR", + 0xf1, regvalue, cur_col, wrap)); +} + +int +ahc_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HNSCB_QOFF", + 0xf4, regvalue, cur_col, wrap)); +} + +int +ahc_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SNSCB_QOFF", + 0xf6, regvalue, cur_col, wrap)); +} + +int +ahc_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SDSCB_QOFF", + 0xf8, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = { + { "SDSCB_ROLLOVER", 0x10, 0x10 }, + { "SNSCB_ROLLOVER", 0x20, 0x20 }, + { "SCB_AVAIL", 0x40, 0x40 }, + { "SCB_QSIZE_256", 0x06, 0x06 }, + { "SCB_QSIZE", 0x07, 0x07 } +}; + +int +ahc_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(QOFF_CTLSTA_parse_table, 5, "QOFF_CTLSTA", + 0xfa, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DFF_THRSH_parse_table[] = { + { "RD_DFTHRSH_MIN", 0x00, 0x00 }, + { "WR_DFTHRSH_MIN", 0x00, 0x00 }, + { "RD_DFTHRSH_25", 0x01, 0x01 }, + { "RD_DFTHRSH_50", 0x02, 0x02 }, + { "RD_DFTHRSH_63", 0x03, 0x03 }, + { "RD_DFTHRSH_75", 0x04, 0x04 }, + { "RD_DFTHRSH_85", 0x05, 0x05 }, + { "RD_DFTHRSH_90", 0x06, 0x06 }, + { "RD_DFTHRSH", 0x07, 0x07 }, + { "RD_DFTHRSH_MAX", 0x07, 0x07 }, + { "WR_DFTHRSH_25", 0x10, 0x10 }, + { "WR_DFTHRSH_50", 0x20, 0x20 }, + { "WR_DFTHRSH_63", 0x30, 0x30 }, + { "WR_DFTHRSH_75", 0x40, 0x40 }, + { "WR_DFTHRSH_85", 0x50, 0x50 }, + { "WR_DFTHRSH_90", 0x60, 0x60 }, + { "WR_DFTHRSH", 0x70, 0x70 }, + { "WR_DFTHRSH_MAX", 0x70, 0x70 } +}; + +int +ahc_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH", + 0xfb, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = { + { "LAST_SEG_DONE", 0x01, 0x01 }, + { "LAST_SEG", 0x02, 0x02 }, + { "ODD_SEG", 0x04, 0x04 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW", + 0xfc, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = { + { "LAST_SEG_DONE", 0x01, 0x01 }, + { "LAST_SEG", 0x02, 0x02 }, + { "ODD_SEG", 0x04, 0x04 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SG_CACHE_PRE_parse_table, 4, "SG_CACHE_PRE", + 0xfc, regvalue, cur_col, wrap)); +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx.seq linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx.seq --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx.seq 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx.seq 2003-01-22 22:10:29.000000000 +0000 @@ -37,11 +37,12 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.94.2.16 2002/04/29 19:36:30 gibbs Exp $ + * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $" PATCH_ARG_LIST = "struct ahc_softc *ahc" +PREFIX = "ahc_" #include "aic7xxx.reg" #include "scsi_message.h" @@ -69,7 +70,7 @@ * Turn off the selection hardware. We need to reset the * selection request in order to perform a new selection. */ - and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ; + and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP; and SIMODE1, ~ENBUSFREE; poll_for_work: call clear_target_state; @@ -192,7 +193,7 @@ * Setup the DMA for sending the identify and * command information. */ - or SEQ_FLAGS, CMDPHASE_PENDING; + mvi SEQ_FLAGS, CMDPHASE_PENDING; mov A, TQINPOS; if ((ahc->features & AHC_CMD_CHAN) != 0) { @@ -305,7 +306,7 @@ } else { mvi DFDAT, SCB_LIST_NULL; } - or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN; + or SEQ_FLAGS, TARG_CMD_PENDING; test SEQ_FLAGS2, TARGET_MSG_PENDING jnz target_mesgout_pending; test SCSISIGI, ATNI jnz target_mesgout_continue; @@ -389,13 +390,8 @@ } /* - * Initialize transfer settings and clear the SCSI channel. - * SINDEX should contain any additional bit's the client wants - * set in SXFRCTL0. We also assume that the current SCB is - * a valid SCB for the target we wish to talk to. + * Initialize transfer settings with SCB provided settings. */ -initialize_channel: - or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; set_transfer_settings: if ((ahc->features & AHC_ULTRA) != 0) { test SCB_CONTROL, ULTRAENB jz . + 2; @@ -442,10 +438,18 @@ mov WAITING_SCBH,SCB_NEXT; mov SAVED_SCSIID, SCB_SCSIID; mov SAVED_LUN, SCB_LUN; - call initialize_channel; + call set_transfer_settings; if ((ahc->flags & AHC_TARGETROLE) != 0) { test SSTAT0, TARGET jz initiator_select; + or SXFRCTL0, CLRSTCNT|CLRCHN; + + /* + * Put tag in connonical location since not + * all connections have an SCB. + */ + mov INITIATOR_TAG, SCB_TARGET_ITAG; + /* * We've just re-selected an initiator. * Assert BSY and setup the phase for @@ -491,15 +495,16 @@ * on the state of NO_DISCONNECT. */ test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect; - mov RETURN_1, ALLZEROS; + mvi TARG_IMMEDIATE_SCB, SCB_LIST_NULL; call complete_target_cmd; - cmp RETURN_1, CONT_MSG_LOOP jne .; if ((ahc->flags & AHC_PAGESCBS) != 0) { mov ALLZEROS call get_free_or_disc_scb; } + cmp TARG_IMMEDIATE_SCB, SCB_LIST_NULL je .; mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; - mov SCB_TAG call dma_scb; + mov TARG_IMMEDIATE_SCB call dma_scb; call set_transfer_settings; + or SXFRCTL0, CLRSTCNT|CLRCHN; jmp target_synccmd; target_mesgout: @@ -507,6 +512,7 @@ target_mesgout_continue: call target_inb; target_mesgout_pending: + and SEQ_FLAGS2, ~TARGET_MSG_PENDING; /* Local Processing goes here... */ jmp host_target_message_loop; @@ -636,13 +642,14 @@ if ((ahc->flags & AHC_INITIATORROLE) != 0) { initiator_select: + or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; /* * As soon as we get a successful selection, the target * should go into the message out phase since we have ATN * asserted. */ mvi MSG_OUT, MSG_IDENTIFYFLAG; - or SEQ_FLAGS, IDENTIFY_SEEN; + mvi SEQ_FLAGS, NO_CDB_SENT; mvi CLRSINT0, CLRSELDO; /* @@ -701,7 +708,7 @@ } mvi LASTPHASE, P_BUSFREE; /* clear target specific flags */ - clr SEQ_FLAGS ret; + mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; sg_advance: clr A; /* add sizeof(struct scatter) */ @@ -815,9 +822,9 @@ } p_data: - test SEQ_FLAGS,IDENTIFY_SEEN jnz p_data_okay; - mvi NO_IDENT jmp set_seqint; -p_data_okay: + test SEQ_FLAGS,NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; + mvi PROTO_VIOLATION call set_seqint; +p_data_allowed: if ((ahc->features & AHC_ULTRA2) != 0) { mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; } else { @@ -1361,8 +1368,8 @@ * Command phase. Set up the DMA registers and let 'er rip. */ p_command: - test SEQ_FLAGS,IDENTIFY_SEEN jnz p_command_okay; - mvi NO_IDENT jmp set_seqint; + test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; + mvi PROTO_VIOLATION call set_seqint; p_command_okay: if ((ahc->features & AHC_ULTRA2) != 0) { @@ -1394,7 +1401,7 @@ } mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET); } - jmp p_command_loop; + jmp p_command_xfer; p_command_embedded: /* * The data fifo seems to require 4 byte aligned @@ -1432,24 +1439,28 @@ call copy_to_fifo_6; or DFCNTRL, FIFOFLUSH; } -p_command_loop: +p_command_xfer: + and SEQ_FLAGS, ~NO_CDB_SENT; if ((ahc->features & AHC_DT) == 0) { test SSTAT0, SDONE jnz . + 2; - test SSTAT1, PHASEMIS jz p_command_loop; + test SSTAT1, PHASEMIS jz . - 1; /* * Wait for our ACK to go-away on it's own * instead of being killed by SCSIEN getting cleared. */ test SCSISIGI, ACKI jnz .; } else { - test DFCNTRL, SCSIEN jnz p_command_loop; + test DFCNTRL, SCSIEN jnz .; } + test SSTAT0, SDONE jnz p_command_successful; + /* + * Don't allow a data phase if the command + * was not fully transferred. + */ + or SEQ_FLAGS, NO_CDB_SENT; +p_command_successful: and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .; - if ((ahc->features & AHC_ULTRA2) != 0) { - /* Drop any residual from the S/G Preload queue */ - or SXFRCTL0, CLRSTCNT; - } jmp ITloop; /* @@ -1457,10 +1468,10 @@ * and store it into the SCB. */ p_status: - test SEQ_FLAGS,IDENTIFY_SEEN jnz p_status_okay; - mvi NO_IDENT jmp set_seqint; + test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; p_status_okay: mov SCB_SCSI_STATUS, SCSIDATL; + or SCB_CONTROL, STATUS_RCVD; jmp ITloop; /* @@ -1581,13 +1592,15 @@ jmp mesgin_done; } +mesgin_proto_violation: + mvi PROTO_VIOLATION call set_seqint; + jmp mesgin_done; mesgin_reject: mvi MSG_MESSAGE_REJECT call mk_mesg; mesgin_done: mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ jmp ITloop; -mesgin_complete: /* * We received a "command complete" message. Put the SCB_TAG into the QOUTFIFO, * and trigger a completion interrupt. Before doing so, check to see if there @@ -1600,27 +1613,49 @@ * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting * RETURN_1 to SEND_SENSE. */ +mesgin_complete: -/* - * If ATN is raised, we still want to give the target a message. - * Perhaps there was a parity error on this last message byte. - * Either way, the target should take us to message out phase - * and then attempt to complete the command again. We should use a - * critical section here to guard against a timeout triggering - * for this command and setting ATN while we are still processing - * the completion. + /* + * If ATN is raised, we still want to give the target a message. + * Perhaps there was a parity error on this last message byte. + * Either way, the target should take us to message out phase + * and then attempt to complete the command again. We should use a + * critical section here to guard against a timeout triggering + * for this command and setting ATN while we are still processing + * the completion. test SCSISIGI, ATNI jnz mesgin_done; - */ + */ -/* - * See if we attempted to deliver a message but the target ingnored us. - */ + /* + * If we are identified and have successfully sent the CDB, + * any status will do. Optimize this fast path. + */ + test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; + + /* + * If the target never sent an identify message but instead went + * to mesgin to give an invalid message, let the host abort us. + */ + test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; + + /* + * If we recevied good status but never successfully sent the + * cdb, abort the command. + */ + test SCB_SCSI_STATUS,0xff jnz complete_accepted; + test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; + +complete_accepted: + /* + * See if we attempted to deliver a message but the target ingnored us. + */ test SCB_CONTROL, MK_MESSAGE jz . + 2; mvi MKMSG_FAILED call set_seqint; -/* - * Check for residuals - */ + /* + * Check for residuals + */ test SCB_SGPTR, SG_LIST_NULL jnz check_status;/* No xfer */ test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; @@ -1673,7 +1708,8 @@ * XXX - Wait for more testing. test SCSISIGI, ATNI jnz mesgin_done; */ - + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT + jnz mesgin_proto_violation; or SCB_CONTROL,DISCONNECTED; if ((ahc->flags & AHC_PAGESCBS) != 0) { call add_scb_to_disc_list; @@ -1741,7 +1777,8 @@ * Restore pointers message? Data pointers are recopied from the * SCB anytime we enter a data phase for the first time, so all * we need to do is clear the DPHASE flag and let the data phase - * code do the rest. + * code do the rest. We also reset/reallocate the FIFO to make + * sure we have a clean start for the next data or command phase. */ mesgin_rdptrs: and SEQ_FLAGS, ~DPHASE; /* @@ -1749,6 +1786,7 @@ * the next time through * the dataphase. */ + or SXFRCTL0, CLRSTCNT|CLRCHN; jmp mesgin_done; /* @@ -1776,7 +1814,7 @@ * transactions by first looking at the transaction stored in * the busy target array. If there is no untagged transaction * for this target or the transaction is for a different lun, then - * this must be an untagged transaction. + * this must be a tagged transaction. */ shr SINDEX, 4, SAVED_SCSIID; and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; @@ -1897,7 +1935,7 @@ mov SCBPTR, A; } setup_SCB_tagged: - mvi SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ + clr SEQ_FLAGS; /* make note of IDENTIFY */ call set_transfer_settings; /* See if the host wants to send a message upon reconnection */ test SCB_CONTROL, MK_MESSAGE jz mesgin_done; @@ -2218,9 +2256,9 @@ * available data to force the chip to * continue the transfer. This does not * happen for SCSI transfers as the SCSI module - * will drain the FIFO as data is made available. + * will drain the FIFO as data are made available. * When the hang occurs, we know that a multiple - * of 8 bytes are in the FIFO because the PCI + * of 8 bytes is in the FIFO because the PCI * module has an 8 byte input latch that only * dumps to the FIFO when HCNT == 0 or the * latch is full. @@ -2257,7 +2295,6 @@ } else { call dma_finish; } - /* If we were putting the SCB, we are done */ call dfdat_in_8; call dfdat_in_8; call dfdat_in_8; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_seq.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_seq.h --- linux.21pre4/drivers/scsi/aic7xxx/aic7xxx_seq.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aic7xxx_seq.h 2003-01-22 22:10:29.000000000 +0000 @@ -2,13 +2,13 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $ - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ */ static uint8_t seqprog[] = { 0xb2, 0x00, 0x00, 0x08, 0xf7, 0x11, 0x22, 0x08, - 0x00, 0x65, 0xe4, 0x59, + 0x00, 0x65, 0xec, 0x59, 0xf7, 0x01, 0x02, 0x08, 0xff, 0x6a, 0x24, 0x08, 0x40, 0x00, 0x40, 0x68, @@ -21,15 +21,15 @@ 0x01, 0x4d, 0xc8, 0x30, 0x00, 0x4c, 0x12, 0x70, 0x01, 0x39, 0xa2, 0x30, - 0x00, 0x6a, 0xb6, 0x5e, + 0x00, 0x6a, 0xd4, 0x5e, 0x01, 0x51, 0x20, 0x31, 0x01, 0x57, 0xae, 0x00, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x51, 0x08, 0x5e, + 0x00, 0x51, 0x26, 0x5e, 0x01, 0x51, 0xc8, 0x30, 0x00, 0x39, 0xc8, 0x60, 0x00, 0xbb, 0x30, 0x70, - 0xc1, 0x6a, 0xce, 0x5e, + 0xc1, 0x6a, 0xec, 0x5e, 0x01, 0xbf, 0x72, 0x30, 0x01, 0x40, 0x7e, 0x31, 0x01, 0x90, 0x80, 0x30, @@ -42,17 +42,17 @@ 0x08, 0x6a, 0x18, 0x00, 0x08, 0x11, 0x22, 0x00, 0x60, 0x0b, 0x00, 0x78, - 0x40, 0x0b, 0xfc, 0x68, + 0x40, 0x0b, 0xfa, 0x68, 0x80, 0x0b, 0xb6, 0x78, 0x20, 0x6a, 0x16, 0x00, 0xa4, 0x6a, 0x06, 0x00, - 0x08, 0x3c, 0x78, 0x00, + 0x08, 0x6a, 0x78, 0x00, 0x01, 0x50, 0xc8, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xf2, 0x5d, + 0x48, 0x6a, 0x10, 0x5e, 0x01, 0x6a, 0xdc, 0x01, 0x88, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xf2, 0x5d, + 0x48, 0x6a, 0x10, 0x5e, 0x01, 0x6a, 0x26, 0x01, 0xf0, 0x19, 0x7a, 0x08, 0x0f, 0x18, 0xc8, 0x08, @@ -63,8 +63,8 @@ 0x80, 0x3d, 0x7a, 0x00, 0x01, 0x3d, 0xd8, 0x31, 0x01, 0x3d, 0x32, 0x31, - 0x10, 0x03, 0x48, 0x79, - 0x00, 0x65, 0xf4, 0x58, + 0x10, 0x03, 0x4e, 0x79, + 0x00, 0x65, 0xf2, 0x58, 0x80, 0x66, 0xae, 0x78, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, @@ -72,29 +72,29 @@ 0x40, 0x66, 0x82, 0x68, 0x01, 0x3c, 0x78, 0x00, 0x10, 0x03, 0x9e, 0x78, - 0x00, 0x65, 0xf4, 0x58, + 0x00, 0x65, 0xf2, 0x58, 0xe0, 0x66, 0xc8, 0x18, 0x00, 0x65, 0xaa, 0x50, 0xdd, 0x66, 0xc8, 0x18, 0x00, 0x65, 0xaa, 0x48, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, - 0x10, 0x03, 0x48, 0x79, - 0x00, 0x65, 0xf4, 0x58, + 0x10, 0x03, 0x4e, 0x79, + 0x00, 0x65, 0xf2, 0x58, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, 0x01, 0x66, 0xac, 0x30, 0x40, 0x3c, 0x78, 0x00, 0xff, 0x6a, 0xd8, 0x01, 0xff, 0x6a, 0x32, 0x01, - 0x90, 0x3c, 0x78, 0x00, - 0x02, 0x57, 0x3c, 0x69, - 0x10, 0x03, 0x3a, 0x69, - 0x00, 0x65, 0x1e, 0x41, + 0x10, 0x3c, 0x78, 0x00, + 0x02, 0x57, 0x40, 0x69, + 0x10, 0x03, 0x3e, 0x69, + 0x00, 0x65, 0x20, 0x41, 0x02, 0x57, 0xae, 0x00, 0x00, 0x65, 0x9e, 0x40, - 0x61, 0x6a, 0xce, 0x5e, - 0x08, 0x51, 0x1e, 0x71, + 0x61, 0x6a, 0xec, 0x5e, + 0x08, 0x51, 0x20, 0x71, 0x02, 0x0b, 0xb2, 0x78, 0x00, 0x65, 0xae, 0x40, 0x1a, 0x01, 0x02, 0x00, @@ -105,8 +105,8 @@ 0x08, 0x1f, 0xc4, 0x78, 0x80, 0x3d, 0x7a, 0x00, 0x20, 0x6a, 0x16, 0x00, - 0x00, 0x65, 0xc4, 0x41, - 0x00, 0x65, 0xa8, 0x5e, + 0x00, 0x65, 0xcc, 0x41, + 0x00, 0x65, 0xc6, 0x5e, 0x00, 0x65, 0x12, 0x40, 0x20, 0x11, 0xd2, 0x68, 0x20, 0x6a, 0x18, 0x00, @@ -123,13 +123,12 @@ 0x80, 0x65, 0xca, 0x00, 0x01, 0x65, 0x00, 0x34, 0x01, 0x54, 0x00, 0x34, - 0x1a, 0x01, 0x02, 0x00, - 0x08, 0xb8, 0xf0, 0x78, + 0x08, 0xb8, 0xee, 0x78, 0x20, 0x01, 0x02, 0x00, 0x02, 0xbd, 0x08, 0x34, 0x01, 0xbd, 0x08, 0x34, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0xf6, 0x78, + 0x02, 0x0b, 0xf4, 0x78, 0xf7, 0x01, 0x02, 0x08, 0x01, 0x06, 0xcc, 0x34, 0xb2, 0x00, 0x00, 0x08, @@ -138,155 +137,160 @@ 0x01, 0xb9, 0x7a, 0x30, 0x01, 0xba, 0x7c, 0x30, 0x00, 0x65, 0xea, 0x58, - 0x80, 0x0b, 0xbe, 0x79, - 0xe4, 0x6a, 0x64, 0x5d, + 0x80, 0x0b, 0xc4, 0x79, + 0x12, 0x01, 0x02, 0x00, + 0x01, 0xab, 0xac, 0x30, + 0xe4, 0x6a, 0x82, 0x5d, 0x40, 0x6a, 0x16, 0x00, - 0x80, 0xba, 0x7a, 0x5d, - 0x20, 0xb8, 0x16, 0x79, - 0x20, 0x6a, 0x7a, 0x5d, - 0x00, 0xab, 0x7a, 0x5d, + 0x80, 0xba, 0x98, 0x5d, + 0x20, 0xb8, 0x18, 0x79, + 0x20, 0x6a, 0x98, 0x5d, + 0x00, 0xab, 0x98, 0x5d, 0x01, 0xa9, 0x78, 0x30, - 0x10, 0xb8, 0x1e, 0x79, - 0xe4, 0x6a, 0x64, 0x5d, + 0x10, 0xb8, 0x20, 0x79, + 0xe4, 0x6a, 0x82, 0x5d, 0x00, 0x65, 0xae, 0x40, - 0x10, 0x03, 0x38, 0x69, - 0x08, 0x3c, 0x54, 0x69, - 0x04, 0x3c, 0x8c, 0x69, - 0x02, 0x3c, 0x92, 0x69, - 0x01, 0x3c, 0x3e, 0x79, - 0x01, 0x6a, 0xa2, 0x30, - 0x00, 0x65, 0x9e, 0x59, - 0x04, 0x51, 0x2c, 0x61, - 0x00, 0x6a, 0xb6, 0x5e, + 0x10, 0x03, 0x3c, 0x69, + 0x08, 0x3c, 0x5a, 0x69, + 0x04, 0x3c, 0x92, 0x69, + 0x02, 0x3c, 0x98, 0x69, + 0x01, 0x3c, 0x44, 0x79, + 0xff, 0x6a, 0x70, 0x00, + 0x00, 0x65, 0xa4, 0x59, + 0x00, 0x6a, 0xd4, 0x5e, + 0xff, 0x38, 0x30, 0x71, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x08, 0x5e, - 0x00, 0x65, 0xec, 0x58, - 0x00, 0x65, 0x16, 0x41, + 0x00, 0x38, 0x26, 0x5e, + 0x00, 0x65, 0xea, 0x58, + 0x12, 0x01, 0x02, 0x00, + 0x00, 0x65, 0x18, 0x41, 0xa4, 0x6a, 0x06, 0x00, - 0x00, 0x65, 0xf4, 0x58, + 0x00, 0x65, 0xf2, 0x58, + 0xfd, 0x57, 0xae, 0x08, 0x00, 0x65, 0xae, 0x40, - 0xe4, 0x6a, 0x64, 0x5d, - 0x20, 0x3c, 0x44, 0x79, - 0x02, 0x6a, 0x7a, 0x5d, - 0x04, 0x6a, 0x7a, 0x5d, - 0x01, 0x03, 0x46, 0x69, + 0xe4, 0x6a, 0x82, 0x5d, + 0x20, 0x3c, 0x4a, 0x79, + 0x02, 0x6a, 0x98, 0x5d, + 0x04, 0x6a, 0x98, 0x5d, + 0x01, 0x03, 0x4c, 0x69, 0xf7, 0x11, 0x22, 0x08, 0xff, 0x6a, 0x24, 0x08, 0xff, 0x6a, 0x06, 0x08, 0x01, 0x6a, 0x7e, 0x00, - 0x00, 0x65, 0x9e, 0x59, + 0x00, 0x65, 0xa4, 0x59, 0x00, 0x65, 0x04, 0x40, 0x80, 0x86, 0xc8, 0x08, 0x01, 0x4f, 0xc8, 0x30, - 0x00, 0x50, 0x66, 0x61, - 0xc4, 0x6a, 0x64, 0x5d, - 0x40, 0x3c, 0x62, 0x79, - 0x28, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x46, 0x41, - 0x08, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x46, 0x41, - 0x84, 0x6a, 0x64, 0x5d, - 0x00, 0x65, 0xf4, 0x58, + 0x00, 0x50, 0x6c, 0x61, + 0xc4, 0x6a, 0x82, 0x5d, + 0x40, 0x3c, 0x68, 0x79, + 0x28, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x08, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x84, 0x6a, 0x82, 0x5d, + 0x00, 0x65, 0xf2, 0x58, 0x01, 0x66, 0xc8, 0x30, 0x01, 0x64, 0xd8, 0x31, 0x01, 0x64, 0x32, 0x31, 0x5b, 0x64, 0xc8, 0x28, 0x30, 0x64, 0xca, 0x18, 0x01, 0x6c, 0xc8, 0x30, - 0xff, 0x64, 0x88, 0x79, + 0xff, 0x64, 0x8e, 0x79, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x7a, 0x79, - 0x01, 0x64, 0x80, 0x61, + 0x02, 0x0b, 0x80, 0x79, + 0x01, 0x64, 0x86, 0x61, 0xf7, 0x01, 0x02, 0x08, 0x01, 0x06, 0xd8, 0x31, 0x01, 0x06, 0x32, 0x31, 0xff, 0x64, 0xc8, 0x18, - 0xff, 0x64, 0x7a, 0x69, + 0xff, 0x64, 0x80, 0x69, 0xf7, 0x3c, 0x78, 0x08, - 0x00, 0x65, 0x1e, 0x41, + 0x00, 0x65, 0x20, 0x41, 0x40, 0xaa, 0x7e, 0x10, - 0x04, 0xaa, 0x64, 0x5d, - 0x00, 0x65, 0x56, 0x42, - 0xc4, 0x6a, 0x64, 0x5d, + 0x04, 0xaa, 0x82, 0x5d, + 0x00, 0x65, 0x5e, 0x42, + 0xc4, 0x6a, 0x82, 0x5d, 0xc0, 0x6a, 0x7e, 0x00, - 0x00, 0xa8, 0x7a, 0x5d, + 0x00, 0xa8, 0x98, 0x5d, 0xe4, 0x6a, 0x06, 0x00, - 0x00, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x46, 0x41, - 0x10, 0x3c, 0xa2, 0x69, - 0x00, 0xbb, 0x84, 0x44, + 0x00, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x10, 0x3c, 0xa8, 0x69, + 0x00, 0xbb, 0x9e, 0x44, 0x18, 0x6a, 0xda, 0x01, 0x01, 0x69, 0xd8, 0x31, 0x1c, 0x6a, 0xd0, 0x01, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0xaa, 0x79, + 0x80, 0xee, 0xb0, 0x79, 0xff, 0x6a, 0xdc, 0x09, 0x01, 0x93, 0x26, 0x01, 0x03, 0x6a, 0x2a, 0x01, 0x01, 0x69, 0x32, 0x31, - 0x1c, 0x6a, 0xd6, 0x5d, + 0x1c, 0x6a, 0xf4, 0x5d, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x5e, + 0x00, 0x65, 0xbc, 0x5e, 0x01, 0x50, 0xa0, 0x18, 0x02, 0x6a, 0x22, 0x05, + 0x1a, 0x01, 0x02, 0x00, 0x80, 0x6a, 0x74, 0x00, - 0x80, 0x3c, 0x78, 0x00, + 0x40, 0x6a, 0x78, 0x00, 0x40, 0x6a, 0x16, 0x00, - 0x00, 0x65, 0xce, 0x5d, + 0x00, 0x65, 0xec, 0x5d, 0x01, 0x3f, 0xc8, 0x30, - 0xbf, 0x64, 0x56, 0x7a, - 0x80, 0x64, 0xaa, 0x73, - 0xa0, 0x64, 0x08, 0x74, - 0xc0, 0x64, 0xfc, 0x73, - 0xe0, 0x64, 0x38, 0x74, - 0x01, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0xc4, 0x41, + 0xbf, 0x64, 0x5e, 0x7a, + 0x80, 0x64, 0xb2, 0x73, + 0xa0, 0x64, 0x14, 0x74, + 0xc0, 0x64, 0x08, 0x74, + 0xe0, 0x64, 0x44, 0x74, + 0x01, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0xf7, 0x11, 0x22, 0x08, 0x01, 0x06, 0xd4, 0x30, 0xff, 0x6a, 0x24, 0x08, 0xf7, 0x01, 0x02, 0x08, - 0x09, 0x0c, 0xde, 0x79, + 0x09, 0x0c, 0xe6, 0x79, 0x08, 0x0c, 0x04, 0x68, - 0xb1, 0x6a, 0xce, 0x5e, + 0xb1, 0x6a, 0xec, 0x5e, 0xff, 0x6a, 0x26, 0x09, 0x12, 0x01, 0x02, 0x00, 0x02, 0x6a, 0x08, 0x30, 0xff, 0x6a, 0x08, 0x08, 0xdf, 0x01, 0x02, 0x08, 0x01, 0x6a, 0x7e, 0x00, - 0xff, 0x6a, 0x78, 0x0c, + 0xc0, 0x6a, 0x78, 0x04, 0xff, 0x6a, 0xc8, 0x08, 0x08, 0xa4, 0x48, 0x19, 0x00, 0xa5, 0x4a, 0x21, 0x00, 0xa6, 0x4c, 0x21, 0x00, 0xa7, 0x4e, 0x25, - 0x08, 0xeb, 0xd2, 0x7e, - 0x80, 0xeb, 0xfe, 0x79, + 0x08, 0xeb, 0xf0, 0x7e, + 0x80, 0xeb, 0x06, 0x7a, 0xff, 0x6a, 0xd6, 0x09, - 0x08, 0xeb, 0x02, 0x6a, + 0x08, 0xeb, 0x0a, 0x6a, 0xff, 0x6a, 0xd4, 0x0c, - 0x80, 0xa3, 0xd2, 0x6e, - 0x88, 0xeb, 0x18, 0x72, - 0x08, 0xeb, 0xd2, 0x6e, - 0x04, 0xea, 0x1c, 0xe2, - 0x08, 0xee, 0xd2, 0x6e, + 0x80, 0xa3, 0xf0, 0x6e, + 0x88, 0xeb, 0x20, 0x72, + 0x08, 0xeb, 0xf0, 0x6e, + 0x04, 0xea, 0x24, 0xe2, + 0x08, 0xee, 0xf0, 0x6e, 0x04, 0x6a, 0xd0, 0x81, 0x05, 0xa4, 0xc0, 0x89, 0x03, 0xa5, 0xc2, 0x31, 0x09, 0x6a, 0xd6, 0x05, - 0x00, 0x65, 0x00, 0x5a, + 0x00, 0x65, 0x08, 0x5a, 0x06, 0xa4, 0xd4, 0x89, - 0x80, 0x94, 0xd2, 0x7e, + 0x80, 0x94, 0xf0, 0x7e, 0x07, 0xe9, 0x10, 0x31, - 0x01, 0x8c, 0x24, 0x7a, + 0x01, 0x8c, 0x2c, 0x7a, 0x01, 0x55, 0xaa, 0x10, 0x01, 0xe9, 0x46, 0x31, - 0x00, 0xa3, 0xb0, 0x5e, - 0x00, 0x65, 0xf2, 0x59, + 0x00, 0xa3, 0xce, 0x5e, + 0x00, 0x65, 0xfa, 0x59, 0x01, 0xa4, 0xca, 0x30, - 0x01, 0x55, 0x30, 0x7a, + 0x01, 0x55, 0x38, 0x7a, 0x04, 0x65, 0xca, 0x00, - 0x80, 0xa3, 0x34, 0x7a, + 0x80, 0xa3, 0x3c, 0x7a, 0x02, 0x65, 0xca, 0x00, 0x01, 0x65, 0xf8, 0x31, 0x80, 0x93, 0x26, 0x01, @@ -294,168 +298,168 @@ 0x01, 0x8c, 0xc8, 0x30, 0x00, 0x88, 0xc8, 0x18, 0x02, 0x64, 0xc8, 0x88, - 0xff, 0x64, 0xd2, 0x7e, - 0xff, 0x8d, 0x4a, 0x6a, - 0xff, 0x8e, 0x4a, 0x6a, + 0xff, 0x64, 0xf0, 0x7e, + 0xff, 0x8d, 0x52, 0x6a, + 0xff, 0x8e, 0x52, 0x6a, 0x03, 0x8c, 0xd4, 0x98, - 0x00, 0x65, 0xd2, 0x56, + 0x00, 0x65, 0xf0, 0x56, 0x01, 0x64, 0x70, 0x30, 0xff, 0x64, 0xc8, 0x10, 0x01, 0x64, 0xc8, 0x18, 0x00, 0x8c, 0x18, 0x19, 0xff, 0x8d, 0x1a, 0x21, 0xff, 0x8e, 0x1c, 0x25, - 0x80, 0x3c, 0x5a, 0x6a, - 0x21, 0x6a, 0xce, 0x46, + 0xc0, 0x3c, 0x62, 0x7a, + 0x21, 0x6a, 0xec, 0x5e, 0xa8, 0x6a, 0x76, 0x00, 0x79, 0x6a, 0x76, 0x00, - 0x40, 0x3f, 0x62, 0x6a, + 0x40, 0x3f, 0x6a, 0x6a, 0x04, 0x3b, 0x76, 0x00, 0x04, 0x6a, 0xd4, 0x81, - 0x20, 0x3c, 0x6a, 0x7a, - 0x51, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x84, 0x42, + 0x20, 0x3c, 0x72, 0x7a, + 0x51, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x8c, 0x42, 0x20, 0x3c, 0x78, 0x00, - 0x00, 0xb3, 0xb0, 0x5e, + 0x00, 0xb3, 0xce, 0x5e, 0x07, 0xac, 0x10, 0x31, 0x05, 0xb3, 0x46, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0xac, 0x6a, 0xe4, 0x5d, + 0xac, 0x6a, 0x02, 0x5e, 0xa3, 0x6a, 0xcc, 0x00, - 0xb3, 0x6a, 0xe8, 0x5d, - 0x00, 0x65, 0x3a, 0x5a, + 0xb3, 0x6a, 0x06, 0x5e, + 0x00, 0x65, 0x42, 0x5a, 0xfd, 0xa4, 0x48, 0x09, 0x01, 0x8c, 0xaa, 0x08, 0x03, 0x8c, 0x10, 0x30, - 0x00, 0x65, 0xdc, 0x5d, - 0x01, 0xa4, 0x96, 0x7a, + 0x00, 0x65, 0xfa, 0x5d, + 0x01, 0xa4, 0x9e, 0x7a, 0x04, 0x3b, 0x76, 0x08, 0x01, 0x3b, 0x26, 0x31, 0x80, 0x02, 0x04, 0x00, - 0x10, 0x0c, 0x8c, 0x7a, - 0x03, 0x9e, 0x8e, 0x6a, + 0x10, 0x0c, 0x94, 0x7a, + 0x03, 0x9e, 0x96, 0x6a, 0x7f, 0x02, 0x04, 0x08, - 0x91, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0xc4, 0x41, + 0x91, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0x01, 0xa4, 0xca, 0x30, - 0x80, 0xa3, 0x9c, 0x7a, + 0x80, 0xa3, 0xa4, 0x7a, 0x02, 0x65, 0xca, 0x00, - 0x01, 0x55, 0xa0, 0x7a, + 0x01, 0x55, 0xa8, 0x7a, 0x04, 0x65, 0xca, 0x00, 0x01, 0x65, 0xf8, 0x31, 0x01, 0x3b, 0x26, 0x31, - 0x00, 0x65, 0x06, 0x5a, - 0x01, 0xfc, 0xae, 0x6a, - 0x80, 0x0b, 0xa4, 0x6a, - 0x10, 0x0c, 0xa4, 0x7a, - 0x20, 0x93, 0xa4, 0x6a, + 0x00, 0x65, 0x0e, 0x5a, + 0x01, 0xfc, 0xb6, 0x6a, + 0x80, 0x0b, 0xac, 0x6a, + 0x10, 0x0c, 0xac, 0x7a, + 0x20, 0x93, 0xac, 0x6a, 0x02, 0x93, 0x26, 0x01, - 0x02, 0xfc, 0xb8, 0x7a, - 0x40, 0x0d, 0xd2, 0x6a, + 0x02, 0xfc, 0xc0, 0x7a, + 0x40, 0x0d, 0xda, 0x6a, 0x01, 0xa4, 0x48, 0x01, - 0x00, 0x65, 0xd2, 0x42, - 0x40, 0x0d, 0xbe, 0x6a, - 0x00, 0x65, 0x06, 0x5a, - 0x00, 0x65, 0xb0, 0x42, - 0x80, 0xfc, 0xc8, 0x7a, - 0x80, 0xa4, 0xc8, 0x6a, + 0x00, 0x65, 0xda, 0x42, + 0x40, 0x0d, 0xc6, 0x6a, + 0x00, 0x65, 0x0e, 0x5a, + 0x00, 0x65, 0xb8, 0x42, + 0x80, 0xfc, 0xd0, 0x7a, + 0x80, 0xa4, 0xd0, 0x6a, 0xff, 0xa5, 0x4a, 0x19, 0xff, 0xa6, 0x4c, 0x21, 0xff, 0xa7, 0x4e, 0x21, 0xf8, 0xfc, 0x48, 0x09, 0xff, 0x6a, 0xaa, 0x08, - 0x04, 0xfc, 0xd0, 0x7a, + 0x04, 0xfc, 0xd8, 0x7a, 0x01, 0x55, 0xaa, 0x00, 0xff, 0x6a, 0x46, 0x09, - 0x04, 0x3b, 0xea, 0x6a, + 0x04, 0x3b, 0xf2, 0x6a, 0x02, 0x93, 0x26, 0x01, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0xa4, 0xe8, 0x7a, - 0x01, 0xfc, 0xe2, 0x7a, - 0x01, 0x94, 0xea, 0x6a, - 0x00, 0x65, 0x84, 0x42, - 0x01, 0x94, 0xe8, 0x7a, - 0x10, 0x94, 0xea, 0x6a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0xa4, 0xf0, 0x7a, + 0x01, 0xfc, 0xea, 0x7a, + 0x01, 0x94, 0xf2, 0x6a, + 0x00, 0x65, 0x8c, 0x42, + 0x01, 0x94, 0xf0, 0x7a, + 0x10, 0x94, 0xf2, 0x6a, 0xd7, 0x93, 0x26, 0x09, - 0x28, 0x93, 0xee, 0x6a, + 0x28, 0x93, 0xf6, 0x6a, 0x01, 0x85, 0x0a, 0x01, - 0x02, 0xfc, 0xf6, 0x6a, + 0x02, 0xfc, 0xfe, 0x6a, 0x01, 0x14, 0x46, 0x31, 0xff, 0x6a, 0x10, 0x09, 0xfe, 0x85, 0x0a, 0x09, - 0xff, 0x38, 0x04, 0x6b, - 0x80, 0xa3, 0x04, 0x7b, - 0x80, 0x0b, 0x02, 0x7b, - 0x04, 0x3b, 0x04, 0x7b, + 0xff, 0x38, 0x0c, 0x6b, + 0x80, 0xa3, 0x0c, 0x7b, + 0x80, 0x0b, 0x0a, 0x7b, + 0x04, 0x3b, 0x0c, 0x7b, 0xbf, 0x3b, 0x76, 0x08, 0x01, 0x3b, 0x26, 0x31, - 0x00, 0x65, 0x06, 0x5a, - 0x01, 0x0b, 0x12, 0x6b, - 0x10, 0x0c, 0x06, 0x7b, - 0x04, 0x93, 0x10, 0x6b, - 0x01, 0x94, 0x0e, 0x7b, - 0x10, 0x94, 0x10, 0x6b, + 0x00, 0x65, 0x0e, 0x5a, + 0x01, 0x0b, 0x1a, 0x6b, + 0x10, 0x0c, 0x0e, 0x7b, + 0x04, 0x93, 0x18, 0x6b, + 0x01, 0x94, 0x16, 0x7b, + 0x10, 0x94, 0x18, 0x6b, 0xc7, 0x93, 0x26, 0x09, 0x01, 0x99, 0xd4, 0x30, - 0x38, 0x93, 0x14, 0x6b, - 0xff, 0x08, 0x66, 0x6b, - 0xff, 0x09, 0x66, 0x6b, - 0xff, 0x0a, 0x66, 0x6b, - 0xff, 0x38, 0x30, 0x7b, + 0x38, 0x93, 0x1c, 0x6b, + 0xff, 0x08, 0x6e, 0x6b, + 0xff, 0x09, 0x6e, 0x6b, + 0xff, 0x0a, 0x6e, 0x6b, + 0xff, 0x38, 0x38, 0x7b, 0x04, 0x14, 0x10, 0x31, 0x01, 0x38, 0x18, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0xea, 0x5d, - 0x00, 0x38, 0xd6, 0x5d, + 0x14, 0x6a, 0x08, 0x5e, + 0x00, 0x38, 0xf4, 0x5d, 0xff, 0x6a, 0x70, 0x08, - 0x00, 0x65, 0x5c, 0x43, - 0x80, 0xa3, 0x36, 0x7b, + 0x00, 0x65, 0x64, 0x43, + 0x80, 0xa3, 0x3e, 0x7b, 0x01, 0xa4, 0x48, 0x01, - 0x00, 0x65, 0x66, 0x43, - 0x08, 0xeb, 0x3c, 0x7b, - 0x00, 0x65, 0x06, 0x5a, - 0x08, 0xeb, 0x38, 0x6b, + 0x00, 0x65, 0x6e, 0x43, + 0x08, 0xeb, 0x44, 0x7b, + 0x00, 0x65, 0x0e, 0x5a, + 0x08, 0xeb, 0x40, 0x6b, 0x07, 0xe9, 0x10, 0x31, 0x01, 0xe9, 0xca, 0x30, 0x01, 0x65, 0x46, 0x31, - 0x00, 0x6a, 0xb0, 0x5e, + 0x00, 0x6a, 0xce, 0x5e, 0x88, 0x6a, 0xcc, 0x00, - 0xa4, 0x6a, 0xea, 0x5d, - 0x08, 0x6a, 0xd6, 0x5d, + 0xa4, 0x6a, 0x08, 0x5e, + 0x08, 0x6a, 0xf4, 0x5d, 0x0d, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x5e, + 0x00, 0x65, 0xbc, 0x5e, 0x88, 0x6a, 0xcc, 0x00, - 0x00, 0x65, 0x80, 0x5e, + 0x00, 0x65, 0x9e, 0x5e, 0x01, 0x99, 0x46, 0x31, - 0x00, 0xa3, 0xb0, 0x5e, + 0x00, 0xa3, 0xce, 0x5e, 0x01, 0x88, 0x10, 0x31, - 0x00, 0x65, 0x3a, 0x5a, - 0x00, 0x65, 0xf2, 0x59, + 0x00, 0x65, 0x42, 0x5a, + 0x00, 0x65, 0xfa, 0x59, 0x03, 0x8c, 0x10, 0x30, - 0x00, 0x65, 0xdc, 0x5d, - 0x01, 0x8c, 0x64, 0x7b, + 0x00, 0x65, 0xfa, 0x5d, + 0x01, 0x8c, 0x6c, 0x7b, 0x01, 0x55, 0xaa, 0x10, - 0x80, 0x0b, 0x84, 0x6a, - 0x80, 0x0b, 0x6e, 0x6b, - 0x01, 0x0c, 0x68, 0x7b, - 0x10, 0x0c, 0x84, 0x7a, - 0x03, 0x9e, 0x84, 0x6a, - 0x00, 0x65, 0xfc, 0x59, - 0x00, 0x6a, 0xb0, 0x5e, - 0x01, 0xa4, 0x8e, 0x6b, - 0xff, 0x38, 0x84, 0x7b, + 0x80, 0x0b, 0x8c, 0x6a, + 0x80, 0x0b, 0x76, 0x6b, + 0x01, 0x0c, 0x70, 0x7b, + 0x10, 0x0c, 0x8c, 0x7a, + 0x03, 0x9e, 0x8c, 0x6a, + 0x00, 0x65, 0x04, 0x5a, + 0x00, 0x6a, 0xce, 0x5e, + 0x01, 0xa4, 0x96, 0x6b, + 0xff, 0x38, 0x8c, 0x7b, 0x01, 0x38, 0xc8, 0x30, 0x00, 0x08, 0x40, 0x19, 0xff, 0x6a, 0xc8, 0x08, 0x00, 0x09, 0x42, 0x21, 0x00, 0x0a, 0x44, 0x21, 0xff, 0x6a, 0x70, 0x08, - 0x00, 0x65, 0x86, 0x43, + 0x00, 0x65, 0x8e, 0x43, 0x03, 0x08, 0x40, 0x31, 0x03, 0x08, 0x40, 0x31, 0x01, 0x08, 0x40, 0x31, @@ -464,19 +468,19 @@ 0xfd, 0xb4, 0x68, 0x09, 0x12, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, - 0x04, 0x3c, 0xc4, 0x79, + 0x04, 0x3c, 0xcc, 0x79, 0xfb, 0x3c, 0x78, 0x08, - 0x04, 0x93, 0x1e, 0x79, - 0x01, 0x0c, 0x9a, 0x6b, - 0x01, 0x55, 0x1e, 0x79, - 0x80, 0x04, 0x1e, 0x79, - 0xe4, 0x6a, 0x64, 0x5d, - 0x23, 0x6a, 0x7a, 0x5d, - 0x01, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x1e, 0x41, - 0x00, 0x65, 0xc4, 0x41, - 0x80, 0x3c, 0xae, 0x6b, - 0x21, 0x6a, 0xce, 0x46, + 0x04, 0x93, 0x20, 0x79, + 0x01, 0x0c, 0xa2, 0x6b, + 0x01, 0x55, 0x20, 0x79, + 0x80, 0x04, 0x20, 0x79, + 0xe4, 0x6a, 0x82, 0x5d, + 0x23, 0x6a, 0x98, 0x5d, + 0x01, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x20, 0x41, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0x3c, 0xb6, 0x7b, + 0x21, 0x6a, 0xec, 0x5e, 0x01, 0xbc, 0x18, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x02, 0x6a, 0xf8, 0x01, @@ -486,16 +490,16 @@ 0xff, 0x6a, 0x12, 0x08, 0xff, 0x6a, 0x14, 0x08, 0xf3, 0xbc, 0xd4, 0x18, - 0xa0, 0x6a, 0xd4, 0x53, + 0xa0, 0x6a, 0xdc, 0x53, 0x04, 0xa0, 0x10, 0x31, 0xac, 0x6a, 0x26, 0x01, 0x04, 0xa0, 0x10, 0x31, 0x03, 0x08, 0x18, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0xa0, 0x6a, 0xea, 0x5d, - 0x00, 0xbc, 0xd6, 0x5d, + 0xa0, 0x6a, 0x08, 0x5e, + 0x00, 0xbc, 0xf4, 0x5d, 0x3d, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0xec, 0x43, + 0x00, 0x65, 0xf4, 0x43, 0xff, 0x6a, 0x10, 0x09, 0xa4, 0x6a, 0x26, 0x01, 0x0c, 0xa0, 0x32, 0x31, @@ -505,117 +509,128 @@ 0x36, 0x6a, 0x26, 0x01, 0x02, 0x93, 0x26, 0x01, 0x35, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0x92, 0x5e, - 0x00, 0x65, 0x92, 0x5e, + 0x00, 0x65, 0xb0, 0x5e, + 0x00, 0x65, 0xb0, 0x5e, 0x02, 0x93, 0x26, 0x01, - 0x04, 0x0b, 0xf0, 0x6b, - 0x10, 0x0c, 0xec, 0x7b, - 0x01, 0x03, 0xf0, 0x6b, - 0x20, 0x93, 0xec, 0x6b, + 0xbf, 0x3c, 0x78, 0x08, + 0x04, 0x0b, 0xfa, 0x6b, + 0x10, 0x0c, 0xf6, 0x7b, + 0x01, 0x03, 0xfa, 0x6b, + 0x20, 0x93, 0xfc, 0x6b, + 0x04, 0x0b, 0x02, 0x6c, + 0x40, 0x3c, 0x78, 0x00, 0xc7, 0x93, 0x26, 0x09, - 0x38, 0x93, 0xf6, 0x6b, - 0x10, 0x01, 0x02, 0x00, - 0x00, 0x65, 0xc4, 0x41, - 0x80, 0x3c, 0x00, 0x6c, - 0x21, 0x6a, 0xce, 0x46, + 0x38, 0x93, 0x04, 0x6c, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0x3c, 0x6a, 0x6c, 0x01, 0x06, 0x50, 0x31, - 0x00, 0x65, 0xc4, 0x41, + 0x80, 0xb8, 0x70, 0x01, + 0x00, 0x65, 0xcc, 0x41, 0x10, 0x3f, 0x06, 0x00, 0x10, 0x6a, 0x06, 0x00, 0x01, 0x3a, 0xca, 0x30, - 0x80, 0x65, 0x24, 0x64, - 0x10, 0xb8, 0x48, 0x6c, + 0x80, 0x65, 0x30, 0x64, + 0x10, 0xb8, 0x54, 0x6c, 0xc0, 0xba, 0xca, 0x00, - 0x40, 0xb8, 0x14, 0x6c, + 0x40, 0xb8, 0x20, 0x6c, 0xbf, 0x65, 0xca, 0x08, - 0x20, 0xb8, 0x28, 0x7c, + 0x20, 0xb8, 0x34, 0x7c, 0x01, 0x65, 0x0c, 0x30, - 0x00, 0x65, 0xce, 0x5d, - 0xa0, 0x3f, 0x30, 0x64, + 0x00, 0x65, 0xec, 0x5d, + 0xa0, 0x3f, 0x3c, 0x64, 0x23, 0xb8, 0x0c, 0x08, - 0x00, 0x65, 0xce, 0x5d, - 0xa0, 0x3f, 0x30, 0x64, - 0x00, 0xbb, 0x28, 0x44, - 0xff, 0x65, 0x28, 0x64, - 0x00, 0x65, 0x48, 0x44, + 0x00, 0x65, 0xec, 0x5d, + 0xa0, 0x3f, 0x3c, 0x64, + 0x00, 0xbb, 0x34, 0x44, + 0xff, 0x65, 0x34, 0x64, + 0x00, 0x65, 0x54, 0x44, 0x40, 0x6a, 0x18, 0x00, 0x01, 0x65, 0x0c, 0x30, - 0x00, 0x65, 0xce, 0x5d, - 0xa0, 0x3f, 0x04, 0x74, + 0x00, 0x65, 0xec, 0x5d, + 0xa0, 0x3f, 0x10, 0x74, 0x40, 0x6a, 0x18, 0x00, 0x01, 0x3a, 0xa6, 0x30, 0x08, 0x6a, 0x74, 0x00, - 0x00, 0x65, 0xc4, 0x41, - 0x64, 0x6a, 0x5e, 0x5d, - 0x80, 0x64, 0xce, 0x6c, - 0x04, 0x64, 0x94, 0x74, - 0x02, 0x64, 0xa2, 0x74, - 0x00, 0x6a, 0x64, 0x74, - 0x03, 0x64, 0xc0, 0x74, - 0x23, 0x64, 0x50, 0x74, - 0x08, 0x64, 0x60, 0x74, - 0x61, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0xce, 0x5d, - 0x08, 0x51, 0xc6, 0x71, - 0x00, 0x65, 0x48, 0x44, - 0x80, 0x04, 0x5e, 0x7c, - 0x51, 0x6a, 0x54, 0x5d, - 0x01, 0x51, 0x5e, 0x64, - 0x01, 0xa4, 0x5a, 0x7c, - 0x01, 0x55, 0x60, 0x7c, - 0x41, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x60, 0x44, - 0x07, 0x6a, 0x4a, 0x5d, + 0x00, 0x65, 0xcc, 0x41, + 0x64, 0x6a, 0x7c, 0x5d, + 0x80, 0x64, 0xec, 0x6c, + 0x04, 0x64, 0xae, 0x74, + 0x02, 0x64, 0xbe, 0x74, + 0x00, 0x6a, 0x74, 0x74, + 0x03, 0x64, 0xdc, 0x74, + 0x23, 0x64, 0x5c, 0x74, + 0x08, 0x64, 0x70, 0x74, + 0x61, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0xec, 0x5d, + 0x08, 0x51, 0xce, 0x71, + 0x00, 0x65, 0x54, 0x44, + 0x80, 0x04, 0x6e, 0x7c, + 0x51, 0x6a, 0x72, 0x5d, + 0x01, 0x51, 0x6e, 0x64, + 0x01, 0xa4, 0x66, 0x7c, + 0x01, 0x55, 0x70, 0x7c, + 0x41, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x70, 0x44, + 0x21, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x70, 0x44, + 0x07, 0x6a, 0x68, 0x5d, 0x01, 0x06, 0xd4, 0x30, - 0x00, 0x65, 0xc4, 0x41, - 0x10, 0xb8, 0x68, 0x7c, - 0xa1, 0x6a, 0xce, 0x5e, - 0x01, 0xb4, 0x6e, 0x6c, - 0x02, 0xb4, 0x70, 0x6c, - 0x01, 0xa4, 0x70, 0x7c, - 0xff, 0xa8, 0x80, 0x7c, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0xb8, 0x6a, 0x7c, + 0xc0, 0x3c, 0x7e, 0x7c, + 0x80, 0x3c, 0x6a, 0x6c, + 0xff, 0xa8, 0x7e, 0x6c, + 0x40, 0x3c, 0x6a, 0x6c, + 0x10, 0xb8, 0x82, 0x7c, + 0xa1, 0x6a, 0xec, 0x5e, + 0x01, 0xb4, 0x88, 0x6c, + 0x02, 0xb4, 0x8a, 0x6c, + 0x01, 0xa4, 0x8a, 0x7c, + 0xff, 0xa8, 0x9a, 0x7c, 0x04, 0xb4, 0x68, 0x01, 0x01, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x08, 0x5e, - 0xff, 0xa8, 0x80, 0x7c, - 0x71, 0x6a, 0xce, 0x5e, - 0x40, 0x51, 0x80, 0x64, - 0x00, 0x65, 0xa8, 0x5e, - 0x00, 0x65, 0xd6, 0x41, - 0x00, 0xbb, 0x84, 0x5c, - 0x00, 0x65, 0xd6, 0x41, - 0x00, 0x65, 0xa8, 0x5e, + 0x00, 0xbb, 0x26, 0x5e, + 0xff, 0xa8, 0x9a, 0x7c, + 0x71, 0x6a, 0xec, 0x5e, + 0x40, 0x51, 0x9a, 0x64, + 0x00, 0x65, 0xc6, 0x5e, + 0x00, 0x65, 0xde, 0x41, + 0x00, 0xbb, 0x9e, 0x5c, + 0x00, 0x65, 0xde, 0x41, + 0x00, 0x65, 0xc6, 0x5e, 0x01, 0x65, 0xa2, 0x30, 0x01, 0xf8, 0xc8, 0x30, 0x01, 0x4e, 0xc8, 0x30, - 0x00, 0x6a, 0xac, 0xdd, - 0x00, 0x51, 0xbe, 0x5d, + 0x00, 0x6a, 0xca, 0xdd, + 0x00, 0x51, 0xdc, 0x5d, 0x01, 0x4e, 0x9c, 0x18, 0x02, 0x6a, 0x22, 0x05, + 0xc0, 0x3c, 0x6a, 0x6c, 0x04, 0xb8, 0x70, 0x01, - 0x00, 0x65, 0xca, 0x5e, - 0x20, 0xb8, 0xd6, 0x69, + 0x00, 0x65, 0xe8, 0x5e, + 0x20, 0xb8, 0xde, 0x69, 0x01, 0xbb, 0xa2, 0x30, 0x01, 0xba, 0x7c, 0x30, - 0x00, 0xb9, 0xc4, 0x5c, - 0x00, 0x65, 0xd6, 0x41, + 0x00, 0xb9, 0xe2, 0x5c, + 0x00, 0x65, 0xde, 0x41, 0x01, 0x06, 0xd4, 0x30, - 0x20, 0x3c, 0xc4, 0x79, - 0x20, 0x3c, 0x60, 0x7c, - 0x01, 0xa4, 0xb0, 0x7c, + 0x20, 0x3c, 0xcc, 0x79, + 0x20, 0x3c, 0x70, 0x7c, + 0x01, 0xa4, 0xcc, 0x7c, 0x01, 0xb4, 0x68, 0x01, - 0x00, 0x65, 0xc4, 0x41, - 0x00, 0x65, 0x60, 0x44, + 0x00, 0x65, 0xcc, 0x41, + 0x00, 0x65, 0x70, 0x44, 0x04, 0x14, 0x58, 0x31, 0x01, 0x06, 0xd4, 0x30, 0x08, 0xa0, 0x60, 0x31, 0xac, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0xea, 0x5d, + 0x14, 0x6a, 0x08, 0x5e, 0x01, 0x06, 0xd4, 0x30, - 0xa0, 0x6a, 0xe2, 0x5d, - 0x00, 0x65, 0xc4, 0x41, + 0xa0, 0x6a, 0x00, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0xdf, 0x3c, 0x78, 0x08, - 0x00, 0x65, 0x60, 0x44, + 0x12, 0x01, 0x02, 0x00, + 0x00, 0x65, 0x70, 0x44, 0x4c, 0x65, 0xcc, 0x28, 0x01, 0x3e, 0x20, 0x31, 0xd0, 0x66, 0xcc, 0x18, @@ -626,102 +641,102 @@ 0xd0, 0x65, 0xca, 0x18, 0x01, 0x3e, 0x20, 0x31, 0x30, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xdc, 0x4c, + 0x00, 0x65, 0xfa, 0x4c, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x20, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xe4, 0x54, + 0x00, 0x65, 0x02, 0x55, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x20, 0x65, 0xca, 0x18, 0xe0, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xee, 0x4c, + 0x00, 0x65, 0x0c, 0x4d, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0xd0, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xf6, 0x54, + 0x00, 0x65, 0x14, 0x55, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x01, 0x6c, 0xa2, 0x30, - 0xff, 0x51, 0x08, 0x75, - 0x00, 0x51, 0x84, 0x5d, + 0xff, 0x51, 0x26, 0x75, + 0x00, 0x51, 0xa2, 0x5d, 0x01, 0x51, 0x20, 0x31, - 0x00, 0x65, 0x2a, 0x45, + 0x00, 0x65, 0x48, 0x45, 0x01, 0xba, 0xc8, 0x30, - 0x00, 0x3e, 0x2a, 0x75, - 0x00, 0x65, 0xa6, 0x5e, + 0x00, 0x3e, 0x48, 0x75, + 0x00, 0x65, 0xc4, 0x5e, 0x80, 0x3c, 0x78, 0x00, 0x01, 0x06, 0xd4, 0x30, - 0x00, 0x65, 0xce, 0x5d, + 0x00, 0x65, 0xec, 0x5d, 0x01, 0x3c, 0x78, 0x00, - 0xe0, 0x3f, 0x46, 0x65, + 0xe0, 0x3f, 0x64, 0x65, 0x02, 0x3c, 0x78, 0x00, - 0x20, 0x12, 0x46, 0x65, - 0x51, 0x6a, 0x54, 0x5d, - 0x00, 0x51, 0x84, 0x5d, - 0x51, 0x6a, 0x54, 0x5d, + 0x20, 0x12, 0x64, 0x65, + 0x51, 0x6a, 0x72, 0x5d, + 0x00, 0x51, 0xa2, 0x5d, + 0x51, 0x6a, 0x72, 0x5d, 0x01, 0x51, 0x20, 0x31, 0x04, 0x3c, 0x78, 0x00, 0x01, 0xb9, 0xc8, 0x30, - 0x00, 0x3d, 0x44, 0x65, + 0x00, 0x3d, 0x62, 0x65, 0x08, 0x3c, 0x78, 0x00, 0x01, 0xba, 0xc8, 0x30, - 0x00, 0x3e, 0x44, 0x65, + 0x00, 0x3e, 0x62, 0x65, 0x10, 0x3c, 0x78, 0x00, - 0x04, 0xb8, 0x44, 0x7d, + 0x04, 0xb8, 0x62, 0x7d, 0xfb, 0xb8, 0x70, 0x09, - 0x20, 0xb8, 0x3a, 0x6d, + 0x20, 0xb8, 0x58, 0x6d, 0x01, 0x90, 0xc8, 0x30, 0xff, 0x6a, 0xa2, 0x00, - 0x00, 0x3d, 0xc4, 0x5c, + 0x00, 0x3d, 0xe2, 0x5c, 0x01, 0x64, 0x20, 0x31, - 0x80, 0x6a, 0x78, 0x00, - 0x00, 0x65, 0xec, 0x58, - 0x10, 0xb8, 0x60, 0x7c, - 0xff, 0x6a, 0x4a, 0x5d, - 0x00, 0x65, 0x60, 0x44, - 0x00, 0x65, 0xa6, 0x5e, - 0x31, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x60, 0x44, + 0xff, 0x6a, 0x78, 0x08, + 0x00, 0x65, 0xea, 0x58, + 0x10, 0xb8, 0x70, 0x7c, + 0xff, 0x6a, 0x68, 0x5d, + 0x00, 0x65, 0x70, 0x44, + 0x00, 0x65, 0xc4, 0x5e, + 0x31, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x70, 0x44, 0x10, 0x3f, 0x06, 0x00, 0x10, 0x6a, 0x06, 0x00, 0x01, 0x65, 0x74, 0x34, - 0x81, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x56, 0x45, + 0x81, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x74, 0x45, 0x01, 0x06, 0xd4, 0x30, - 0x01, 0x0c, 0x56, 0x7d, - 0x04, 0x0c, 0x50, 0x6d, + 0x01, 0x0c, 0x74, 0x7d, + 0x04, 0x0c, 0x6e, 0x6d, 0xe0, 0x03, 0x7e, 0x08, - 0xe0, 0x3f, 0xc4, 0x61, + 0xe0, 0x3f, 0xcc, 0x61, 0x01, 0x65, 0xcc, 0x30, 0x01, 0x12, 0xda, 0x34, 0x01, 0x06, 0xd4, 0x34, - 0x01, 0x03, 0x64, 0x6d, + 0x01, 0x03, 0x82, 0x6d, 0x40, 0x03, 0xcc, 0x08, 0x01, 0x65, 0x06, 0x30, 0x40, 0x65, 0xc8, 0x08, - 0x00, 0x66, 0x72, 0x75, - 0x40, 0x65, 0x72, 0x7d, - 0x00, 0x65, 0x72, 0x5d, + 0x00, 0x66, 0x90, 0x75, + 0x40, 0x65, 0x90, 0x7d, + 0x00, 0x65, 0x90, 0x5d, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x0c, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x7c, 0x7d, + 0x02, 0x0b, 0x9a, 0x7d, 0x01, 0x65, 0x0c, 0x30, - 0x02, 0x0b, 0x80, 0x7d, + 0x02, 0x0b, 0x9e, 0x7d, 0xf7, 0x01, 0x02, 0x0c, 0x01, 0x65, 0xc8, 0x30, - 0xff, 0x41, 0xa4, 0x75, + 0xff, 0x41, 0xc2, 0x75, 0x01, 0x41, 0x20, 0x31, 0xff, 0x6a, 0xa4, 0x00, - 0x00, 0x65, 0x94, 0x45, - 0xff, 0xbf, 0xa4, 0x75, + 0x00, 0x65, 0xb2, 0x45, + 0xff, 0xbf, 0xc2, 0x75, 0x01, 0x90, 0xa4, 0x30, 0x01, 0xbf, 0x20, 0x31, - 0x00, 0xbb, 0x8e, 0x65, - 0xff, 0x52, 0xa2, 0x75, + 0x00, 0xbb, 0xac, 0x65, + 0xff, 0x52, 0xc0, 0x75, 0x01, 0xbf, 0xcc, 0x30, 0x01, 0x90, 0xca, 0x30, 0x01, 0x52, 0x20, 0x31, @@ -729,28 +744,28 @@ 0x01, 0x65, 0x20, 0x35, 0x01, 0xbf, 0x82, 0x34, 0x01, 0x64, 0xa2, 0x30, - 0x00, 0x6a, 0xb6, 0x5e, + 0x00, 0x6a, 0xd4, 0x5e, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x51, 0x08, 0x46, + 0x00, 0x51, 0x26, 0x46, 0x01, 0x65, 0xa4, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xfc, 0x5d, + 0x48, 0x6a, 0x1a, 0x5e, 0x01, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x05, 0x88, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xfc, 0x5d, - 0x01, 0x6a, 0xd6, 0x5d, + 0x48, 0x6a, 0x1a, 0x5e, + 0x01, 0x6a, 0xf4, 0x5d, 0x01, 0x6a, 0x26, 0x05, 0x01, 0x65, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0xc2, 0x7d, + 0x80, 0xee, 0xe0, 0x7d, 0xff, 0x6a, 0xdc, 0x0d, 0x01, 0x65, 0x32, 0x31, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x46, - 0x81, 0x6a, 0xce, 0x5e, - 0x01, 0x0c, 0xce, 0x7d, - 0x04, 0x0c, 0xcc, 0x6d, + 0x00, 0x65, 0xbc, 0x46, + 0x81, 0x6a, 0xec, 0x5e, + 0x01, 0x0c, 0xec, 0x7d, + 0x04, 0x0c, 0xea, 0x6d, 0xe0, 0x03, 0x06, 0x08, 0xe0, 0x03, 0x7e, 0x0c, 0x01, 0x65, 0x18, 0x31, @@ -769,7 +784,7 @@ 0x01, 0x6c, 0xda, 0x34, 0x3d, 0x64, 0xa4, 0x28, 0x55, 0x64, 0xc8, 0x28, - 0x00, 0x65, 0xfc, 0x45, + 0x00, 0x65, 0x1a, 0x46, 0x2e, 0x64, 0xa4, 0x28, 0x66, 0x64, 0xc8, 0x28, 0x00, 0x6c, 0xda, 0x18, @@ -780,63 +795,63 @@ 0x00, 0x6c, 0xda, 0x24, 0x01, 0x65, 0xc8, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x44, 0x6a, 0xf8, 0x5d, + 0x44, 0x6a, 0x16, 0x5e, 0x01, 0x90, 0xe2, 0x31, - 0x04, 0x3b, 0x1c, 0x7e, + 0x04, 0x3b, 0x3a, 0x7e, 0x30, 0x6a, 0xd0, 0x01, 0x20, 0x6a, 0xd0, 0x01, 0x1d, 0x6a, 0xdc, 0x01, - 0xdc, 0xee, 0x18, 0x66, - 0x00, 0x65, 0x34, 0x46, + 0xdc, 0xee, 0x36, 0x66, + 0x00, 0x65, 0x52, 0x46, 0x20, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x01, 0x20, 0xa0, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0x24, 0x7e, + 0x80, 0xee, 0x42, 0x7e, 0x11, 0x6a, 0xdc, 0x01, - 0x50, 0xee, 0x28, 0x66, + 0x50, 0xee, 0x46, 0x66, 0x20, 0x6a, 0xd0, 0x01, 0x09, 0x6a, 0xdc, 0x01, - 0x88, 0xee, 0x2e, 0x66, + 0x88, 0xee, 0x4c, 0x66, 0x19, 0x6a, 0xdc, 0x01, - 0xd8, 0xee, 0x32, 0x66, + 0xd8, 0xee, 0x50, 0x66, 0xff, 0x6a, 0xdc, 0x09, - 0x18, 0xee, 0x36, 0x6e, + 0x18, 0xee, 0x54, 0x6e, 0xff, 0x6a, 0xd4, 0x0c, 0x88, 0x6a, 0xcc, 0x00, - 0x44, 0x6a, 0xf8, 0x5d, - 0x20, 0x6a, 0xd6, 0x5d, + 0x44, 0x6a, 0x16, 0x5e, + 0x20, 0x6a, 0xf4, 0x5d, 0x01, 0x3b, 0x26, 0x31, - 0x04, 0x3b, 0x50, 0x6e, + 0x04, 0x3b, 0x6e, 0x6e, 0xa0, 0x6a, 0xca, 0x00, 0x20, 0x65, 0xc8, 0x18, - 0x00, 0x65, 0x8e, 0x5e, - 0x00, 0x65, 0x48, 0x66, + 0x00, 0x65, 0xac, 0x5e, + 0x00, 0x65, 0x66, 0x66, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x46, + 0x00, 0x65, 0xbc, 0x46, 0xa0, 0x6a, 0xcc, 0x00, 0xff, 0x6a, 0xc8, 0x08, - 0x20, 0x94, 0x54, 0x6e, - 0x10, 0x94, 0x56, 0x6e, - 0x08, 0x94, 0x70, 0x6e, - 0x08, 0x94, 0x70, 0x6e, - 0x08, 0x94, 0x70, 0x6e, + 0x20, 0x94, 0x72, 0x6e, + 0x10, 0x94, 0x74, 0x6e, + 0x08, 0x94, 0x8e, 0x6e, + 0x08, 0x94, 0x8e, 0x6e, + 0x08, 0x94, 0x8e, 0x6e, 0xff, 0x8c, 0xc8, 0x10, 0xc1, 0x64, 0xc8, 0x18, 0xf8, 0x64, 0xc8, 0x08, 0x01, 0x99, 0xda, 0x30, - 0x00, 0x66, 0x64, 0x66, - 0xc0, 0x66, 0xa0, 0x76, + 0x00, 0x66, 0x82, 0x66, + 0xc0, 0x66, 0xbe, 0x76, 0x60, 0x66, 0xc8, 0x18, 0x3d, 0x64, 0xc8, 0x28, - 0x00, 0x65, 0x54, 0x46, + 0x00, 0x65, 0x72, 0x46, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0x72, 0x6e, + 0x08, 0x93, 0x90, 0x6e, 0x00, 0x62, 0xc4, 0x18, - 0x00, 0x65, 0x9e, 0x5e, - 0x00, 0x65, 0x7e, 0x5e, - 0x00, 0x65, 0x7e, 0x5e, - 0x00, 0x65, 0x7e, 0x5e, + 0x00, 0x65, 0xbc, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, 0x01, 0x99, 0xda, 0x30, 0x01, 0x99, 0xda, 0x30, 0x01, 0x99, 0xda, 0x30, @@ -853,11 +868,11 @@ 0x01, 0x6c, 0x32, 0x31, 0x01, 0x6c, 0x32, 0x31, 0x01, 0x6c, 0x32, 0x35, - 0x08, 0x94, 0x9e, 0x7e, + 0x08, 0x94, 0xbc, 0x7e, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0xa2, 0x6e, + 0x08, 0x93, 0xc0, 0x6e, 0xff, 0x6a, 0xd4, 0x0c, - 0x04, 0xb8, 0xca, 0x6e, + 0x04, 0xb8, 0xe8, 0x6e, 0x01, 0x42, 0x7e, 0x31, 0xff, 0x6a, 0x76, 0x01, 0x01, 0x90, 0x84, 0x34, @@ -865,14 +880,14 @@ 0x01, 0x85, 0x0a, 0x01, 0x7f, 0x65, 0x10, 0x09, 0xfe, 0x85, 0x0a, 0x0d, - 0xff, 0x42, 0xc6, 0x66, - 0xff, 0x41, 0xbe, 0x66, - 0xd1, 0x6a, 0xce, 0x5e, + 0xff, 0x42, 0xe4, 0x66, + 0xff, 0x41, 0xdc, 0x66, + 0xd1, 0x6a, 0xec, 0x5e, 0xff, 0x6a, 0xca, 0x04, 0x01, 0x41, 0x20, 0x31, 0x01, 0xbf, 0x82, 0x30, 0x01, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x08, 0x46, + 0x00, 0xbb, 0x26, 0x46, 0x01, 0x42, 0x20, 0x31, 0x01, 0xbf, 0x84, 0x34, 0x01, 0x41, 0x7e, 0x31, @@ -882,420 +897,421 @@ 0xff, 0x6a, 0xd4, 0x0c }; -static int aic_patch23_func(struct ahc_softc *ahc); +typedef int ahc_patch_func_t (struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch23_func; static int -aic_patch23_func(struct ahc_softc *ahc) +ahc_patch23_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0); } -static int aic_patch22_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch22_func; static int -aic_patch22_func(struct ahc_softc *ahc) +ahc_patch22_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_CMD_CHAN) == 0); } -static int aic_patch21_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch21_func; static int -aic_patch21_func(struct ahc_softc *ahc) +ahc_patch21_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_QUEUE_REGS) == 0); } -static int aic_patch20_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch20_func; static int -aic_patch20_func(struct ahc_softc *ahc) +ahc_patch20_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_WIDE) != 0); } -static int aic_patch19_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch19_func; static int -aic_patch19_func(struct ahc_softc *ahc) +ahc_patch19_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_SCB_BTT) != 0); } -static int aic_patch18_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch18_func; static int -aic_patch18_func(struct ahc_softc *ahc) +ahc_patch18_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0); } -static int aic_patch17_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch17_func; static int -aic_patch17_func(struct ahc_softc *ahc) +ahc_patch17_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0); } -static int aic_patch16_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch16_func; static int -aic_patch16_func(struct ahc_softc *ahc) +ahc_patch16_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0); } -static int aic_patch15_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch15_func; static int -aic_patch15_func(struct ahc_softc *ahc) +ahc_patch15_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_ULTRA2) == 0); } -static int aic_patch14_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch14_func; static int -aic_patch14_func(struct ahc_softc *ahc) +ahc_patch14_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0); } -static int aic_patch13_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch13_func; static int -aic_patch13_func(struct ahc_softc *ahc) +ahc_patch13_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_39BIT_ADDRESSING) != 0); } -static int aic_patch12_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch12_func; static int -aic_patch12_func(struct ahc_softc *ahc) +ahc_patch12_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_HS_MAILBOX) != 0); } -static int aic_patch11_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch11_func; static int -aic_patch11_func(struct ahc_softc *ahc) +ahc_patch11_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_ULTRA) != 0); } -static int aic_patch10_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch10_func; static int -aic_patch10_func(struct ahc_softc *ahc) +ahc_patch10_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_MULTI_TID) != 0); } -static int aic_patch9_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch9_func; static int -aic_patch9_func(struct ahc_softc *ahc) +ahc_patch9_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_CMD_CHAN) != 0); } -static int aic_patch8_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch8_func; static int -aic_patch8_func(struct ahc_softc *ahc) +ahc_patch8_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_INITIATORROLE) != 0); } -static int aic_patch7_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch7_func; static int -aic_patch7_func(struct ahc_softc *ahc) +ahc_patch7_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_TARGETROLE) != 0); } -static int aic_patch6_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch6_func; static int -aic_patch6_func(struct ahc_softc *ahc) +ahc_patch6_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_DT) == 0); } -static int aic_patch5_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch5_func; static int -aic_patch5_func(struct ahc_softc *ahc) +ahc_patch5_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0); } -static int aic_patch4_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch4_func; static int -aic_patch4_func(struct ahc_softc *ahc) +ahc_patch4_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_PAGESCBS) != 0); } -static int aic_patch3_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch3_func; static int -aic_patch3_func(struct ahc_softc *ahc) +ahc_patch3_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_QUEUE_REGS) != 0); } -static int aic_patch2_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch2_func; static int -aic_patch2_func(struct ahc_softc *ahc) +ahc_patch2_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_TWIN) != 0); } -static int aic_patch1_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch1_func; static int -aic_patch1_func(struct ahc_softc *ahc) +ahc_patch1_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_ULTRA2) != 0); } -static int aic_patch0_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch0_func; static int -aic_patch0_func(struct ahc_softc *ahc) +ahc_patch0_func(struct ahc_softc *ahc) { return (0); } -typedef int patch_func_t (struct ahc_softc *ahc); static struct patch { - patch_func_t *patch_func; - uint32_t begin :10, - skip_instr :10, - skip_patch :12; + ahc_patch_func_t *patch_func; + uint32_t begin :10, + skip_instr :10, + skip_patch :12; } patches[] = { - { aic_patch1_func, 4, 1, 1 }, - { aic_patch2_func, 6, 2, 1 }, - { aic_patch2_func, 9, 1, 1 }, - { aic_patch3_func, 11, 1, 2 }, - { aic_patch0_func, 12, 2, 1 }, - { aic_patch4_func, 15, 1, 2 }, - { aic_patch0_func, 16, 1, 1 }, - { aic_patch5_func, 22, 2, 1 }, - { aic_patch3_func, 27, 1, 2 }, - { aic_patch0_func, 28, 1, 1 }, - { aic_patch6_func, 34, 1, 1 }, - { aic_patch7_func, 37, 54, 19 }, - { aic_patch8_func, 37, 1, 1 }, - { aic_patch9_func, 42, 3, 2 }, - { aic_patch0_func, 45, 3, 1 }, - { aic_patch10_func, 49, 1, 2 }, - { aic_patch0_func, 50, 2, 3 }, - { aic_patch1_func, 50, 1, 2 }, - { aic_patch0_func, 51, 1, 1 }, - { aic_patch2_func, 53, 2, 1 }, - { aic_patch9_func, 55, 1, 2 }, - { aic_patch0_func, 56, 1, 1 }, - { aic_patch9_func, 60, 1, 2 }, - { aic_patch0_func, 61, 1, 1 }, - { aic_patch9_func, 71, 1, 2 }, - { aic_patch0_func, 72, 1, 1 }, - { aic_patch9_func, 75, 1, 2 }, - { aic_patch0_func, 76, 1, 1 }, - { aic_patch9_func, 79, 1, 2 }, - { aic_patch0_func, 80, 1, 1 }, - { aic_patch8_func, 91, 9, 4 }, - { aic_patch1_func, 93, 1, 2 }, - { aic_patch0_func, 94, 1, 1 }, - { aic_patch2_func, 96, 2, 1 }, - { aic_patch2_func, 105, 4, 1 }, - { aic_patch1_func, 109, 1, 2 }, - { aic_patch0_func, 110, 2, 3 }, - { aic_patch2_func, 110, 1, 2 }, - { aic_patch0_func, 111, 1, 1 }, - { aic_patch7_func, 112, 4, 2 }, - { aic_patch0_func, 116, 1, 1 }, - { aic_patch11_func, 118, 2, 1 }, - { aic_patch1_func, 120, 1, 2 }, - { aic_patch0_func, 121, 1, 1 }, - { aic_patch7_func, 122, 4, 1 }, - { aic_patch7_func, 132, 91, 11 }, - { aic_patch4_func, 151, 1, 1 }, - { aic_patch1_func, 165, 1, 1 }, - { aic_patch12_func, 170, 1, 2 }, - { aic_patch0_func, 171, 1, 1 }, - { aic_patch9_func, 182, 1, 2 }, - { aic_patch0_func, 183, 1, 1 }, - { aic_patch9_func, 192, 1, 2 }, - { aic_patch0_func, 193, 1, 1 }, - { aic_patch9_func, 209, 6, 2 }, - { aic_patch0_func, 215, 6, 1 }, - { aic_patch8_func, 223, 19, 2 }, - { aic_patch1_func, 237, 1, 1 }, - { aic_patch1_func, 244, 1, 2 }, - { aic_patch0_func, 245, 2, 2 }, - { aic_patch11_func, 246, 1, 1 }, - { aic_patch9_func, 254, 31, 3 }, - { aic_patch1_func, 270, 14, 2 }, - { aic_patch13_func, 275, 1, 1 }, - { aic_patch14_func, 285, 14, 1 }, - { aic_patch1_func, 301, 1, 2 }, - { aic_patch0_func, 302, 1, 1 }, - { aic_patch9_func, 305, 1, 1 }, - { aic_patch13_func, 310, 1, 1 }, - { aic_patch9_func, 311, 2, 2 }, - { aic_patch0_func, 313, 4, 1 }, - { aic_patch14_func, 317, 1, 1 }, - { aic_patch15_func, 320, 2, 3 }, - { aic_patch9_func, 320, 1, 2 }, - { aic_patch0_func, 321, 1, 1 }, - { aic_patch6_func, 326, 1, 2 }, - { aic_patch0_func, 327, 1, 1 }, - { aic_patch1_func, 331, 50, 11 }, - { aic_patch6_func, 340, 2, 4 }, - { aic_patch7_func, 340, 1, 1 }, - { aic_patch8_func, 341, 1, 1 }, - { aic_patch0_func, 342, 1, 1 }, - { aic_patch16_func, 343, 1, 1 }, - { aic_patch6_func, 362, 6, 3 }, - { aic_patch16_func, 362, 5, 1 }, - { aic_patch0_func, 368, 5, 1 }, - { aic_patch13_func, 376, 5, 1 }, - { aic_patch0_func, 381, 54, 17 }, - { aic_patch14_func, 381, 1, 1 }, - { aic_patch7_func, 383, 2, 2 }, - { aic_patch17_func, 384, 1, 1 }, - { aic_patch9_func, 387, 1, 1 }, - { aic_patch18_func, 394, 1, 1 }, - { aic_patch14_func, 399, 9, 3 }, - { aic_patch9_func, 400, 3, 2 }, - { aic_patch0_func, 403, 3, 1 }, - { aic_patch9_func, 411, 6, 2 }, - { aic_patch0_func, 417, 9, 2 }, - { aic_patch13_func, 417, 1, 1 }, - { aic_patch13_func, 426, 2, 1 }, - { aic_patch14_func, 428, 1, 1 }, - { aic_patch9_func, 430, 1, 2 }, - { aic_patch0_func, 431, 1, 1 }, - { aic_patch7_func, 434, 1, 1 }, - { aic_patch7_func, 435, 1, 1 }, - { aic_patch8_func, 436, 3, 3 }, - { aic_patch6_func, 437, 1, 2 }, - { aic_patch0_func, 438, 1, 1 }, - { aic_patch9_func, 439, 1, 1 }, - { aic_patch15_func, 440, 1, 2 }, - { aic_patch13_func, 440, 1, 1 }, - { aic_patch14_func, 442, 9, 4 }, - { aic_patch9_func, 442, 1, 1 }, - { aic_patch9_func, 449, 2, 1 }, - { aic_patch0_func, 451, 4, 3 }, - { aic_patch9_func, 451, 1, 2 }, - { aic_patch0_func, 452, 3, 1 }, - { aic_patch1_func, 456, 2, 1 }, - { aic_patch7_func, 458, 10, 2 }, - { aic_patch0_func, 468, 1, 1 }, - { aic_patch8_func, 469, 109, 23 }, - { aic_patch1_func, 471, 3, 2 }, - { aic_patch0_func, 474, 5, 3 }, - { aic_patch9_func, 474, 2, 2 }, - { aic_patch0_func, 476, 3, 1 }, - { aic_patch1_func, 481, 2, 2 }, - { aic_patch0_func, 483, 6, 3 }, - { aic_patch9_func, 483, 2, 2 }, - { aic_patch0_func, 485, 3, 1 }, - { aic_patch1_func, 491, 2, 2 }, - { aic_patch0_func, 493, 9, 7 }, - { aic_patch9_func, 493, 5, 6 }, - { aic_patch19_func, 493, 1, 2 }, - { aic_patch0_func, 494, 1, 1 }, - { aic_patch19_func, 496, 1, 2 }, - { aic_patch0_func, 497, 1, 1 }, - { aic_patch0_func, 498, 4, 1 }, - { aic_patch6_func, 502, 3, 2 }, - { aic_patch0_func, 505, 1, 1 }, - { aic_patch1_func, 508, 1, 1 }, - { aic_patch6_func, 514, 1, 2 }, - { aic_patch0_func, 515, 1, 1 }, - { aic_patch20_func, 552, 7, 1 }, - { aic_patch3_func, 580, 1, 2 }, - { aic_patch0_func, 581, 1, 1 }, - { aic_patch21_func, 584, 1, 1 }, - { aic_patch8_func, 586, 104, 33 }, - { aic_patch4_func, 587, 1, 1 }, - { aic_patch1_func, 593, 2, 2 }, - { aic_patch0_func, 595, 1, 1 }, - { aic_patch1_func, 598, 1, 2 }, - { aic_patch0_func, 599, 1, 1 }, - { aic_patch9_func, 600, 3, 3 }, - { aic_patch15_func, 601, 1, 1 }, - { aic_patch0_func, 603, 4, 1 }, - { aic_patch19_func, 611, 2, 2 }, - { aic_patch0_func, 613, 1, 1 }, - { aic_patch19_func, 617, 10, 3 }, - { aic_patch5_func, 619, 8, 1 }, - { aic_patch0_func, 627, 9, 2 }, - { aic_patch5_func, 628, 8, 1 }, - { aic_patch4_func, 638, 1, 2 }, - { aic_patch0_func, 639, 1, 1 }, - { aic_patch19_func, 640, 1, 2 }, - { aic_patch0_func, 641, 3, 2 }, - { aic_patch4_func, 643, 1, 1 }, - { aic_patch5_func, 644, 1, 1 }, - { aic_patch5_func, 647, 1, 1 }, - { aic_patch5_func, 649, 1, 1 }, - { aic_patch4_func, 651, 2, 2 }, - { aic_patch0_func, 653, 2, 1 }, - { aic_patch5_func, 655, 1, 1 }, - { aic_patch5_func, 658, 1, 1 }, - { aic_patch5_func, 661, 1, 1 }, - { aic_patch19_func, 665, 1, 1 }, - { aic_patch19_func, 668, 1, 1 }, - { aic_patch4_func, 674, 1, 1 }, - { aic_patch6_func, 677, 1, 2 }, - { aic_patch0_func, 678, 1, 1 }, - { aic_patch7_func, 690, 16, 1 }, - { aic_patch4_func, 706, 20, 1 }, - { aic_patch9_func, 727, 4, 2 }, - { aic_patch0_func, 731, 4, 1 }, - { aic_patch9_func, 735, 4, 2 }, - { aic_patch0_func, 739, 3, 1 }, - { aic_patch6_func, 745, 1, 1 }, - { aic_patch22_func, 747, 14, 1 }, - { aic_patch7_func, 761, 3, 1 }, - { aic_patch9_func, 773, 24, 8 }, - { aic_patch19_func, 777, 1, 2 }, - { aic_patch0_func, 778, 1, 1 }, - { aic_patch15_func, 783, 4, 2 }, - { aic_patch0_func, 787, 7, 3 }, - { aic_patch23_func, 787, 5, 2 }, - { aic_patch0_func, 792, 2, 1 }, - { aic_patch0_func, 797, 42, 3 }, - { aic_patch18_func, 809, 18, 2 }, - { aic_patch0_func, 827, 1, 1 }, - { aic_patch4_func, 851, 1, 1 }, - { aic_patch4_func, 852, 3, 2 }, - { aic_patch0_func, 855, 1, 1 }, - { aic_patch13_func, 856, 3, 1 }, - { aic_patch4_func, 859, 12, 1 } + { ahc_patch1_func, 4, 1, 1 }, + { ahc_patch2_func, 6, 2, 1 }, + { ahc_patch2_func, 9, 1, 1 }, + { ahc_patch3_func, 11, 1, 2 }, + { ahc_patch0_func, 12, 2, 1 }, + { ahc_patch4_func, 15, 1, 2 }, + { ahc_patch0_func, 16, 1, 1 }, + { ahc_patch5_func, 22, 2, 1 }, + { ahc_patch3_func, 27, 1, 2 }, + { ahc_patch0_func, 28, 1, 1 }, + { ahc_patch6_func, 34, 1, 1 }, + { ahc_patch7_func, 37, 54, 19 }, + { ahc_patch8_func, 37, 1, 1 }, + { ahc_patch9_func, 42, 3, 2 }, + { ahc_patch0_func, 45, 3, 1 }, + { ahc_patch10_func, 49, 1, 2 }, + { ahc_patch0_func, 50, 2, 3 }, + { ahc_patch1_func, 50, 1, 2 }, + { ahc_patch0_func, 51, 1, 1 }, + { ahc_patch2_func, 53, 2, 1 }, + { ahc_patch9_func, 55, 1, 2 }, + { ahc_patch0_func, 56, 1, 1 }, + { ahc_patch9_func, 60, 1, 2 }, + { ahc_patch0_func, 61, 1, 1 }, + { ahc_patch9_func, 71, 1, 2 }, + { ahc_patch0_func, 72, 1, 1 }, + { ahc_patch9_func, 75, 1, 2 }, + { ahc_patch0_func, 76, 1, 1 }, + { ahc_patch9_func, 79, 1, 2 }, + { ahc_patch0_func, 80, 1, 1 }, + { ahc_patch8_func, 91, 9, 4 }, + { ahc_patch1_func, 93, 1, 2 }, + { ahc_patch0_func, 94, 1, 1 }, + { ahc_patch2_func, 96, 2, 1 }, + { ahc_patch2_func, 105, 4, 1 }, + { ahc_patch1_func, 109, 1, 2 }, + { ahc_patch0_func, 110, 2, 3 }, + { ahc_patch2_func, 110, 1, 2 }, + { ahc_patch0_func, 111, 1, 1 }, + { ahc_patch7_func, 112, 4, 2 }, + { ahc_patch0_func, 116, 1, 1 }, + { ahc_patch11_func, 117, 2, 1 }, + { ahc_patch1_func, 119, 1, 2 }, + { ahc_patch0_func, 120, 1, 1 }, + { ahc_patch7_func, 121, 4, 1 }, + { ahc_patch7_func, 131, 95, 11 }, + { ahc_patch4_func, 151, 1, 1 }, + { ahc_patch1_func, 168, 1, 1 }, + { ahc_patch12_func, 173, 1, 2 }, + { ahc_patch0_func, 174, 1, 1 }, + { ahc_patch9_func, 185, 1, 2 }, + { ahc_patch0_func, 186, 1, 1 }, + { ahc_patch9_func, 195, 1, 2 }, + { ahc_patch0_func, 196, 1, 1 }, + { ahc_patch9_func, 212, 6, 2 }, + { ahc_patch0_func, 218, 6, 1 }, + { ahc_patch8_func, 226, 20, 2 }, + { ahc_patch1_func, 241, 1, 1 }, + { ahc_patch1_func, 248, 1, 2 }, + { ahc_patch0_func, 249, 2, 2 }, + { ahc_patch11_func, 250, 1, 1 }, + { ahc_patch9_func, 258, 31, 3 }, + { ahc_patch1_func, 274, 14, 2 }, + { ahc_patch13_func, 279, 1, 1 }, + { ahc_patch14_func, 289, 14, 1 }, + { ahc_patch1_func, 305, 1, 2 }, + { ahc_patch0_func, 306, 1, 1 }, + { ahc_patch9_func, 309, 1, 1 }, + { ahc_patch13_func, 314, 1, 1 }, + { ahc_patch9_func, 315, 2, 2 }, + { ahc_patch0_func, 317, 4, 1 }, + { ahc_patch14_func, 321, 1, 1 }, + { ahc_patch15_func, 324, 2, 3 }, + { ahc_patch9_func, 324, 1, 2 }, + { ahc_patch0_func, 325, 1, 1 }, + { ahc_patch6_func, 330, 1, 2 }, + { ahc_patch0_func, 331, 1, 1 }, + { ahc_patch1_func, 335, 50, 11 }, + { ahc_patch6_func, 344, 2, 4 }, + { ahc_patch7_func, 344, 1, 1 }, + { ahc_patch8_func, 345, 1, 1 }, + { ahc_patch0_func, 346, 1, 1 }, + { ahc_patch16_func, 347, 1, 1 }, + { ahc_patch6_func, 366, 6, 3 }, + { ahc_patch16_func, 366, 5, 1 }, + { ahc_patch0_func, 372, 5, 1 }, + { ahc_patch13_func, 380, 5, 1 }, + { ahc_patch0_func, 385, 54, 17 }, + { ahc_patch14_func, 385, 1, 1 }, + { ahc_patch7_func, 387, 2, 2 }, + { ahc_patch17_func, 388, 1, 1 }, + { ahc_patch9_func, 391, 1, 1 }, + { ahc_patch18_func, 398, 1, 1 }, + { ahc_patch14_func, 403, 9, 3 }, + { ahc_patch9_func, 404, 3, 2 }, + { ahc_patch0_func, 407, 3, 1 }, + { ahc_patch9_func, 415, 6, 2 }, + { ahc_patch0_func, 421, 9, 2 }, + { ahc_patch13_func, 421, 1, 1 }, + { ahc_patch13_func, 430, 2, 1 }, + { ahc_patch14_func, 432, 1, 1 }, + { ahc_patch9_func, 434, 1, 2 }, + { ahc_patch0_func, 435, 1, 1 }, + { ahc_patch7_func, 438, 1, 1 }, + { ahc_patch7_func, 439, 1, 1 }, + { ahc_patch8_func, 440, 3, 3 }, + { ahc_patch6_func, 441, 1, 2 }, + { ahc_patch0_func, 442, 1, 1 }, + { ahc_patch9_func, 443, 1, 1 }, + { ahc_patch15_func, 444, 1, 2 }, + { ahc_patch13_func, 444, 1, 1 }, + { ahc_patch14_func, 446, 9, 4 }, + { ahc_patch9_func, 446, 1, 1 }, + { ahc_patch9_func, 453, 2, 1 }, + { ahc_patch0_func, 455, 4, 3 }, + { ahc_patch9_func, 455, 1, 2 }, + { ahc_patch0_func, 456, 3, 1 }, + { ahc_patch1_func, 460, 2, 1 }, + { ahc_patch7_func, 462, 10, 2 }, + { ahc_patch0_func, 472, 1, 1 }, + { ahc_patch8_func, 473, 118, 22 }, + { ahc_patch1_func, 475, 3, 2 }, + { ahc_patch0_func, 478, 5, 3 }, + { ahc_patch9_func, 478, 2, 2 }, + { ahc_patch0_func, 480, 3, 1 }, + { ahc_patch1_func, 485, 2, 2 }, + { ahc_patch0_func, 487, 6, 3 }, + { ahc_patch9_func, 487, 2, 2 }, + { ahc_patch0_func, 489, 3, 1 }, + { ahc_patch1_func, 495, 2, 2 }, + { ahc_patch0_func, 497, 9, 7 }, + { ahc_patch9_func, 497, 5, 6 }, + { ahc_patch19_func, 497, 1, 2 }, + { ahc_patch0_func, 498, 1, 1 }, + { ahc_patch19_func, 500, 1, 2 }, + { ahc_patch0_func, 501, 1, 1 }, + { ahc_patch0_func, 502, 4, 1 }, + { ahc_patch6_func, 507, 3, 2 }, + { ahc_patch0_func, 510, 1, 1 }, + { ahc_patch6_func, 520, 1, 2 }, + { ahc_patch0_func, 521, 1, 1 }, + { ahc_patch20_func, 558, 7, 1 }, + { ahc_patch3_func, 593, 1, 2 }, + { ahc_patch0_func, 594, 1, 1 }, + { ahc_patch21_func, 597, 1, 1 }, + { ahc_patch8_func, 599, 106, 33 }, + { ahc_patch4_func, 601, 1, 1 }, + { ahc_patch1_func, 607, 2, 2 }, + { ahc_patch0_func, 609, 1, 1 }, + { ahc_patch1_func, 612, 1, 2 }, + { ahc_patch0_func, 613, 1, 1 }, + { ahc_patch9_func, 614, 3, 3 }, + { ahc_patch15_func, 615, 1, 1 }, + { ahc_patch0_func, 617, 4, 1 }, + { ahc_patch19_func, 626, 2, 2 }, + { ahc_patch0_func, 628, 1, 1 }, + { ahc_patch19_func, 632, 10, 3 }, + { ahc_patch5_func, 634, 8, 1 }, + { ahc_patch0_func, 642, 9, 2 }, + { ahc_patch5_func, 643, 8, 1 }, + { ahc_patch4_func, 653, 1, 2 }, + { ahc_patch0_func, 654, 1, 1 }, + { ahc_patch19_func, 655, 1, 2 }, + { ahc_patch0_func, 656, 3, 2 }, + { ahc_patch4_func, 658, 1, 1 }, + { ahc_patch5_func, 659, 1, 1 }, + { ahc_patch5_func, 662, 1, 1 }, + { ahc_patch5_func, 664, 1, 1 }, + { ahc_patch4_func, 666, 2, 2 }, + { ahc_patch0_func, 668, 2, 1 }, + { ahc_patch5_func, 670, 1, 1 }, + { ahc_patch5_func, 673, 1, 1 }, + { ahc_patch5_func, 676, 1, 1 }, + { ahc_patch19_func, 680, 1, 1 }, + { ahc_patch19_func, 683, 1, 1 }, + { ahc_patch4_func, 689, 1, 1 }, + { ahc_patch6_func, 692, 1, 2 }, + { ahc_patch0_func, 693, 1, 1 }, + { ahc_patch7_func, 705, 16, 1 }, + { ahc_patch4_func, 721, 20, 1 }, + { ahc_patch9_func, 742, 4, 2 }, + { ahc_patch0_func, 746, 4, 1 }, + { ahc_patch9_func, 750, 4, 2 }, + { ahc_patch0_func, 754, 3, 1 }, + { ahc_patch6_func, 760, 1, 1 }, + { ahc_patch22_func, 762, 14, 1 }, + { ahc_patch7_func, 776, 3, 1 }, + { ahc_patch9_func, 788, 24, 8 }, + { ahc_patch19_func, 792, 1, 2 }, + { ahc_patch0_func, 793, 1, 1 }, + { ahc_patch15_func, 798, 4, 2 }, + { ahc_patch0_func, 802, 7, 3 }, + { ahc_patch23_func, 802, 5, 2 }, + { ahc_patch0_func, 807, 2, 1 }, + { ahc_patch0_func, 812, 42, 3 }, + { ahc_patch18_func, 824, 18, 2 }, + { ahc_patch0_func, 842, 1, 1 }, + { ahc_patch4_func, 866, 1, 1 }, + { ahc_patch4_func, 867, 3, 2 }, + { ahc_patch0_func, 870, 1, 1 }, + { ahc_patch13_func, 871, 3, 1 }, + { ahc_patch4_func, 874, 12, 1 } }; + static struct cs { - u_int16_t begin; - u_int16_t end; + uint16_t begin; + uint16_t end; } critical_sections[] = { { 11, 18 }, { 21, 30 }, - { 706, 722 }, - { 852, 855 }, - { 859, 865 }, - { 867, 869 }, - { 869, 871 } + { 721, 737 }, + { 867, 870 }, + { 874, 880 }, + { 882, 884 }, + { 884, 886 } }; + static const int num_critical_sections = sizeof(critical_sections) / sizeof(*critical_sections); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm.c --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm.c 2003-01-22 22:10:29.000000000 +0000 @@ -2,7 +2,7 @@ * Aic7xxx SCSI host adapter firmware asssembler * * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#15 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.c,v 1.29 2000/10/05 04:25:42 gibbs Exp $ + * $FreeBSD$ */ #include #include @@ -85,12 +85,15 @@ struct path_list search_path; int includes_search_curdir; char *appname; +char *stock_include_file; FILE *ofile; char *ofilename; char *regfilename; FILE *regfile; char *listfilename; FILE *listfile; +char *regdiagfilename; +FILE *regdiagfile; int src_mode; int dst_mode; @@ -140,7 +143,7 @@ yydebug = 0; mmdebug = 0; #endif - while ((ch = getopt(argc, argv, "d:l:n:o:r:I:O:")) != -1) { + while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) { switch(ch) { case 'd': #if DEBUG @@ -160,6 +163,9 @@ "information", EX_SOFTWARE); #endif break; + case 'i': + stock_include_file = optarg; + break; case 'l': /* Create a program listing */ if ((listfile = fopen(optarg, "w")) == NULL) { @@ -184,6 +190,14 @@ } ofilename = optarg; break; + case 'p': + /* Create Register Diagnostic "printing" Functions */ + if ((regdiagfile = fopen(optarg, "w")) == NULL) { + perror(optarg); + stop(NULL, EX_CANTCREAT); + } + regdiagfilename = optarg; + break; case 'r': if ((regfile = fopen(optarg, "w")) == NULL) { perror(optarg); @@ -245,6 +259,14 @@ /* NOTREACHED */ } + if (regdiagfile != NULL + && (regfile == NULL || stock_include_file == NULL)) { + fprintf(stderr, + "%s: The -p option requires the -r and -i options.\n", + appname); + usage(); + /* NOTREACHED */ + } symtable_open(); inputfilename = *argv; include_file(*argv, SOURCE_FILE); @@ -271,9 +293,8 @@ if (ofile != NULL) output_code(); - if (regfile != NULL) { - symtable_dump(regfile); - } + if (regfile != NULL) + symtable_dump(regfile, regdiagfile); if (listfile != NULL) output_listing(inputfilename); } @@ -288,10 +309,10 @@ { (void)fprintf(stderr, -"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file] - [-r register_output_file] [-l program_list_file] - input_file\n", - appname); +"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n" +" [-r register_output_file [-p register_diag_file -i includefile]]\n" +" [-l program_list_file]\n" +" input_file\n", appname); exit(EX_USAGE); } @@ -335,11 +356,11 @@ instrcount = 0; fprintf(ofile, -"/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * -%s */\n", versions); +"/*\n" +" * DO NOT EDIT - This file is automatically generated\n" +" * from the following source files:\n" +" *\n" +"%s */\n", versions); fprintf(ofile, "static uint8_t seqprog[] = {\n"); for (cur_instr = STAILQ_FIRST(&seq_program); @@ -370,49 +391,54 @@ /* * Output patch information. Patch functions first. */ + fprintf(ofile, +"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list); + for (cur_node = SLIST_FIRST(&patch_functions); cur_node != NULL; cur_node = SLIST_NEXT(cur_node,links)) { fprintf(ofile, -"static int aic_patch%d_func(%s); - -static int -aic_patch%d_func(%s) -{ - return (%s); -}\n\n", +"static %spatch_func_t %spatch%d_func;\n" +"\n" +"static int\n" +"%spatch%d_func(%s)\n" +"{\n" +" return (%s);\n" +"}\n\n", + prefix, + prefix, cur_node->symbol->info.condinfo->func_num, - patch_arg_list, + prefix, cur_node->symbol->info.condinfo->func_num, patch_arg_list, cur_node->symbol->name); } fprintf(ofile, -"typedef int patch_func_t (%s); -static struct patch { - patch_func_t *patch_func; - uint32_t begin :10, - skip_instr :10, - skip_patch :12; -} patches[] = {\n", patch_arg_list); +"static struct patch {\n" +" %spatch_func_t *patch_func;\n" +" uint32_t begin :10,\n" +" skip_instr :10,\n" +" skip_patch :12;\n" +"} patches[] = {\n", prefix); for (cur_patch = STAILQ_FIRST(&patches); cur_patch != NULL; cur_patch = STAILQ_NEXT(cur_patch,links)) { - fprintf(ofile, "%s\t{ aic_patch%d_func, %d, %d, %d }", + fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }", cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n", + prefix, cur_patch->patch_func, cur_patch->begin, cur_patch->skip_instr, cur_patch->skip_patch); } - fprintf(ofile, "\n};\n"); + fprintf(ofile, "\n};\n\n"); fprintf(ofile, -"static struct cs { - u_int16_t begin; - u_int16_t end; -} critical_sections[] = {\n"); +"static struct cs {\n" +" uint16_t begin;\n" +" uint16_t end;\n" +"} critical_sections[] = {\n"); for (cs = TAILQ_FIRST(&cs_tailq); cs != NULL; @@ -422,11 +448,11 @@ cs->begin_addr, cs->end_addr); } - fprintf(ofile, "\n};\n"); + fprintf(ofile, "\n};\n\n"); fprintf(ofile, -"static const int num_critical_sections = sizeof(critical_sections) - / sizeof(*critical_sections);\n"); +"static const int num_critical_sections = sizeof(critical_sections)\n" +" / sizeof(*critical_sections);\n"); fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 2003-01-22 22:10:29.000000000 +0000 @@ -3,7 +3,7 @@ * Parser for the Aic7xxx SCSI Host adapter sequencer assembler. * * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#14 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_gram.y,v 1.12 2000/10/31 18:44:32 gibbs Exp $ + * $FreeBSD$ */ #include @@ -64,11 +64,14 @@ int yylineno; char *yyfilename; +char stock_prefix[] = "aic_"; +char *prefix = stock_prefix; char *patch_arg_list; char *versions; static char errbuf[255]; static char regex_pattern[255]; static symbol_t *cur_symbol; +static symbol_t *field_symbol; static symbol_t *scb_or_sram_symbol; static symtype cur_symtype; static symbol_ref_t accumulator; @@ -82,8 +85,10 @@ static int sram_or_scb_offset; static int download_constant_count; static int in_critical_section; +static u_int enum_increment; +static u_int enum_next_value; -static void process_bitmask(int mask_type, symbol_t *sym, int mask); +static void process_field(int field_type, symbol_t *sym, int mask); static void initialize_symbol(symbol_t *symbol); static void add_macro_arg(const char *argtext, int position); static void add_macro_body(const char *bodytext); @@ -152,7 +157,9 @@ %token T_END_CS -%token T_BIT +%token T_FIELD + +%token T_ENUM %token T_MASK @@ -162,7 +169,7 @@ %token T_CEXPR -%token T_EOF T_INCLUDE T_VERSION T_PATCH_ARG_LIST +%token T_EOF T_INCLUDE T_VERSION T_PREFIX T_PATCH_ARG_LIST %token T_SHR T_SHL T_ROR T_ROL @@ -202,7 +209,7 @@ %type export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne -%type numerical_value mode_value mode_list macro_arglist +%type mode_value mode_list macro_arglist %left '|' %left '&' @@ -216,6 +223,8 @@ program: include | program include +| prefix +| program prefix | patch_arg_list | program patch_arg_list | version @@ -257,6 +266,18 @@ } ; +prefix: + T_PREFIX '=' T_STRING + { + if (prefix != stock_prefix) + stop("Prefix multiply defined", + EX_DATAERR); + prefix = strdup($3); + if (prefix == NULL) + stop("Unable to record prefix", EX_SOFTWARE); + } +; + patch_arg_list: T_PATCH_ARG_LIST '=' T_STRING { @@ -326,7 +347,8 @@ | size | access_mode | modes -| bit_defn +| field_defn +| enum_defn | mask_defn | alias | accumulator @@ -418,17 +440,68 @@ } ; -bit_defn: - T_BIT T_SYMBOL T_NUMBER +field_defn: + T_FIELD + { + field_symbol = NULL; + enum_next_value = 0; + enum_increment = 1; + } + '{' enum_entry_list '}' +| T_FIELD T_SYMBOL expression + { + process_field(FIELD, $2, $3.value); + field_symbol = $2; + enum_next_value = 0; + enum_increment = 0x01 << (ffs($3.value) - 1); + } + '{' enum_entry_list '}' +| T_FIELD T_SYMBOL expression + { + process_field(FIELD, $2, $3.value); + } +; + +enum_defn: + T_ENUM + { + field_symbol = NULL; + enum_next_value = 0; + enum_increment = 1; + } + '{' enum_entry_list '}' +| T_ENUM T_SYMBOL expression + { + process_field(ENUM, $2, $3.value); + field_symbol = $2; + enum_next_value = 0; + enum_increment = 0x01 << (ffs($3.value) - 1); + } + '{' enum_entry_list '}' +; + +enum_entry_list: + enum_entry +| enum_entry_list ',' enum_entry +; + +enum_entry: + T_SYMBOL { - process_bitmask(BIT, $2, $3); + process_field(ENUM_ENTRY, $1, enum_next_value); + enum_next_value += enum_increment; + } +| T_SYMBOL expression + { + process_field(ENUM_ENTRY, $1, $2.value); + enum_next_value = $2.value + enum_increment; } ; mask_defn: T_MASK T_SYMBOL expression { - process_bitmask(MASK, $2, $3.value); + process_field(MASK, $2, $3.value); } ; @@ -608,8 +681,10 @@ $$.value = symbol->info.rinfo->address; break; case MASK: - case BIT: - $$.value = symbol->info.minfo->mask; + case FIELD: + case ENUM: + case ENUM_ENTRY: + $$.value = symbol->info.finfo->value; break; case DOWNLOAD_CONST: case CONST: @@ -632,7 +707,7 @@ ; constant: - T_CONST T_SYMBOL numerical_value + T_CONST T_SYMBOL expression { if ($2->type != UNINITIALIZED) { stop("Re-definition of symbol as a constant", @@ -641,7 +716,7 @@ } $2->type = CONST; initialize_symbol($2); - $2->info.cinfo->value = $3; + $2->info.cinfo->value = $3.value; } | T_CONST T_SYMBOL T_DOWNLOAD { @@ -709,17 +784,6 @@ } ; -numerical_value: - T_NUMBER - { - $$ = $1; - } -| '-' T_NUMBER - { - $$ = -$2; - } -; - scratch_ram: T_SRAM '{' { @@ -862,6 +926,8 @@ | T_A { SLIST_INIT(&$$.referenced_syms); + symlist_add(&$$.referenced_syms, accumulator.symbol, + SYMLIST_INSERT_HEAD); $$.value = 0; } ; @@ -917,6 +983,7 @@ cs->begin_addr = instruction_ptr; in_critical_section = TRUE; } +; critical_section_end: T_END_CS ';' @@ -931,6 +998,7 @@ cs->end_addr = instruction_ptr; in_critical_section = FALSE; } +; export: { $$ = 0; } @@ -1161,9 +1229,22 @@ ; code: - T_MVI destination ',' immediate_or_a ret ';' + T_MVI destination ',' immediate ret ';' { - format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); + if ($4.value == 0 + && is_download_const(&$4) == 0) { + expression_t immed; + + /* + * Allow move immediates of 0 so that macros, + * that can't know the immediate's value and + * otherwise compensate, still work. + */ + make_expression(&immed, 1); + format_1_instr(AIC_OP_BMOV, &$2, &immed, &allzeros, $5); + } else { + format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); + } } ; @@ -1298,7 +1379,7 @@ %% static void -process_bitmask(int mask_type, symbol_t *sym, int mask) +process_field(int field_type, symbol_t *sym, int value) { /* * Add the current register to its @@ -1308,52 +1389,54 @@ * the "allowed bits" of this register. */ if (sym->type == UNINITIALIZED) { - sym->type = mask_type; + sym->type = field_type; initialize_symbol(sym); - if (mask_type == BIT) { - if (mask == 0) { - stop("Bitmask with no bits set", EX_DATAERR); - /* NOTREACHED */ - } - if ((mask & ~(0x01 << (ffs(mask) - 1))) != 0) { - stop("Bitmask with more than one bit set", - EX_DATAERR); + sym->info.finfo->value = value; + if (field_type != ENUM_ENTRY) { + if (field_type != MASK && value == 0) { + stop("Empty Field, or Enum", EX_DATAERR); /* NOTREACHED */ } + sym->info.finfo->value = value; + sym->info.finfo->mask = value; + } else if (field_symbol != NULL) { + sym->info.finfo->mask = field_symbol->info.finfo->value; + } else { + sym->info.finfo->mask = 0xFF; } - sym->info.minfo->mask = mask; - } else if (sym->type != mask_type) { - stop("Bit definition mirrors a definition of the same " + } else if (sym->type != field_type) { + stop("Field definition mirrors a definition of the same " " name, but a different type", EX_DATAERR); /* NOTREACHED */ - } else if (mask != sym->info.minfo->mask) { - stop("Bitmask redefined with a conflicting value", EX_DATAERR); + } else if (value != sym->info.finfo->value) { + stop("Field redefined with a conflicting value", EX_DATAERR); /* NOTREACHED */ } /* Fail if this symbol is already listed */ - if (symlist_search(&(sym->info.minfo->symrefs), + if (symlist_search(&(sym->info.finfo->symrefs), cur_symbol->name) != NULL) { - stop("Bitmask defined multiple times for register", EX_DATAERR); + stop("Field defined multiple times for register", EX_DATAERR); /* NOTREACHED */ } - symlist_add(&(sym->info.minfo->symrefs), cur_symbol, + symlist_add(&(sym->info.finfo->symrefs), cur_symbol, SYMLIST_INSERT_HEAD); - cur_symbol->info.rinfo->valid_bitmask |= mask; + cur_symbol->info.rinfo->valid_bitmask |= sym->info.finfo->mask; cur_symbol->info.rinfo->typecheck_masks = TRUE; + symlist_add(&(cur_symbol->info.rinfo->fields), sym, SYMLIST_SORT); } static void initialize_symbol(symbol_t *symbol) { switch (symbol->type) { - case UNINITIALIZED: + case UNINITIALIZED: stop("Call to initialize_symbol with type field unset", EX_SOFTWARE); /* NOTREACHED */ break; - case REGISTER: - case SRAMLOC: - case SCBLOC: + case REGISTER: + case SRAMLOC: + case SCBLOC: symbol->info.rinfo = (struct reg_info *)malloc(sizeof(struct reg_info)); if (symbol->info.rinfo == NULL) { @@ -1362,6 +1445,7 @@ } memset(symbol->info.rinfo, 0, sizeof(struct reg_info)); + SLIST_INIT(&(symbol->info.rinfo->fields)); /* * Default to allowing access in all register modes * or to the mode specified by the SCB or SRAM space @@ -1373,7 +1457,7 @@ else symbol->info.rinfo->modes = ~0; break; - case ALIAS: + case ALIAS: symbol->info.ainfo = (struct alias_info *)malloc(sizeof(struct alias_info)); if (symbol->info.ainfo == NULL) { @@ -1383,19 +1467,21 @@ memset(symbol->info.ainfo, 0, sizeof(struct alias_info)); break; - case MASK: - case BIT: - symbol->info.minfo = - (struct mask_info *)malloc(sizeof(struct mask_info)); - if (symbol->info.minfo == NULL) { - stop("Can't create bitmask info", EX_SOFTWARE); + case MASK: + case FIELD: + case ENUM: + case ENUM_ENTRY: + symbol->info.finfo = + (struct field_info *)malloc(sizeof(struct field_info)); + if (symbol->info.finfo == NULL) { + stop("Can't create field info", EX_SOFTWARE); /* NOTREACHED */ } - memset(symbol->info.minfo, 0, sizeof(struct mask_info)); - SLIST_INIT(&(symbol->info.minfo->symrefs)); + memset(symbol->info.finfo, 0, sizeof(struct field_info)); + SLIST_INIT(&(symbol->info.finfo->symrefs)); break; - case CONST: - case DOWNLOAD_CONST: + case CONST: + case DOWNLOAD_CONST: symbol->info.cinfo = (struct const_info *)malloc(sizeof(struct const_info)); if (symbol->info.cinfo == NULL) { @@ -1577,7 +1663,6 @@ case AIC_OP_OR: dst_value = src_value | immed->value; break; - break; case AIC_OP_BMOV: dst_value = src_value; break; @@ -1586,9 +1671,9 @@ } src_mode = dst_value & 0xF; dst_mode = (dst_value >> 4) & 0xF; -cant_update: } +cant_update: symlist_free(&immed->referenced_syms); instruction_ptr++; } @@ -1763,11 +1848,13 @@ node != NULL; node = node->links.sle_next) { if ((node->symbol->type == MASK - || node->symbol->type == BIT) - && symlist_search(&node->symbol->info.minfo->symrefs, + || node->symbol->type == FIELD + || node->symbol->type == ENUM + || node->symbol->type == ENUM_ENTRY) + && symlist_search(&node->symbol->info.finfo->symrefs, symbol->name) == NULL) { snprintf(errbuf, sizeof(errbuf), - "Invalid bit or mask %s " + "Invalid field or mask %s " "for register %s", node->symbol->name, symbol->name); stop(errbuf, EX_DATAERR); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm.h --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm.h 2003-01-22 22:10:29.000000000 +0000 @@ -2,7 +2,7 @@ * Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters * * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#9 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.h,v 1.11 2000/09/22 22:19:54 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -76,8 +76,10 @@ extern struct symlist patch_functions; extern int includes_search_curdir; /* False if we've seen -I- */ extern char *appname; +extern char *stock_include_file; extern int yylineno; extern char *yyfilename; +extern char *prefix; extern char *patch_arg_list; extern char *versions; extern int src_mode; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 2003-01-22 22:10:29.000000000 +0000 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#8 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_insformat.h,v 1.3 2000/09/22 22:19:54 gibbs Exp $ + * $FreeBSD$ */ struct ins_format1 { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 2003-01-22 22:10:29.000000000 +0000 @@ -38,7 +38,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id$ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $ * * $FreeBSD$ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 2003-01-22 22:10:29.000000000 +0000 @@ -38,13 +38,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id$ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 $ * * $FreeBSD$ */ #include +#include #include #include #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 2003-01-22 22:10:29.000000000 +0000 @@ -3,7 +3,7 @@ * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. * * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,13 +38,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#10 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_scan.l,v 1.13.2.3 2001/07/28 18:46:44 gibbs Exp $ + * $FreeBSD$ */ #include +#include #include #include #include @@ -131,6 +132,7 @@ } VERSION { return T_VERSION; } +PREFIX { return T_PREFIX; } PATCH_ARG_LIST { return T_PATCH_ARG_LIST; } \" { string_buf_ptr = string_buf; @@ -173,7 +175,8 @@ END_CRITICAL { return T_END_CS; } SET_SRC_MODE { return T_SET_SRC_MODE; } SET_DST_MODE { return T_SET_DST_MODE; } -bit { return T_BIT; } +field { return T_FIELD; } +enum { return T_ENUM; } mask { return T_MASK; } alias { return T_ALIAS; } size { return T_SIZE; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 2003-01-22 22:10:29.000000000 +0000 @@ -2,6 +2,7 @@ * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation * * Copyright (c) 1997 Justin T. Gibbs. + * Copyright (c) 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#13 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.11 2000/09/22 22:19:54 gibbs Exp $ + * $FreeBSD$ */ #include @@ -49,6 +50,7 @@ #include #endif #include +#include #include #include #include @@ -72,6 +74,8 @@ } memset(new_symbol, 0, sizeof(*new_symbol)); new_symbol->name = strdup(name); + if (new_symbol->name == NULL) + stop("Unable to strdup symbol name", EX_SOFTWARE); new_symbol->type = UNINITIALIZED; return (new_symbol); } @@ -98,10 +102,12 @@ free(symbol->info.ainfo); break; case MASK: - case BIT: - if (symbol->info.minfo != NULL) { - symlist_free(&symbol->info.minfo->symrefs); - free(symbol->info.minfo); + case FIELD: + case ENUM: + case ENUM_ENTRY: + if (symbol->info.finfo != NULL) { + symlist_free(&symbol->info.finfo->symrefs); + free(symbol->info.finfo); } break; case DOWNLOAD_CONST: @@ -222,17 +228,19 @@ newnode->symbol = symbol; if (how == SYMLIST_SORT) { symbol_node_t *curnode; - int mask; + int field; - mask = FALSE; + field = FALSE; switch(symbol->type) { case REGISTER: case SCBLOC: case SRAMLOC: break; - case BIT: + case FIELD: case MASK: - mask = TRUE; + case ENUM: + case ENUM_ENTRY: + field = TRUE; break; default: stop("symlist_add: Invalid symbol type for sorting", @@ -242,9 +250,12 @@ curnode = SLIST_FIRST(symlist); if (curnode == NULL - || (mask && (curnode->symbol->info.minfo->mask > - newnode->symbol->info.minfo->mask)) - || (!mask && (curnode->symbol->info.rinfo->address > + || (field + && (curnode->symbol->type > newnode->symbol->type + || (curnode->symbol->type == newnode->symbol->type + && (curnode->symbol->info.finfo->value > + newnode->symbol->info.finfo->value)))) + || (!field && (curnode->symbol->info.rinfo->address > newnode->symbol->info.rinfo->address))) { SLIST_INSERT_HEAD(symlist, newnode, links); return; @@ -259,10 +270,14 @@ symbol_t *cursymbol; cursymbol = SLIST_NEXT(curnode, links)->symbol; - if ((mask && (cursymbol->info.minfo->mask > - symbol->info.minfo->mask)) - || (!mask &&(cursymbol->info.rinfo->address > - symbol->info.rinfo->address))){ + if ((field + && (cursymbol->type > symbol->type + || (cursymbol->type == symbol->type + && (cursymbol->info.finfo->value > + symbol->info.finfo->value)))) + || (!field + && (cursymbol->info.rinfo->address > + symbol->info.rinfo->address))) { SLIST_INSERT_AFTER(curnode, newnode, links); break; @@ -307,20 +322,160 @@ } void -symtable_dump(FILE *ofile) +aic_print_file_prologue(FILE *ofile) +{ + + if (ofile == NULL) + return; + + fprintf(ofile, +"/*\n" +" * DO NOT EDIT - This file is automatically generated\n" +" * from the following source files:\n" +" *\n" +"%s */\n", + versions); +} + +void +aic_print_include(FILE *dfile, char *include_file) +{ + + if (dfile == NULL) + return; + fprintf(dfile, "\n#include \"%s\"\n\n", include_file); +} + +void +aic_print_reg_dump_types(FILE *ofile) +{ + if (ofile == NULL) + return; + + fprintf(ofile, +"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" +"typedef struct %sreg_parse_entry {\n" +" char *name;\n" +" uint8_t value;\n" +" uint8_t mask;\n" +"} %sreg_parse_entry_t;\n" +"\n", + prefix, prefix, prefix); +} + +static void +aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) +{ + if (dfile == NULL) + return; + + fprintf(dfile, +"static %sreg_parse_entry_t %s_parse_table[] = {\n", + prefix, + regnode->symbol->name); +} + +static void +aic_print_reg_dump_end(FILE *ofile, FILE *dfile, + symbol_node_t *regnode, u_int num_entries) +{ + char *lower_name; + char *letter; + + lower_name = strdup(regnode->symbol->name); + if (lower_name == NULL) + stop("Unable to strdup symbol name", EX_SOFTWARE); + + for (letter = lower_name; *letter != '\0'; letter++) + *letter = tolower(*letter); + + if (dfile != NULL) { + if (num_entries != 0) + fprintf(dfile, +"\n" +"};\n" +"\n"); + + fprintf(dfile, +"int\n" +"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" +"{\n" +" return (%sprint_register(%s%s, %d, \"%s\",\n" +" 0x%02x, regvalue, cur_col, wrap));\n" +"}\n" +"\n", + prefix, + lower_name, + prefix, + num_entries != 0 ? regnode->symbol->name : "NULL", + num_entries != 0 ? "_parse_table" : "", + num_entries, + regnode->symbol->name, + regnode->symbol->info.rinfo->address); + } + + fprintf(ofile, +"#if AIC_DEBUG_REGISTERS\n" +"%sreg_print_t %s%s_print;\n" +"#else\n" +"#define %s%s_print(regvalue, cur_col, wrap) \\\n" +" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" +"#endif\n" +"\n", + prefix, + prefix, + lower_name, + prefix, + lower_name, + prefix, + regnode->symbol->name, + regnode->symbol->info.rinfo->address); +} + +static void +aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) +{ + int num_tabs; + + if (dfile == NULL) + return; + + fprintf(dfile, +" { \"%s\",", + curnode->symbol->name); + + num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; + + while (num_tabs-- > 0) + fputc('\t', dfile); + fprintf(dfile, "0x%02x, 0x%02x }", + curnode->symbol->info.finfo->value, + curnode->symbol->info.finfo->mask); +} + +void +symtable_dump(FILE *ofile, FILE *dfile) { /* * Sort the registers by address with a simple insertion sort. * Put bitmasks next to the first register that defines them. * Put constants at the end. */ - symlist_t registers; - symlist_t masks; - symlist_t constants; - symlist_t download_constants; - symlist_t aliases; - symlist_t exported_labels; - u_int i; + symlist_t registers; + symlist_t masks; + symlist_t constants; + symlist_t download_constants; + symlist_t aliases; + symlist_t exported_labels; + symbol_node_t *curnode; + symbol_node_t *regnode; + DBT key; + DBT data; + int flag; + u_int i; + + if (symtable == NULL) + return; SLIST_INIT(®isters); SLIST_INIT(&masks); @@ -328,173 +483,195 @@ SLIST_INIT(&download_constants); SLIST_INIT(&aliases); SLIST_INIT(&exported_labels); + flag = R_FIRST; + while (symtable->seq(symtable, &key, &data, flag) == 0) { + symbol_t *cursym; - if (symtable != NULL) { - DBT key; - DBT data; - int flag = R_FIRST; + memcpy(&cursym, data.data, sizeof(cursym)); + switch(cursym->type) { + case REGISTER: + case SCBLOC: + case SRAMLOC: + symlist_add(®isters, cursym, SYMLIST_SORT); + break; + case MASK: + case FIELD: + case ENUM: + case ENUM_ENTRY: + symlist_add(&masks, cursym, SYMLIST_SORT); + break; + case CONST: + symlist_add(&constants, cursym, + SYMLIST_INSERT_HEAD); + break; + case DOWNLOAD_CONST: + symlist_add(&download_constants, cursym, + SYMLIST_INSERT_HEAD); + break; + case ALIAS: + symlist_add(&aliases, cursym, + SYMLIST_INSERT_HEAD); + break; + case LABEL: + if (cursym->info.linfo->exported == 0) + break; + symlist_add(&exported_labels, cursym, + SYMLIST_INSERT_HEAD); + break; + default: + break; + } + flag = R_NEXT; + } - while (symtable->seq(symtable, &key, &data, flag) == 0) { - symbol_t *cursym; + /* Register dianostic functions/declarations first. */ + aic_print_file_prologue(ofile); + aic_print_reg_dump_types(ofile); + aic_print_file_prologue(dfile); + aic_print_include(dfile, stock_include_file); + SLIST_FOREACH(curnode, ®isters, links) { - memcpy(&cursym, data.data, sizeof(cursym)); - switch(cursym->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - symlist_add(®isters, cursym, SYMLIST_SORT); - break; - case MASK: - case BIT: - symlist_add(&masks, cursym, SYMLIST_SORT); - break; - case CONST: - symlist_add(&constants, cursym, - SYMLIST_INSERT_HEAD); - break; - case DOWNLOAD_CONST: - symlist_add(&download_constants, cursym, - SYMLIST_INSERT_HEAD); - break; - case ALIAS: - symlist_add(&aliases, cursym, - SYMLIST_INSERT_HEAD); - break; - case LABEL: - if (cursym->info.linfo->exported == 0) - break; - symlist_add(&exported_labels, cursym, - SYMLIST_INSERT_HEAD); - break; - default: - break; + switch(curnode->symbol->type) { + case REGISTER: + case SCBLOC: + case SRAMLOC: + { + symlist_t *fields; + symbol_node_t *fieldnode; + int num_entries; + + num_entries = 0; + fields = &curnode->symbol->info.rinfo->fields; + SLIST_FOREACH(fieldnode, fields, links) { + if (num_entries == 0) + aic_print_reg_dump_start(dfile, + curnode); + else if (dfile != NULL) + fputs(",\n", dfile); + num_entries++; + aic_print_reg_dump_entry(dfile, fieldnode); } - flag = R_NEXT; + aic_print_reg_dump_end(ofile, dfile, + curnode, num_entries); + } + default: + break; } + } - /* Put in the masks and bits */ - while (SLIST_FIRST(&masks) != NULL) { - symbol_node_t *curnode; - symbol_node_t *regnode; - char *regname; + /* Fold in the masks and bits */ + while (SLIST_FIRST(&masks) != NULL) { + char *regname; - curnode = SLIST_FIRST(&masks); - SLIST_REMOVE_HEAD(&masks, links); + curnode = SLIST_FIRST(&masks); + SLIST_REMOVE_HEAD(&masks, links); - regnode = - SLIST_FIRST(&curnode->symbol->info.minfo->symrefs); - regname = regnode->symbol->name; - regnode = symlist_search(®isters, regname); - SLIST_INSERT_AFTER(regnode, curnode, links); - } + regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); + regname = regnode->symbol->name; + regnode = symlist_search(®isters, regname); + SLIST_INSERT_AFTER(regnode, curnode, links); + } - /* Add the aliases */ - while (SLIST_FIRST(&aliases) != NULL) { - symbol_node_t *curnode; - symbol_node_t *regnode; - char *regname; + /* Add the aliases */ + while (SLIST_FIRST(&aliases) != NULL) { + char *regname; - curnode = SLIST_FIRST(&aliases); - SLIST_REMOVE_HEAD(&aliases, links); + curnode = SLIST_FIRST(&aliases); + SLIST_REMOVE_HEAD(&aliases, links); - regname = curnode->symbol->info.ainfo->parent->name; - regnode = symlist_search(®isters, regname); - SLIST_INSERT_AFTER(regnode, curnode, links); - } + regname = curnode->symbol->info.ainfo->parent->name; + regnode = symlist_search(®isters, regname); + SLIST_INSERT_AFTER(regnode, curnode, links); + } - /* Output what we have */ - fprintf(ofile, -"/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * -%s */\n", versions); - while (SLIST_FIRST(®isters) != NULL) { - symbol_node_t *curnode; - u_int value; - char *tab_str; - char *tab_str2; - - curnode = SLIST_FIRST(®isters); - SLIST_REMOVE_HEAD(®isters, links); - switch(curnode->symbol->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - fprintf(ofile, "\n"); - value = curnode->symbol->info.rinfo->address; - tab_str = "\t"; - tab_str2 = "\t\t"; - break; - case ALIAS: - { - symbol_t *parent; - - parent = curnode->symbol->info.ainfo->parent; - value = parent->info.rinfo->address; - tab_str = "\t"; - tab_str2 = "\t\t"; - break; - } - case MASK: - case BIT: - value = curnode->symbol->info.minfo->mask; - tab_str = "\t\t"; - tab_str2 = "\t"; - break; - default: - value = 0; /* Quiet compiler */ - tab_str = NULL; - tab_str2 = NULL; - stop("symtable_dump: Invalid symbol type " - "encountered", EX_SOFTWARE); - break; - } - fprintf(ofile, "#define%s%-16s%s0x%02x\n", - tab_str, curnode->symbol->name, tab_str2, - value); - free(curnode); - } - fprintf(ofile, "\n\n"); - - while (SLIST_FIRST(&constants) != NULL) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&constants); - SLIST_REMOVE_HEAD(&constants, links); - fprintf(ofile, "#define\t%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.cinfo->value); - free(curnode); + /* Output generated #defines. */ + while (SLIST_FIRST(®isters) != NULL) { + symbol_node_t *curnode; + u_int value; + char *tab_str; + char *tab_str2; + + curnode = SLIST_FIRST(®isters); + SLIST_REMOVE_HEAD(®isters, links); + switch(curnode->symbol->type) { + case REGISTER: + case SCBLOC: + case SRAMLOC: + fprintf(ofile, "\n"); + value = curnode->symbol->info.rinfo->address; + tab_str = "\t"; + tab_str2 = "\t\t"; + break; + case ALIAS: + { + symbol_t *parent; + + parent = curnode->symbol->info.ainfo->parent; + value = parent->info.rinfo->address; + tab_str = "\t"; + tab_str2 = "\t\t"; + break; } + case MASK: + case FIELD: + case ENUM: + case ENUM_ENTRY: + value = curnode->symbol->info.finfo->value; + tab_str = "\t\t"; + tab_str2 = "\t"; + break; + default: + value = 0; /* Quiet compiler */ + tab_str = NULL; + tab_str2 = NULL; + stop("symtable_dump: Invalid symbol type " + "encountered", EX_SOFTWARE); + break; + } + fprintf(ofile, "#define%s%-16s%s0x%02x\n", + tab_str, curnode->symbol->name, tab_str2, + value); + free(curnode); + } + fprintf(ofile, "\n\n"); - - fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); + while (SLIST_FIRST(&constants) != NULL) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&constants); + SLIST_REMOVE_HEAD(&constants, links); + fprintf(ofile, "#define\t%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.cinfo->value); + free(curnode); + } - for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { - symbol_node_t *curnode; + + fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); - curnode = SLIST_FIRST(&download_constants); - SLIST_REMOVE_HEAD(&download_constants, links); - fprintf(ofile, "#define\t%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.cinfo->value); - free(curnode); - } - fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); - - fprintf(ofile, "\n\n/* Exported Labels */\n"); - - while (SLIST_FIRST(&exported_labels) != NULL) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&exported_labels); - SLIST_REMOVE_HEAD(&exported_labels, links); - fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.linfo->address); - free(curnode); - } + for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&download_constants); + SLIST_REMOVE_HEAD(&download_constants, links); + fprintf(ofile, "#define\t%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.cinfo->value); + free(curnode); + } + fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); + + fprintf(ofile, "\n\n/* Exported Labels */\n"); + + while (SLIST_FIRST(&exported_labels) != NULL) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&exported_labels); + SLIST_REMOVE_HEAD(&exported_labels, links); + fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.linfo->address); + free(curnode); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h --- linux.21pre4/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 2003-01-22 22:10:29.000000000 +0000 @@ -2,6 +2,7 @@ * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions * * Copyright (c) 1997 Justin T. Gibbs. + * Copyright (c) 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#10 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.h,v 1.11 2000/09/22 22:19:55 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -53,8 +54,10 @@ ALIAS, SCBLOC, SRAMLOC, + ENUM_ENTRY, + FIELD, MASK, - BIT, + ENUM, CONST, DOWNLOAD_CONST, LABEL, @@ -68,20 +71,22 @@ RW = 0x03 }amode_t; +typedef SLIST_HEAD(symlist, symbol_node) symlist_t; + struct reg_info { - u_int address; - int size; - amode_t mode; - u_int8_t valid_bitmask; - u_int8_t modes; - int typecheck_masks; + u_int address; + int size; + amode_t mode; + symlist_t fields; + uint8_t valid_bitmask; + uint8_t modes; + int typecheck_masks; }; -typedef SLIST_HEAD(symlist, symbol_node) symlist_t; - -struct mask_info { +struct field_info { symlist_t symrefs; - u_int8_t mask; + uint8_t value; + uint8_t mask; }; struct const_info { @@ -125,7 +130,7 @@ symtype type; union { struct reg_info *rinfo; - struct mask_info *minfo; + struct field_info *finfo; struct const_info *cinfo; struct alias_info *ainfo; struct label_info *linfo; @@ -178,25 +183,25 @@ SLIST_HEAD(scope_list, scope); TAILQ_HEAD(scope_tailq, scope); -void symbol_delete __P((symbol_t *symbol)); +void symbol_delete(symbol_t *symbol); -void symtable_open __P((void)); +void symtable_open(void); -void symtable_close __P((void)); +void symtable_close(void); symbol_t * - symtable_get __P((char *name)); + symtable_get(char *name); symbol_node_t * - symlist_search __P((symlist_t *symlist, char *symname)); + symlist_search(symlist_t *symlist, char *symname); void - symlist_add __P((symlist_t *symlist, symbol_t *symbol, int how)); + symlist_add(symlist_t *symlist, symbol_t *symbol, int how); #define SYMLIST_INSERT_HEAD 0x00 #define SYMLIST_SORT 0x01 -void symlist_free __P((symlist_t *symlist)); +void symlist_free(symlist_t *symlist); -void symlist_merge __P((symlist_t *symlist_dest, symlist_t *symlist_src1, - symlist_t *symlist_src2)); -void symtable_dump __P((FILE *ofile)); +void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, + symlist_t *symlist_src2); +void symtable_dump(FILE *ofile, FILE *dfile); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aiclib.c linux.21pre4-ac6/drivers/scsi/aic7xxx/aiclib.c --- linux.21pre4/drivers/scsi/aic7xxx/aiclib.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aiclib.c 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,1335 @@ +/* + * Implementation of Utility functions for all SCSI device types. + * + * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. + * Copyright (c) 1997, 1998 Kenneth D. Merry. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $ + * $Id$ + */ + +#include +#include +#include +#include + +/* Core SCSI definitions */ +#include "scsi.h" +#include "hosts.h" +#include "aiclib.h" +#include "cam.h" + +#ifndef FALSE +#define FALSE 0 +#endif /* FALSE */ +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef ERESTART +#define ERESTART -1 /* restart syscall */ +#endif +#ifndef EJUSTRETURN +#define EJUSTRETURN -2 /* don't modify regs, just return */ +#endif + +static int ascentrycomp(const void *key, const void *member); +static int senseentrycomp(const void *key, const void *member); +static void fetchtableentries(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *, + const struct sense_key_table_entry **, + const struct asc_table_entry **); +static void * scsibsearch(const void *key, const void *base, size_t nmemb, + size_t size, + int (*compar)(const void *, const void *)); +typedef int (cam_quirkmatch_t)(caddr_t, caddr_t); +static int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, + int str_len); +static caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, + int num_entries, int entry_size, + cam_quirkmatch_t *comp_func); + +#define SCSI_NO_SENSE_STRINGS 1 +#if !defined(SCSI_NO_SENSE_STRINGS) +#define SST(asc, ascq, action, desc) \ + asc, ascq, action, desc +#else +static const char empty_string[] = ""; + +#define SST(asc, ascq, action, desc) \ + asc, ascq, action, empty_string +#endif + +static const struct sense_key_table_entry sense_key_table[] = +{ + { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" }, + { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" }, + { + SSD_KEY_NOT_READY, SS_TUR|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, + "NOT READY" + }, + { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" }, + { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" }, + { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" }, + { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" }, + { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" }, + { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" }, + { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" }, + { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" }, + { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" }, + { SSD_KEY_EQUAL, SS_NOP, "EQUAL" }, + { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" }, + { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" }, + { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" } +}; + +static const int sense_key_table_size = + sizeof(sense_key_table)/sizeof(sense_key_table[0]); + +static struct asc_table_entry quantum_fireball_entries[] = { + {SST(0x04, 0x0b, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, initializing cmd. required")} +}; + +static struct asc_table_entry sony_mo_entries[] = { + {SST(0x04, 0x00, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, cause not reportable")} +}; + +static struct scsi_sense_quirk_entry sense_quirk_table[] = { + { + /* + * The Quantum Fireball ST and SE like to return 0x04 0x0b when + * they really should return 0x04 0x02. 0x04,0x0b isn't + * defined in any SCSI spec, and it isn't mentioned in the + * hardware manual for these drives. + */ + {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"}, + /*num_sense_keys*/0, + sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry), + /*sense key entries*/NULL, + quantum_fireball_entries + }, + { + /* + * This Sony MO drive likes to return 0x04, 0x00 when it + * isn't spun up. + */ + {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"}, + /*num_sense_keys*/0, + sizeof(sony_mo_entries)/sizeof(struct asc_table_entry), + /*sense key entries*/NULL, + sony_mo_entries + } +}; + +static const int sense_quirk_table_size = + sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]); + +static struct asc_table_entry asc_table[] = { +/* + * From File: ASC-NUM.TXT + * SCSI ASC/ASCQ Assignments + * Numeric Sorted Listing + * as of 5/12/97 + * + * D - DIRECT ACCESS DEVICE (SBC) device column key + * .T - SEQUENTIAL ACCESS DEVICE (SSC) ------------------- + * . L - PRINTER DEVICE (SSC) blank = reserved + * . P - PROCESSOR DEVICE (SPC) not blank = allowed + * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC) + * . . R - CD DEVICE (MMC) + * . . S - SCANNER DEVICE (SGC) + * . . .O - OPTICAL MEMORY DEVICE (SBC) + * . . . M - MEDIA CHANGER DEVICE (SMC) + * . . . C - COMMUNICATION DEVICE (SSC) + * . . . .A - STORAGE ARRAY DEVICE (SCC) + * . . . . E - ENCLOSURE SERVICES DEVICE (SES) + * DTLPWRSOMCAE ASC ASCQ Action Description + * ------------ ---- ---- ------ -----------------------------------*/ +/* DTLPWRSOMCAE */{SST(0x00, 0x00, SS_NOP, + "No additional sense information") }, +/* T S */{SST(0x00, 0x01, SS_RDEF, + "Filemark detected") }, +/* T S */{SST(0x00, 0x02, SS_RDEF, + "End-of-partition/medium detected") }, +/* T */{SST(0x00, 0x03, SS_RDEF, + "Setmark detected") }, +/* T S */{SST(0x00, 0x04, SS_RDEF, + "Beginning-of-partition/medium detected") }, +/* T S */{SST(0x00, 0x05, SS_RDEF, + "End-of-data detected") }, +/* DTLPWRSOMCAE */{SST(0x00, 0x06, SS_RDEF, + "I/O process terminated") }, +/* R */{SST(0x00, 0x11, SS_FATAL|EBUSY, + "Audio play operation in progress") }, +/* R */{SST(0x00, 0x12, SS_NOP, + "Audio play operation paused") }, +/* R */{SST(0x00, 0x13, SS_NOP, + "Audio play operation successfully completed") }, +/* R */{SST(0x00, 0x14, SS_RDEF, + "Audio play operation stopped due to error") }, +/* R */{SST(0x00, 0x15, SS_NOP, + "No current audio status to return") }, +/* DTLPWRSOMCAE */{SST(0x00, 0x16, SS_FATAL|EBUSY, + "Operation in progress") }, +/* DTL WRSOM AE */{SST(0x00, 0x17, SS_RDEF, + "Cleaning requested") }, +/* D W O */{SST(0x01, 0x00, SS_RDEF, + "No index/sector signal") }, +/* D WR OM */{SST(0x02, 0x00, SS_RDEF, + "No seek complete") }, +/* DTL W SO */{SST(0x03, 0x00, SS_RDEF, + "Peripheral device write fault") }, +/* T */{SST(0x03, 0x01, SS_RDEF, + "No write current") }, +/* T */{SST(0x03, 0x02, SS_RDEF, + "Excessive write errors") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x00, + SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EIO, + "Logical unit not ready, cause not reportable") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x01, + SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, + "Logical unit is in process of becoming ready") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x02, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, initializing cmd. required") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x03, SS_FATAL|ENXIO, + "Logical unit not ready, manual intervention required")}, +/* DTL O */{SST(0x04, 0x04, SS_FATAL|EBUSY, + "Logical unit not ready, format in progress") }, +/* DT W OMCA */{SST(0x04, 0x05, SS_FATAL|EBUSY, + "Logical unit not ready, rebuild in progress") }, +/* DT W OMCA */{SST(0x04, 0x06, SS_FATAL|EBUSY, + "Logical unit not ready, recalculation in progress") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x07, SS_FATAL|EBUSY, + "Logical unit not ready, operation in progress") }, +/* R */{SST(0x04, 0x08, SS_FATAL|EBUSY, + "Logical unit not ready, long write in progress") }, +/* DTL WRSOMCAE */{SST(0x05, 0x00, SS_RDEF, + "Logical unit does not respond to selection") }, +/* D WR OM */{SST(0x06, 0x00, SS_RDEF, + "No reference position found") }, +/* DTL WRSOM */{SST(0x07, 0x00, SS_RDEF, + "Multiple peripheral devices selected") }, +/* DTL WRSOMCAE */{SST(0x08, 0x00, SS_RDEF, + "Logical unit communication failure") }, +/* DTL WRSOMCAE */{SST(0x08, 0x01, SS_RDEF, + "Logical unit communication time-out") }, +/* DTL WRSOMCAE */{SST(0x08, 0x02, SS_RDEF, + "Logical unit communication parity error") }, +/* DT R OM */{SST(0x08, 0x03, SS_RDEF, + "Logical unit communication crc error (ultra-dma/32)")}, +/* DT WR O */{SST(0x09, 0x00, SS_RDEF, + "Track following error") }, +/* WR O */{SST(0x09, 0x01, SS_RDEF, + "Tracking servo failure") }, +/* WR O */{SST(0x09, 0x02, SS_RDEF, + "Focus servo failure") }, +/* WR O */{SST(0x09, 0x03, SS_RDEF, + "Spindle servo failure") }, +/* DT WR O */{SST(0x09, 0x04, SS_RDEF, + "Head select fault") }, +/* DTLPWRSOMCAE */{SST(0x0A, 0x00, SS_FATAL|ENOSPC, + "Error log overflow") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x00, SS_RDEF, + "Warning") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x01, SS_RDEF, + "Specified temperature exceeded") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x02, SS_RDEF, + "Enclosure degraded") }, +/* T RS */{SST(0x0C, 0x00, SS_RDEF, + "Write error") }, +/* D W O */{SST(0x0C, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Write error - recovered with auto reallocation") }, +/* D W O */{SST(0x0C, 0x02, SS_RDEF, + "Write error - auto reallocation failed") }, +/* D W O */{SST(0x0C, 0x03, SS_RDEF, + "Write error - recommend reassignment") }, +/* DT W O */{SST(0x0C, 0x04, SS_RDEF, + "Compression check miscompare error") }, +/* DT W O */{SST(0x0C, 0x05, SS_RDEF, + "Data expansion occurred during compression") }, +/* DT W O */{SST(0x0C, 0x06, SS_RDEF, + "Block not compressible") }, +/* R */{SST(0x0C, 0x07, SS_RDEF, + "Write error - recovery needed") }, +/* R */{SST(0x0C, 0x08, SS_RDEF, + "Write error - recovery failed") }, +/* R */{SST(0x0C, 0x09, SS_RDEF, + "Write error - loss of streaming") }, +/* R */{SST(0x0C, 0x0A, SS_RDEF, + "Write error - padding blocks added") }, +/* D W O */{SST(0x10, 0x00, SS_RDEF, + "ID CRC or ECC error") }, +/* DT WRSO */{SST(0x11, 0x00, SS_RDEF, + "Unrecovered read error") }, +/* DT W SO */{SST(0x11, 0x01, SS_RDEF, + "Read retries exhausted") }, +/* DT W SO */{SST(0x11, 0x02, SS_RDEF, + "Error too long to correct") }, +/* DT W SO */{SST(0x11, 0x03, SS_RDEF, + "Multiple read errors") }, +/* D W O */{SST(0x11, 0x04, SS_RDEF, + "Unrecovered read error - auto reallocate failed") }, +/* WR O */{SST(0x11, 0x05, SS_RDEF, + "L-EC uncorrectable error") }, +/* WR O */{SST(0x11, 0x06, SS_RDEF, + "CIRC unrecovered error") }, +/* W O */{SST(0x11, 0x07, SS_RDEF, + "Data re-synchronization error") }, +/* T */{SST(0x11, 0x08, SS_RDEF, + "Incomplete block read") }, +/* T */{SST(0x11, 0x09, SS_RDEF, + "No gap found") }, +/* DT O */{SST(0x11, 0x0A, SS_RDEF, + "Miscorrected error") }, +/* D W O */{SST(0x11, 0x0B, SS_RDEF, + "Unrecovered read error - recommend reassignment") }, +/* D W O */{SST(0x11, 0x0C, SS_RDEF, + "Unrecovered read error - recommend rewrite the data")}, +/* DT WR O */{SST(0x11, 0x0D, SS_RDEF, + "De-compression CRC error") }, +/* DT WR O */{SST(0x11, 0x0E, SS_RDEF, + "Cannot decompress using declared algorithm") }, +/* R */{SST(0x11, 0x0F, SS_RDEF, + "Error reading UPC/EAN number") }, +/* R */{SST(0x11, 0x10, SS_RDEF, + "Error reading ISRC number") }, +/* R */{SST(0x11, 0x11, SS_RDEF, + "Read error - loss of streaming") }, +/* D W O */{SST(0x12, 0x00, SS_RDEF, + "Address mark not found for id field") }, +/* D W O */{SST(0x13, 0x00, SS_RDEF, + "Address mark not found for data field") }, +/* DTL WRSO */{SST(0x14, 0x00, SS_RDEF, + "Recorded entity not found") }, +/* DT WR O */{SST(0x14, 0x01, SS_RDEF, + "Record not found") }, +/* T */{SST(0x14, 0x02, SS_RDEF, + "Filemark or setmark not found") }, +/* T */{SST(0x14, 0x03, SS_RDEF, + "End-of-data not found") }, +/* T */{SST(0x14, 0x04, SS_RDEF, + "Block sequence error") }, +/* DT W O */{SST(0x14, 0x05, SS_RDEF, + "Record not found - recommend reassignment") }, +/* DT W O */{SST(0x14, 0x06, SS_RDEF, + "Record not found - data auto-reallocated") }, +/* DTL WRSOM */{SST(0x15, 0x00, SS_RDEF, + "Random positioning error") }, +/* DTL WRSOM */{SST(0x15, 0x01, SS_RDEF, + "Mechanical positioning error") }, +/* DT WR O */{SST(0x15, 0x02, SS_RDEF, + "Positioning error detected by read of medium") }, +/* D W O */{SST(0x16, 0x00, SS_RDEF, + "Data synchronization mark error") }, +/* D W O */{SST(0x16, 0x01, SS_RDEF, + "Data sync error - data rewritten") }, +/* D W O */{SST(0x16, 0x02, SS_RDEF, + "Data sync error - recommend rewrite") }, +/* D W O */{SST(0x16, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Data sync error - data auto-reallocated") }, +/* D W O */{SST(0x16, 0x04, SS_RDEF, + "Data sync error - recommend reassignment") }, +/* DT WRSO */{SST(0x17, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with no error correction applied") }, +/* DT WRSO */{SST(0x17, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with retries") }, +/* DT WR O */{SST(0x17, 0x02, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with positive head offset") }, +/* DT WR O */{SST(0x17, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with negative head offset") }, +/* WR O */{SST(0x17, 0x04, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with retries and/or CIRC applied") }, +/* D WR O */{SST(0x17, 0x05, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data using previous sector id") }, +/* D W O */{SST(0x17, 0x06, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - data auto-reallocated") }, +/* D W O */{SST(0x17, 0x07, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - recommend reassignment")}, +/* D W O */{SST(0x17, 0x08, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - recommend rewrite") }, +/* D W O */{SST(0x17, 0x09, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - data rewritten") }, +/* D W O */{SST(0x18, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with error correction applied") }, +/* D WR O */{SST(0x18, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with error corr. & retries applied") }, +/* D WR O */{SST(0x18, 0x02, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - data auto-reallocated") }, +/* R */{SST(0x18, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with CIRC") }, +/* R */{SST(0x18, 0x04, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with L-EC") }, +/* D WR O */{SST(0x18, 0x05, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - recommend reassignment") }, +/* D WR O */{SST(0x18, 0x06, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - recommend rewrite") }, +/* D W O */{SST(0x18, 0x07, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with ECC - data rewritten") }, +/* D O */{SST(0x19, 0x00, SS_RDEF, + "Defect list error") }, +/* D O */{SST(0x19, 0x01, SS_RDEF, + "Defect list not available") }, +/* D O */{SST(0x19, 0x02, SS_RDEF, + "Defect list error in primary list") }, +/* D O */{SST(0x19, 0x03, SS_RDEF, + "Defect list error in grown list") }, +/* DTLPWRSOMCAE */{SST(0x1A, 0x00, SS_RDEF, + "Parameter list length error") }, +/* DTLPWRSOMCAE */{SST(0x1B, 0x00, SS_RDEF, + "Synchronous data transfer error") }, +/* D O */{SST(0x1C, 0x00, SS_RDEF, + "Defect list not found") }, +/* D O */{SST(0x1C, 0x01, SS_RDEF, + "Primary defect list not found") }, +/* D O */{SST(0x1C, 0x02, SS_RDEF, + "Grown defect list not found") }, +/* D W O */{SST(0x1D, 0x00, SS_FATAL, + "Miscompare during verify operation" )}, +/* D W O */{SST(0x1E, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered id with ecc correction") }, +/* D O */{SST(0x1F, 0x00, SS_RDEF, + "Partial defect list transfer") }, +/* DTLPWRSOMCAE */{SST(0x20, 0x00, SS_FATAL|EINVAL, + "Invalid command operation code") }, +/* DT WR OM */{SST(0x21, 0x00, SS_FATAL|EINVAL, + "Logical block address out of range" )}, +/* DT WR OM */{SST(0x21, 0x01, SS_FATAL|EINVAL, + "Invalid element address") }, +/* D */{SST(0x22, 0x00, SS_FATAL|EINVAL, + "Illegal function") }, /* Deprecated. Use 20 00, 24 00, or 26 00 instead */ +/* DTLPWRSOMCAE */{SST(0x24, 0x00, SS_FATAL|EINVAL, + "Invalid field in CDB") }, +/* DTLPWRSOMCAE */{SST(0x25, 0x00, SS_FATAL|ENXIO, + "Logical unit not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x00, SS_FATAL|EINVAL, + "Invalid field in parameter list") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x01, SS_FATAL|EINVAL, + "Parameter not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x02, SS_FATAL|EINVAL, + "Parameter value invalid") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x03, SS_FATAL|EINVAL, + "Threshold parameters not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x04, SS_FATAL|EINVAL, + "Invalid release of active persistent reservation") }, +/* DT W O */{SST(0x27, 0x00, SS_FATAL|EACCES, + "Write protected") }, +/* DT W O */{SST(0x27, 0x01, SS_FATAL|EACCES, + "Hardware write protected") }, +/* DT W O */{SST(0x27, 0x02, SS_FATAL|EACCES, + "Logical unit software write protected") }, +/* T */{SST(0x27, 0x03, SS_FATAL|EACCES, + "Associated write protect") }, +/* T */{SST(0x27, 0x04, SS_FATAL|EACCES, + "Persistent write protect") }, +/* T */{SST(0x27, 0x05, SS_FATAL|EACCES, + "Permanent write protect") }, +/* DTLPWRSOMCAE */{SST(0x28, 0x00, SS_RDEF, + "Not ready to ready change, medium may have changed") }, +/* DTLPWRSOMCAE */{SST(0x28, 0x01, SS_FATAL|ENXIO, + "Import or export element accessed") }, +/* + * XXX JGibbs - All of these should use the same errno, but I don't think + * ENXIO is the correct choice. Should we borrow from the networking + * errnos? ECONNRESET anyone? + */ +/* DTLPWRSOMCAE */{SST(0x29, 0x00, SS_RDEF, + "Power on, reset, or bus device reset occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x01, SS_RDEF, + "Power on occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x02, SS_RDEF, + "Scsi bus reset occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x03, SS_RDEF, + "Bus device reset function occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x04, SS_RDEF, + "Device internal reset") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x05, SS_RDEF, + "Transceiver mode changed to single-ended") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x06, SS_RDEF, + "Transceiver mode changed to LVD") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x00, SS_RDEF, + "Parameters changed") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x01, SS_RDEF, + "Mode parameters changed") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x02, SS_RDEF, + "Log parameters changed") }, +/* DTLPWRSOMCAE */{SST(0x2A, 0x03, SS_RDEF, + "Reservations preempted") }, +/* DTLPWRSO C */{SST(0x2B, 0x00, SS_RDEF, + "Copy cannot execute since host cannot disconnect") }, +/* DTLPWRSOMCAE */{SST(0x2C, 0x00, SS_RDEF, + "Command sequence error") }, +/* S */{SST(0x2C, 0x01, SS_RDEF, + "Too many windows specified") }, +/* S */{SST(0x2C, 0x02, SS_RDEF, + "Invalid combination of windows specified") }, +/* R */{SST(0x2C, 0x03, SS_RDEF, + "Current program area is not empty") }, +/* R */{SST(0x2C, 0x04, SS_RDEF, + "Current program area is empty") }, +/* T */{SST(0x2D, 0x00, SS_RDEF, + "Overwrite error on update in place") }, +/* DTLPWRSOMCAE */{SST(0x2F, 0x00, SS_RDEF, + "Commands cleared by another initiator") }, +/* DT WR OM */{SST(0x30, 0x00, SS_RDEF, + "Incompatible medium installed") }, +/* DT WR O */{SST(0x30, 0x01, SS_RDEF, + "Cannot read medium - unknown format") }, +/* DT WR O */{SST(0x30, 0x02, SS_RDEF, + "Cannot read medium - incompatible format") }, +/* DT */{SST(0x30, 0x03, SS_RDEF, + "Cleaning cartridge installed") }, +/* DT WR O */{SST(0x30, 0x04, SS_RDEF, + "Cannot write medium - unknown format") }, +/* DT WR O */{SST(0x30, 0x05, SS_RDEF, + "Cannot write medium - incompatible format") }, +/* DT W O */{SST(0x30, 0x06, SS_RDEF, + "Cannot format medium - incompatible medium") }, +/* DTL WRSOM AE */{SST(0x30, 0x07, SS_RDEF, + "Cleaning failure") }, +/* R */{SST(0x30, 0x08, SS_RDEF, + "Cannot write - application code mismatch") }, +/* R */{SST(0x30, 0x09, SS_RDEF, + "Current session not fixated for append") }, +/* DT WR O */{SST(0x31, 0x00, SS_RDEF, + "Medium format corrupted") }, +/* D L R O */{SST(0x31, 0x01, SS_RDEF, + "Format command failed") }, +/* D W O */{SST(0x32, 0x00, SS_RDEF, + "No defect spare location available") }, +/* D W O */{SST(0x32, 0x01, SS_RDEF, + "Defect list update failure") }, +/* T */{SST(0x33, 0x00, SS_RDEF, + "Tape length error") }, +/* DTLPWRSOMCAE */{SST(0x34, 0x00, SS_RDEF, + "Enclosure failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x00, SS_RDEF, + "Enclosure services failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x01, SS_RDEF, + "Unsupported enclosure function") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x02, SS_RDEF, + "Enclosure services unavailable") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x03, SS_RDEF, + "Enclosure services transfer failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x04, SS_RDEF, + "Enclosure services transfer refused") }, +/* L */{SST(0x36, 0x00, SS_RDEF, + "Ribbon, ink, or toner failure") }, +/* DTL WRSOMCAE */{SST(0x37, 0x00, SS_RDEF, + "Rounded parameter") }, +/* DTL WRSOMCAE */{SST(0x39, 0x00, SS_RDEF, + "Saving parameters not supported") }, +/* DTL WRSOM */{SST(0x3A, 0x00, SS_NOP, + "Medium not present") }, +/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, + "Medium not present - tray closed") }, +/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, + "Medium not present - tray open") }, +/* DT WR OM */{SST(0x3A, 0x03, SS_NOP, + "Medium not present - Loadable") }, +/* DT WR OM */{SST(0x3A, 0x04, SS_NOP, + "Medium not present - medium auxiliary " + "memory accessible") }, +/* DT WR OM */{SST(0x3A, 0xFF, SS_NOP, NULL) },/* Range 0x05->0xFF */ +/* TL */{SST(0x3B, 0x00, SS_RDEF, + "Sequential positioning error") }, +/* T */{SST(0x3B, 0x01, SS_RDEF, + "Tape position error at beginning-of-medium") }, +/* T */{SST(0x3B, 0x02, SS_RDEF, + "Tape position error at end-of-medium") }, +/* L */{SST(0x3B, 0x03, SS_RDEF, + "Tape or electronic vertical forms unit not ready") }, +/* L */{SST(0x3B, 0x04, SS_RDEF, + "Slew failure") }, +/* L */{SST(0x3B, 0x05, SS_RDEF, + "Paper jam") }, +/* L */{SST(0x3B, 0x06, SS_RDEF, + "Failed to sense top-of-form") }, +/* L */{SST(0x3B, 0x07, SS_RDEF, + "Failed to sense bottom-of-form") }, +/* T */{SST(0x3B, 0x08, SS_RDEF, + "Reposition error") }, +/* S */{SST(0x3B, 0x09, SS_RDEF, + "Read past end of medium") }, +/* S */{SST(0x3B, 0x0A, SS_RDEF, + "Read past beginning of medium") }, +/* S */{SST(0x3B, 0x0B, SS_RDEF, + "Position past end of medium") }, +/* T S */{SST(0x3B, 0x0C, SS_RDEF, + "Position past beginning of medium") }, +/* DT WR OM */{SST(0x3B, 0x0D, SS_FATAL|ENOSPC, + "Medium destination element full") }, +/* DT WR OM */{SST(0x3B, 0x0E, SS_RDEF, + "Medium source element empty") }, +/* R */{SST(0x3B, 0x0F, SS_RDEF, + "End of medium reached") }, +/* DT WR OM */{SST(0x3B, 0x11, SS_RDEF, + "Medium magazine not accessible") }, +/* DT WR OM */{SST(0x3B, 0x12, SS_RDEF, + "Medium magazine removed") }, +/* DT WR OM */{SST(0x3B, 0x13, SS_RDEF, + "Medium magazine inserted") }, +/* DT WR OM */{SST(0x3B, 0x14, SS_RDEF, + "Medium magazine locked") }, +/* DT WR OM */{SST(0x3B, 0x15, SS_RDEF, + "Medium magazine unlocked") }, +/* DTLPWRSOMCAE */{SST(0x3D, 0x00, SS_RDEF, + "Invalid bits in identify message") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x00, SS_RDEF, + "Logical unit has not self-configured yet") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x01, SS_RDEF, + "Logical unit failure") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x02, SS_RDEF, + "Timeout on logical unit") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x00, SS_RDEF, + "Target operating conditions have changed") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x01, SS_RDEF, + "Microcode has been changed") }, +/* DTLPWRSOMC */{SST(0x3F, 0x02, SS_RDEF, + "Changed operating definition") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x03, SS_INQ_REFRESH|SSQ_DECREMENT_COUNT, + "Inquiry data has changed") }, +/* DT WR OMCAE */{SST(0x3F, 0x04, SS_RDEF, + "Component device attached") }, +/* DT WR OMCAE */{SST(0x3F, 0x05, SS_RDEF, + "Device identifier changed") }, +/* DT WR OMCAE */{SST(0x3F, 0x06, SS_RDEF, + "Redundancy group created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x07, SS_RDEF, + "Redundancy group deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x08, SS_RDEF, + "Spare created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x09, SS_RDEF, + "Spare deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x0A, SS_RDEF, + "Volume set created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x0B, SS_RDEF, + "Volume set deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x0C, SS_RDEF, + "Volume set deassigned") }, +/* DT WR OMCAE */{SST(0x3F, 0x0D, SS_RDEF, + "Volume set reassigned") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x0E, SS_RDEF, + "Reported luns data has changed") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x0F, SS_RETRY|SSQ_DECREMENT_COUNT + | SSQ_DELAY_RANDOM|EBUSY, + "Echo buffer overwritten") }, +/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, "Medium Loadable") }, +/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, + "Medium auxiliary memory accessible") }, +/* D */{SST(0x40, 0x00, SS_RDEF, + "Ram failure") }, /* deprecated - use 40 NN instead */ +/* DTLPWRSOMCAE */{SST(0x40, 0x80, SS_RDEF, + "Diagnostic failure: ASCQ = Component ID") }, +/* DTLPWRSOMCAE */{SST(0x40, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) },/* Range 0x80->0xFF */ +/* D */{SST(0x41, 0x00, SS_RDEF, + "Data path failure") }, /* deprecated - use 40 NN instead */ +/* D */{SST(0x42, 0x00, SS_RDEF, + "Power-on or self-test failure") }, /* deprecated - use 40 NN instead */ +/* DTLPWRSOMCAE */{SST(0x43, 0x00, SS_RDEF, + "Message error") }, +/* DTLPWRSOMCAE */{SST(0x44, 0x00, SS_RDEF, + "Internal target failure") }, +/* DTLPWRSOMCAE */{SST(0x45, 0x00, SS_RDEF, + "Select or reselect failure") }, +/* DTLPWRSOMC */{SST(0x46, 0x00, SS_RDEF, + "Unsuccessful soft reset") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x00, SS_RDEF|SSQ_FALLBACK, + "SCSI parity error") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x01, SS_RDEF|SSQ_FALLBACK, + "Data Phase CRC error detected") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x02, SS_RDEF|SSQ_FALLBACK, + "SCSI parity error detected during ST data phase") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x03, SS_RDEF|SSQ_FALLBACK, + "Information Unit iuCRC error") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x04, SS_RDEF|SSQ_FALLBACK, + "Asynchronous information protection error detected") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x05, SS_RDEF|SSQ_FALLBACK, + "Protocol server CRC error") }, +/* DTLPWRSOMCAE */{SST(0x48, 0x00, SS_RDEF|SSQ_FALLBACK, + "Initiator detected error message received") }, +/* DTLPWRSOMCAE */{SST(0x49, 0x00, SS_RDEF, + "Invalid message error") }, +/* DTLPWRSOMCAE */{SST(0x4A, 0x00, SS_RDEF, + "Command phase error") }, +/* DTLPWRSOMCAE */{SST(0x4B, 0x00, SS_RDEF, + "Data phase error") }, +/* DTLPWRSOMCAE */{SST(0x4C, 0x00, SS_RDEF, + "Logical unit failed self-configuration") }, +/* DTLPWRSOMCAE */{SST(0x4D, 0x00, SS_RDEF, + "Tagged overlapped commands: ASCQ = Queue tag ID") }, +/* DTLPWRSOMCAE */{SST(0x4D, 0xFF, SS_RDEF|SSQ_RANGE, + NULL)}, /* Range 0x00->0xFF */ +/* DTLPWRSOMCAE */{SST(0x4E, 0x00, SS_RDEF, + "Overlapped commands attempted") }, +/* T */{SST(0x50, 0x00, SS_RDEF, + "Write append error") }, +/* T */{SST(0x50, 0x01, SS_RDEF, + "Write append position error") }, +/* T */{SST(0x50, 0x02, SS_RDEF, + "Position error related to timing") }, +/* T O */{SST(0x51, 0x00, SS_RDEF, + "Erase failure") }, +/* T */{SST(0x52, 0x00, SS_RDEF, + "Cartridge fault") }, +/* DTL WRSOM */{SST(0x53, 0x00, SS_RDEF, + "Media load or eject failed") }, +/* T */{SST(0x53, 0x01, SS_RDEF, + "Unload tape failure") }, +/* DT WR OM */{SST(0x53, 0x02, SS_RDEF, + "Medium removal prevented") }, +/* P */{SST(0x54, 0x00, SS_RDEF, + "Scsi to host system interface failure") }, +/* P */{SST(0x55, 0x00, SS_RDEF, + "System resource failure") }, +/* D O */{SST(0x55, 0x01, SS_FATAL|ENOSPC, + "System buffer full") }, +/* R */{SST(0x57, 0x00, SS_RDEF, + "Unable to recover table-of-contents") }, +/* O */{SST(0x58, 0x00, SS_RDEF, + "Generation does not exist") }, +/* O */{SST(0x59, 0x00, SS_RDEF, + "Updated block read") }, +/* DTLPWRSOM */{SST(0x5A, 0x00, SS_RDEF, + "Operator request or state change input") }, +/* DT WR OM */{SST(0x5A, 0x01, SS_RDEF, + "Operator medium removal request") }, +/* DT W O */{SST(0x5A, 0x02, SS_RDEF, + "Operator selected write protect") }, +/* DT W O */{SST(0x5A, 0x03, SS_RDEF, + "Operator selected write permit") }, +/* DTLPWRSOM */{SST(0x5B, 0x00, SS_RDEF, + "Log exception") }, +/* DTLPWRSOM */{SST(0x5B, 0x01, SS_RDEF, + "Threshold condition met") }, +/* DTLPWRSOM */{SST(0x5B, 0x02, SS_RDEF, + "Log counter at maximum") }, +/* DTLPWRSOM */{SST(0x5B, 0x03, SS_RDEF, + "Log list codes exhausted") }, +/* D O */{SST(0x5C, 0x00, SS_RDEF, + "RPL status change") }, +/* D O */{SST(0x5C, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Spindles synchronized") }, +/* D O */{SST(0x5C, 0x02, SS_RDEF, + "Spindles not synchronized") }, +/* DTLPWRSOMCAE */{SST(0x5D, 0x00, SS_RDEF, + "Failure prediction threshold exceeded") }, +/* DTLPWRSOMCAE */{SST(0x5D, 0xFF, SS_RDEF, + "Failure prediction threshold exceeded (false)") }, +/* DTLPWRSO CA */{SST(0x5E, 0x00, SS_RDEF, + "Low power condition on") }, +/* DTLPWRSO CA */{SST(0x5E, 0x01, SS_RDEF, + "Idle condition activated by timer") }, +/* DTLPWRSO CA */{SST(0x5E, 0x02, SS_RDEF, + "Standby condition activated by timer") }, +/* DTLPWRSO CA */{SST(0x5E, 0x03, SS_RDEF, + "Idle condition activated by command") }, +/* DTLPWRSO CA */{SST(0x5E, 0x04, SS_RDEF, + "Standby condition activated by command") }, +/* S */{SST(0x60, 0x00, SS_RDEF, + "Lamp failure") }, +/* S */{SST(0x61, 0x00, SS_RDEF, + "Video acquisition error") }, +/* S */{SST(0x61, 0x01, SS_RDEF, + "Unable to acquire video") }, +/* S */{SST(0x61, 0x02, SS_RDEF, + "Out of focus") }, +/* S */{SST(0x62, 0x00, SS_RDEF, + "Scan head positioning error") }, +/* R */{SST(0x63, 0x00, SS_RDEF, + "End of user area encountered on this track") }, +/* R */{SST(0x63, 0x01, SS_FATAL|ENOSPC, + "Packet does not fit in available space") }, +/* R */{SST(0x64, 0x00, SS_RDEF, + "Illegal mode for this track") }, +/* R */{SST(0x64, 0x01, SS_RDEF, + "Invalid packet size") }, +/* DTLPWRSOMCAE */{SST(0x65, 0x00, SS_RDEF, + "Voltage fault") }, +/* S */{SST(0x66, 0x00, SS_RDEF, + "Automatic document feeder cover up") }, +/* S */{SST(0x66, 0x01, SS_RDEF, + "Automatic document feeder lift up") }, +/* S */{SST(0x66, 0x02, SS_RDEF, + "Document jam in automatic document feeder") }, +/* S */{SST(0x66, 0x03, SS_RDEF, + "Document miss feed automatic in document feeder") }, +/* A */{SST(0x67, 0x00, SS_RDEF, + "Configuration failure") }, +/* A */{SST(0x67, 0x01, SS_RDEF, + "Configuration of incapable logical units failed") }, +/* A */{SST(0x67, 0x02, SS_RDEF, + "Add logical unit failed") }, +/* A */{SST(0x67, 0x03, SS_RDEF, + "Modification of logical unit failed") }, +/* A */{SST(0x67, 0x04, SS_RDEF, + "Exchange of logical unit failed") }, +/* A */{SST(0x67, 0x05, SS_RDEF, + "Remove of logical unit failed") }, +/* A */{SST(0x67, 0x06, SS_RDEF, + "Attachment of logical unit failed") }, +/* A */{SST(0x67, 0x07, SS_RDEF, + "Creation of logical unit failed") }, +/* A */{SST(0x68, 0x00, SS_RDEF, + "Logical unit not configured") }, +/* A */{SST(0x69, 0x00, SS_RDEF, + "Data loss on logical unit") }, +/* A */{SST(0x69, 0x01, SS_RDEF, + "Multiple logical unit failures") }, +/* A */{SST(0x69, 0x02, SS_RDEF, + "Parity/data mismatch") }, +/* A */{SST(0x6A, 0x00, SS_RDEF, + "Informational, refer to log") }, +/* A */{SST(0x6B, 0x00, SS_RDEF, + "State change has occurred") }, +/* A */{SST(0x6B, 0x01, SS_RDEF, + "Redundancy level got better") }, +/* A */{SST(0x6B, 0x02, SS_RDEF, + "Redundancy level got worse") }, +/* A */{SST(0x6C, 0x00, SS_RDEF, + "Rebuild failure occurred") }, +/* A */{SST(0x6D, 0x00, SS_RDEF, + "Recalculate failure occurred") }, +/* A */{SST(0x6E, 0x00, SS_RDEF, + "Command to logical unit failed") }, +/* T */{SST(0x70, 0x00, SS_RDEF, + "Decompression exception short: ASCQ = Algorithm ID") }, +/* T */{SST(0x70, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) }, /* Range 0x00 -> 0xFF */ +/* T */{SST(0x71, 0x00, SS_RDEF, + "Decompression exception long: ASCQ = Algorithm ID") }, +/* T */{SST(0x71, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) }, /* Range 0x00 -> 0xFF */ +/* R */{SST(0x72, 0x00, SS_RDEF, + "Session fixation error") }, +/* R */{SST(0x72, 0x01, SS_RDEF, + "Session fixation error writing lead-in") }, +/* R */{SST(0x72, 0x02, SS_RDEF, + "Session fixation error writing lead-out") }, +/* R */{SST(0x72, 0x03, SS_RDEF, + "Session fixation error - incomplete track in session") }, +/* R */{SST(0x72, 0x04, SS_RDEF, + "Empty or partially written reserved track") }, +/* R */{SST(0x73, 0x00, SS_RDEF, + "CD control error") }, +/* R */{SST(0x73, 0x01, SS_RDEF, + "Power calibration area almost full") }, +/* R */{SST(0x73, 0x02, SS_FATAL|ENOSPC, + "Power calibration area is full") }, +/* R */{SST(0x73, 0x03, SS_RDEF, + "Power calibration area error") }, +/* R */{SST(0x73, 0x04, SS_RDEF, + "Program memory area update failure") }, +/* R */{SST(0x73, 0x05, SS_RDEF, + "program memory area is full") } +}; + +static const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]); + +struct asc_key +{ + int asc; + int ascq; +}; + +static int +ascentrycomp(const void *key, const void *member) +{ + int asc; + int ascq; + const struct asc_table_entry *table_entry; + + asc = ((const struct asc_key *)key)->asc; + ascq = ((const struct asc_key *)key)->ascq; + table_entry = (const struct asc_table_entry *)member; + + if (asc >= table_entry->asc) { + + if (asc > table_entry->asc) + return (1); + + if (ascq <= table_entry->ascq) { + /* Check for ranges */ + if (ascq == table_entry->ascq + || ((table_entry->action & SSQ_RANGE) != 0 + && ascq >= (table_entry - 1)->ascq)) + return (0); + return (-1); + } + return (1); + } + return (-1); +} + +static int +senseentrycomp(const void *key, const void *member) +{ + int sense_key; + const struct sense_key_table_entry *table_entry; + + sense_key = *((const int *)key); + table_entry = (const struct sense_key_table_entry *)member; + + if (sense_key >= table_entry->sense_key) { + if (sense_key == table_entry->sense_key) + return (0); + return (1); + } + return (-1); +} + +static void +fetchtableentries(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *inq_data, + const struct sense_key_table_entry **sense_entry, + const struct asc_table_entry **asc_entry) +{ + void *match; + const struct asc_table_entry *asc_tables[2]; + const struct sense_key_table_entry *sense_tables[2]; + struct asc_key asc_ascq; + size_t asc_tables_size[2]; + size_t sense_tables_size[2]; + int num_asc_tables; + int num_sense_tables; + int i; + + /* Default to failure */ + *sense_entry = NULL; + *asc_entry = NULL; + match = NULL; + if (inq_data != NULL) + match = cam_quirkmatch((void *)inq_data, + (void *)sense_quirk_table, + sense_quirk_table_size, + sizeof(*sense_quirk_table), + aic_inquiry_match); + + if (match != NULL) { + struct scsi_sense_quirk_entry *quirk; + + quirk = (struct scsi_sense_quirk_entry *)match; + asc_tables[0] = quirk->asc_info; + asc_tables_size[0] = quirk->num_ascs; + asc_tables[1] = asc_table; + asc_tables_size[1] = asc_table_size; + num_asc_tables = 2; + sense_tables[0] = quirk->sense_key_info; + sense_tables_size[0] = quirk->num_sense_keys; + sense_tables[1] = sense_key_table; + sense_tables_size[1] = sense_key_table_size; + num_sense_tables = 2; + } else { + asc_tables[0] = asc_table; + asc_tables_size[0] = asc_table_size; + num_asc_tables = 1; + sense_tables[0] = sense_key_table; + sense_tables_size[0] = sense_key_table_size; + num_sense_tables = 1; + } + + asc_ascq.asc = asc; + asc_ascq.ascq = ascq; + for (i = 0; i < num_asc_tables; i++) { + void *found_entry; + + found_entry = scsibsearch(&asc_ascq, asc_tables[i], + asc_tables_size[i], + sizeof(**asc_tables), + ascentrycomp); + + if (found_entry) { + *asc_entry = (struct asc_table_entry *)found_entry; + break; + } + } + + for (i = 0; i < num_sense_tables; i++) { + void *found_entry; + + found_entry = scsibsearch(&sense_key, sense_tables[i], + sense_tables_size[i], + sizeof(**sense_tables), + senseentrycomp); + + if (found_entry) { + *sense_entry = + (struct sense_key_table_entry *)found_entry; + break; + } + } +} + +static void * +scsibsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) +{ + const void *entry; + u_int l; + u_int u; + u_int m; + + l = -1; + u = nmemb; + while (l + 1 != u) { + m = (l + u) / 2; + entry = base + m * size; + if (compar(key, entry) > 0) + l = m; + else + u = m; + } + + entry = base + u * size; + if (u == nmemb + || compar(key, entry) != 0) + return (NULL); + + return ((void *)entry); +} + +/* + * Compare string with pattern, returning 0 on match. + * Short pattern matches trailing blanks in name, + * wildcard '*' in pattern matches rest of name, + * wildcard '?' matches a single non-space character. + */ +static int +cam_strmatch(const uint8_t *str, const uint8_t *pattern, int str_len) +{ + + while (*pattern != '\0'&& str_len > 0) { + + if (*pattern == '*') { + return (0); + } + if ((*pattern != *str) + && (*pattern != '?' || *str == ' ')) { + return (1); + } + pattern++; + str++; + str_len--; + } + while (str_len > 0 && *str++ == ' ') + str_len--; + + return (str_len); +} + +static caddr_t +cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, + int entry_size, cam_quirkmatch_t *comp_func) +{ + for (; num_entries > 0; num_entries--, quirk_table += entry_size) { + if ((*comp_func)(target, quirk_table) == 0) + return (quirk_table); + } + return (NULL); +} + +void +aic_sense_desc(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *inq_data, + const char **sense_key_desc, const char **asc_desc) +{ + const struct asc_table_entry *asc_entry; + const struct sense_key_table_entry *sense_entry; + + fetchtableentries(sense_key, asc, ascq, + inq_data, + &sense_entry, + &asc_entry); + + *sense_key_desc = sense_entry->desc; + + if (asc_entry != NULL) + *asc_desc = asc_entry->desc; + else if (asc >= 0x80 && asc <= 0xff) + *asc_desc = "Vendor Specific ASC"; + else if (ascq >= 0x80 && ascq <= 0xff) + *asc_desc = "Vendor Specific ASCQ"; + else + *asc_desc = "Reserved ASC/ASCQ pair"; +} + +/* + * Given sense and device type information, return the appropriate action. + * If we do not understand the specific error as identified by the ASC/ASCQ + * pair, fall back on the more generic actions derived from the sense key. + */ +aic_sense_action +aic_sense_error_action(struct scsi_sense_data *sense_data, + struct scsi_inquiry_data *inq_data, uint32_t sense_flags) +{ + const struct asc_table_entry *asc_entry; + const struct sense_key_table_entry *sense_entry; + int error_code, sense_key, asc, ascq; + aic_sense_action action; + + scsi_extract_sense(sense_data, &error_code, &sense_key, &asc, &ascq); + + if (error_code == SSD_DEFERRED_ERROR) { + /* + * XXX dufault@FreeBSD.org + * This error doesn't relate to the command associated + * with this request sense. A deferred error is an error + * for a command that has already returned GOOD status + * (see SCSI2 8.2.14.2). + * + * By my reading of that section, it looks like the current + * command has been cancelled, we should now clean things up + * (hopefully recovering any lost data) and then retry the + * current command. There are two easy choices, both wrong: + * + * 1. Drop through (like we had been doing), thus treating + * this as if the error were for the current command and + * return and stop the current command. + * + * 2. Issue a retry (like I made it do) thus hopefully + * recovering the current transfer, and ignoring the + * fact that we've dropped a command. + * + * These should probably be handled in a device specific + * sense handler or punted back up to a user mode daemon + */ + action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE; + } else { + fetchtableentries(sense_key, asc, ascq, + inq_data, + &sense_entry, + &asc_entry); + + /* + * Override the 'No additional Sense' entry (0,0) + * with the error action of the sense key. + */ + if (asc_entry != NULL + && (asc != 0 || ascq != 0)) + action = asc_entry->action; + else + action = sense_entry->action; + + if (sense_key == SSD_KEY_RECOVERED_ERROR) { + /* + * The action succeeded but the device wants + * the user to know that some recovery action + * was required. + */ + action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK); + action |= SS_NOP|SSQ_PRINT_SENSE; + } else if (sense_key == SSD_KEY_ILLEGAL_REQUEST) { + if ((sense_flags & SF_QUIET_IR) != 0) + action &= ~SSQ_PRINT_SENSE; + } else if (sense_key == SSD_KEY_UNIT_ATTENTION) { + if ((sense_flags & SF_RETRY_UA) != 0 + && (action & SS_MASK) == SS_FAIL) { + action &= ~(SS_MASK|SSQ_MASK); + action |= SS_RETRY|SSQ_DECREMENT_COUNT| + SSQ_PRINT_SENSE; + } + } + } + + if ((sense_flags & SF_PRINT_ALWAYS) != 0) + action |= SSQ_PRINT_SENSE; + else if ((sense_flags & SF_NO_PRINT) != 0) + action &= ~SSQ_PRINT_SENSE; + + return (action); +} + +/* + * Try make as good a match as possible with + * available sub drivers + */ +int +aic_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) +{ + struct scsi_inquiry_pattern *entry; + struct scsi_inquiry_data *inq; + + entry = (struct scsi_inquiry_pattern *)table_entry; + inq = (struct scsi_inquiry_data *)inqbuffer; + + if (((SID_TYPE(inq) == entry->type) + || (entry->type == T_ANY)) + && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE + : entry->media_type & SIP_MEDIA_FIXED) + && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) + && (cam_strmatch(inq->product, entry->product, + sizeof(inq->product)) == 0) + && (cam_strmatch(inq->revision, entry->revision, + sizeof(inq->revision)) == 0)) { + return (0); + } + return (-1); +} + +/* + * Table of syncrates that don't follow the "divisible by 4" + * rule. This table will be expanded in future SCSI specs. + */ +static struct { + u_int period_factor; + u_int period; /* in 100ths of ns */ +} scsi_syncrates[] = { + { 0x08, 625 }, /* FAST-160 */ + { 0x09, 1250 }, /* FAST-80 */ + { 0x0a, 2500 }, /* FAST-40 40MHz */ + { 0x0b, 3030 }, /* FAST-40 33MHz */ + { 0x0c, 5000 } /* FAST-20 */ +}; + +/* + * Return the frequency in kHz corresponding to the given + * sync period factor. + */ +u_int +aic_calc_syncsrate(u_int period_factor) +{ + int i; + int num_syncrates; + + num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); + /* See if the period is in the "exception" table */ + for (i = 0; i < num_syncrates; i++) { + + if (period_factor == scsi_syncrates[i].period_factor) { + /* Period in kHz */ + return (100000000 / scsi_syncrates[i].period); + } + } + + /* + * Wasn't in the table, so use the standard + * 4 times conversion. + */ + return (10000000 / (period_factor * 4 * 10)); +} + +/* + * Return speed in KB/s. + */ +u_int +aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate) +{ + u_int freq; + + if (offset != 0 && period < min_rate) + freq = aic_calc_syncsrate(period); + else + /* Roughly 3.3MB/s for async */ + freq = 3300; + freq <<= width; + return (freq); +} + +uint32_t +aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data, + cam_status status, u_int scsi_status) +{ + aic_sense_action err_action; + int sense; + + sense = (cmd->result >> 24) == DRIVER_SENSE; + + switch (status) { + case CAM_REQ_CMP: + err_action = SS_NOP; + break; + case CAM_AUTOSENSE_FAIL: + case CAM_SCSI_STATUS_ERROR: + + switch (scsi_status) { + case SCSI_STATUS_OK: + case SCSI_STATUS_COND_MET: + case SCSI_STATUS_INTERMED: + case SCSI_STATUS_INTERMED_COND_MET: + err_action = SS_NOP; + break; + case SCSI_STATUS_CMD_TERMINATED: + case SCSI_STATUS_CHECK_COND: + if (sense != 0) { + struct scsi_sense_data *sense; + + sense = (struct scsi_sense_data *) + &cmd->sense_buffer; + err_action = + aic_sense_error_action(sense, inq_data, 0); + + } else { + err_action = SS_RETRY|SSQ_FALLBACK + | SSQ_DECREMENT_COUNT|EIO; + } + break; + case SCSI_STATUS_QUEUE_FULL: + case SCSI_STATUS_BUSY: + err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY + | SSQ_DECREMENT_COUNT|EBUSY; + break; + case SCSI_STATUS_RESERV_CONFLICT: + default: + err_action = SS_FAIL|EBUSY; + break; + } + break; + case CAM_CMD_TIMEOUT: + case CAM_REQ_CMP_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_UNCOR_PARITY: + case CAM_DATA_RUN_ERR: + err_action = SS_RETRY|SSQ_FALLBACK|EIO; + break; + case CAM_UA_ABORT: + case CAM_UA_TERMIO: + case CAM_MSG_REJECT_REC: + case CAM_SEL_TIMEOUT: + err_action = SS_FAIL|EIO; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + case CAM_DEV_NOT_THERE: + case CAM_NO_HBA: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TOO_BIG: + case CAM_RESRC_UNAVAIL: + case CAM_BUSY: + default: + /* panic?? These should never occur in our application. */ + err_action = SS_FAIL|EIO; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + case CAM_REQUEUE_REQ: + /* Unconditional requeue */ + err_action = SS_RETRY; + break; + } + + return (err_action); +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/aiclib.h linux.21pre4-ac6/drivers/scsi/aic7xxx/aiclib.h --- linux.21pre4/drivers/scsi/aic7xxx/aiclib.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/aiclib.h 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,1001 @@ +/* + * Largely written by Julian Elischer (julian@tfs.com) + * for TRW Financial Systems. + * + * TRW Financial Systems, in accordance with their agreement with Carnegie + * Mellon University, makes this software available to CMU to distribute + * or use in any manner that they see fit as long as this message is kept with + * the software. For this reason TFS also grants any other persons or + * organisations permission to use or modify this software. + * + * TFS supplies this software to be publicly redistributed + * on the understanding that TFS is not responsible for the correct + * functioning of this software in any circumstances. + * + * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 + * + * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.21 2002/10/08 17:12:44 ken Exp $ + * $Id$ + */ + +/* + * SCSI general interface description + */ + +#ifndef _SCSI_SCSI_ALL_H +#define _SCSI_SCSI_ALL_H 1 + +/* + * SCSI command format + */ + +/* + * Define dome bits that are in ALL (or a lot of) scsi commands + */ +#define SCSI_CTL_LINK 0x01 +#define SCSI_CTL_FLAG 0x02 +#define SCSI_CTL_VENDOR 0xC0 +#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */ +#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */ + +#define SCSI_MAX_CDBLEN 16 /* + * 16 byte commands are in the + * SCSI-3 spec + */ +/* 6byte CDBs special case 0 length to be 256 */ +#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len) + +/* + * This type defines actions to be taken when a particular sense code is + * received. Right now, these flags are only defined to take up 16 bits, + * but can be expanded in the future if necessary. + */ +typedef enum { + SS_NOP = 0x000000, /* Do nothing */ + SS_RETRY = 0x010000, /* Retry the command */ + SS_FAIL = 0x020000, /* Bail out */ + SS_START = 0x030000, /* Send a Start Unit command to the device, + * then retry the original command. + */ + SS_TUR = 0x040000, /* Send a Test Unit Ready command to the + * device, then retry the original command. + */ + SS_REQSENSE = 0x050000, /* Send a RequestSense command to the + * device, then retry the original command. + */ + SS_INQ_REFRESH = 0x060000, + SS_MASK = 0xff0000 +} aic_sense_action; + +typedef enum { + SSQ_NONE = 0x0000, + SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */ + SSQ_MANY = 0x0200, /* send lots of recovery commands */ + SSQ_RANGE = 0x0400, /* + * This table entry represents the + * end of a range of ASCQs that + * have identical error actions + * and text. + */ + SSQ_PRINT_SENSE = 0x0800, + SSQ_DELAY = 0x1000, /* Delay before retry. */ + SSQ_DELAY_RANDOM = 0x2000, /* Randomized delay before retry. */ + SSQ_FALLBACK = 0x4000, /* Do a speed fallback to recover */ + SSQ_MASK = 0xff00 +} aic_sense_action_qualifier; + +/* Mask for error status values */ +#define SS_ERRMASK 0xff + +/* The default, retyable, error action */ +#define SS_RDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO + +/* The retyable, error action, with table specified error code */ +#define SS_RET SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE + +/* Fatal error action, with table specified error code */ +#define SS_FATAL SS_FAIL|SSQ_PRINT_SENSE + +struct scsi_generic +{ + uint8_t opcode; + uint8_t bytes[11]; +}; + +struct scsi_request_sense +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_test_unit_ready +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[3]; + uint8_t control; +}; + +struct scsi_send_diag +{ + uint8_t opcode; + uint8_t byte2; +#define SSD_UOL 0x01 +#define SSD_DOL 0x02 +#define SSD_SELFTEST 0x04 +#define SSD_PF 0x10 + uint8_t unused[1]; + uint8_t paramlen[2]; + uint8_t control; +}; + +struct scsi_sense +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_inquiry +{ + uint8_t opcode; + uint8_t byte2; +#define SI_EVPD 0x01 + uint8_t page_code; + uint8_t reserved; + uint8_t length; + uint8_t control; +}; + +struct scsi_mode_sense_6 +{ + uint8_t opcode; + uint8_t byte2; +#define SMS_DBD 0x08 + uint8_t page; +#define SMS_PAGE_CODE 0x3F +#define SMS_VENDOR_SPECIFIC_PAGE 0x00 +#define SMS_DISCONNECT_RECONNECT_PAGE 0x02 +#define SMS_PERIPHERAL_DEVICE_PAGE 0x09 +#define SMS_CONTROL_MODE_PAGE 0x0A +#define SMS_ALL_PAGES_PAGE 0x3F +#define SMS_PAGE_CTRL_MASK 0xC0 +#define SMS_PAGE_CTRL_CURRENT 0x00 +#define SMS_PAGE_CTRL_CHANGEABLE 0x40 +#define SMS_PAGE_CTRL_DEFAULT 0x80 +#define SMS_PAGE_CTRL_SAVED 0xC0 + uint8_t unused; + uint8_t length; + uint8_t control; +}; + +struct scsi_mode_sense_10 +{ + uint8_t opcode; + uint8_t byte2; /* same bits as small version */ + uint8_t page; /* same bits as small version */ + uint8_t unused[4]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_mode_select_6 +{ + uint8_t opcode; + uint8_t byte2; +#define SMS_SP 0x01 +#define SMS_PF 0x10 + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_mode_select_10 +{ + uint8_t opcode; + uint8_t byte2; /* same bits as small version */ + uint8_t unused[5]; + uint8_t length[2]; + uint8_t control; +}; + +/* + * When sending a mode select to a tape drive, the medium type must be 0. + */ +struct scsi_mode_hdr_6 +{ + uint8_t datalen; + uint8_t medium_type; + uint8_t dev_specific; + uint8_t block_descr_len; +}; + +struct scsi_mode_hdr_10 +{ + uint8_t datalen[2]; + uint8_t medium_type; + uint8_t dev_specific; + uint8_t reserved[2]; + uint8_t block_descr_len[2]; +}; + +struct scsi_mode_block_descr +{ + uint8_t density_code; + uint8_t num_blocks[3]; + uint8_t reserved; + uint8_t block_len[3]; +}; + +struct scsi_log_sense +{ + uint8_t opcode; + uint8_t byte2; +#define SLS_SP 0x01 +#define SLS_PPC 0x02 + uint8_t page; +#define SLS_PAGE_CODE 0x3F +#define SLS_ALL_PAGES_PAGE 0x00 +#define SLS_OVERRUN_PAGE 0x01 +#define SLS_ERROR_WRITE_PAGE 0x02 +#define SLS_ERROR_READ_PAGE 0x03 +#define SLS_ERROR_READREVERSE_PAGE 0x04 +#define SLS_ERROR_VERIFY_PAGE 0x05 +#define SLS_ERROR_NONMEDIUM_PAGE 0x06 +#define SLS_ERROR_LASTN_PAGE 0x07 +#define SLS_PAGE_CTRL_MASK 0xC0 +#define SLS_PAGE_CTRL_THRESHOLD 0x00 +#define SLS_PAGE_CTRL_CUMULATIVE 0x40 +#define SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 +#define SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 + uint8_t reserved[2]; + uint8_t paramptr[2]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_log_select +{ + uint8_t opcode; + uint8_t byte2; +/* SLS_SP 0x01 */ +#define SLS_PCR 0x02 + uint8_t page; +/* SLS_PAGE_CTRL_MASK 0xC0 */ +/* SLS_PAGE_CTRL_THRESHOLD 0x00 */ +/* SLS_PAGE_CTRL_CUMULATIVE 0x40 */ +/* SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 */ +/* SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 */ + uint8_t reserved[4]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_log_header +{ + uint8_t page; + uint8_t reserved; + uint8_t datalen[2]; +}; + +struct scsi_log_param_header { + uint8_t param_code[2]; + uint8_t param_control; +#define SLP_LP 0x01 +#define SLP_LBIN 0x02 +#define SLP_TMC_MASK 0x0C +#define SLP_TMC_ALWAYS 0x00 +#define SLP_TMC_EQUAL 0x04 +#define SLP_TMC_NOTEQUAL 0x08 +#define SLP_TMC_GREATER 0x0C +#define SLP_ETC 0x10 +#define SLP_TSD 0x20 +#define SLP_DS 0x40 +#define SLP_DU 0x80 + uint8_t param_len; +}; + +struct scsi_control_page { + uint8_t page_code; + uint8_t page_length; + uint8_t rlec; +#define SCB_RLEC 0x01 /*Report Log Exception Cond*/ + uint8_t queue_flags; +#define SCP_QUEUE_ALG_MASK 0xF0 +#define SCP_QUEUE_ALG_RESTRICTED 0x00 +#define SCP_QUEUE_ALG_UNRESTRICTED 0x10 +#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/ +#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/ + uint8_t eca_and_aen; +#define SCP_EECA 0x80 /*Enable Extended CA*/ +#define SCP_RAENP 0x04 /*Ready AEN Permission*/ +#define SCP_UAAENP 0x02 /*UA AEN Permission*/ +#define SCP_EAENP 0x01 /*Error AEN Permission*/ + uint8_t reserved; + uint8_t aen_holdoff_period[2]; +}; + +struct scsi_reserve +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_release +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_prevent +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t how; + uint8_t control; +}; +#define PR_PREVENT 0x01 +#define PR_ALLOW 0x00 + +struct scsi_sync_cache +{ + uint8_t opcode; + uint8_t byte2; + uint8_t begin_lba[4]; + uint8_t reserved; + uint8_t lb_count[2]; + uint8_t control; +}; + + +struct scsi_changedef +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused1; + uint8_t how; + uint8_t unused[4]; + uint8_t datalen; + uint8_t control; +}; + +struct scsi_read_buffer +{ + uint8_t opcode; + uint8_t byte2; +#define RWB_MODE 0x07 +#define RWB_MODE_HDR_DATA 0x00 +#define RWB_MODE_DATA 0x02 +#define RWB_MODE_DOWNLOAD 0x04 +#define RWB_MODE_DOWNLOAD_SAVE 0x05 + uint8_t buffer_id; + uint8_t offset[3]; + uint8_t length[3]; + uint8_t control; +}; + +struct scsi_write_buffer +{ + uint8_t opcode; + uint8_t byte2; + uint8_t buffer_id; + uint8_t offset[3]; + uint8_t length[3]; + uint8_t control; +}; + +struct scsi_rw_6 +{ + uint8_t opcode; + uint8_t addr[3]; +/* only 5 bits are valid in the MSB address byte */ +#define SRW_TOPADDR 0x1F + uint8_t length; + uint8_t control; +}; + +struct scsi_rw_10 +{ + uint8_t opcode; +#define SRW10_RELADDR 0x01 +#define SRW10_FUA 0x08 +#define SRW10_DPO 0x10 + uint8_t byte2; + uint8_t addr[4]; + uint8_t reserved; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_rw_12 +{ + uint8_t opcode; +#define SRW12_RELADDR 0x01 +#define SRW12_FUA 0x08 +#define SRW12_DPO 0x10 + uint8_t byte2; + uint8_t addr[4]; + uint8_t length[4]; + uint8_t reserved; + uint8_t control; +}; + +struct scsi_start_stop_unit +{ + uint8_t opcode; + uint8_t byte2; +#define SSS_IMMED 0x01 + uint8_t reserved[2]; + uint8_t how; +#define SSS_START 0x01 +#define SSS_LOEJ 0x02 + uint8_t control; +}; + +#define SC_SCSI_1 0x01 +#define SC_SCSI_2 0x03 + +/* + * Opcodes + */ + +#define TEST_UNIT_READY 0x00 +#define REQUEST_SENSE 0x03 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define INQUIRY 0x12 +#define MODE_SELECT_6 0x15 +#define MODE_SENSE_6 0x1a +#define START_STOP_UNIT 0x1b +#define START_STOP 0x1b +#define RESERVE 0x16 +#define RELEASE 0x17 +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define PREVENT_ALLOW 0x1e +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define POSITION_TO_ELEMENT 0x2b +#define SYNCHRONIZE_CACHE 0x35 +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define CHANGE_DEFINITION 0x40 +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#ifdef XXXCAM +#define MODE_SENSE_10 0x5A +#endif +#define MODE_SELECT_10 0x55 +#define MOVE_MEDIUM 0xa5 +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define READ_ELEMENT_STATUS 0xb8 + + +/* + * Device Types + */ +#define T_DIRECT 0x00 +#define T_SEQUENTIAL 0x01 +#define T_PRINTER 0x02 +#define T_PROCESSOR 0x03 +#define T_WORM 0x04 +#define T_CDROM 0x05 +#define T_SCANNER 0x06 +#define T_OPTICAL 0x07 +#define T_CHANGER 0x08 +#define T_COMM 0x09 +#define T_ASC0 0x0a +#define T_ASC1 0x0b +#define T_STORARRAY 0x0c +#define T_ENCLOSURE 0x0d +#define T_RBC 0x0e +#define T_OCRW 0x0f +#define T_NODEVICE 0x1F +#define T_ANY 0xFF /* Used in Quirk table matches */ + +#define T_REMOV 1 +#define T_FIXED 0 + +/* + * This length is the initial inquiry length used by the probe code, as + * well as the legnth necessary for aic_print_inquiry() to function + * correctly. If either use requires a different length in the future, + * the two values should be de-coupled. + */ +#define SHORT_INQUIRY_LENGTH 36 + +struct scsi_inquiry_data +{ + uint8_t device; +#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f) +#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5) +#define SID_QUAL_LU_CONNECTED 0x00 /* + * The specified peripheral device + * type is currently connected to + * logical unit. If the target cannot + * determine whether or not a physical + * device is currently connected, it + * shall also use this peripheral + * qualifier when returning the INQUIRY + * data. This peripheral qualifier + * does not mean that the device is + * ready for access by the initiator. + */ +#define SID_QUAL_LU_OFFLINE 0x01 /* + * The target is capable of supporting + * the specified peripheral device type + * on this logical unit; however, the + * physical device is not currently + * connected to this logical unit. + */ +#define SID_QUAL_RSVD 0x02 +#define SID_QUAL_BAD_LU 0x03 /* + * The target is not capable of + * supporting a physical device on + * this logical unit. For this + * peripheral qualifier the peripheral + * device type shall be set to 1Fh to + * provide compatibility with previous + * versions of SCSI. All other + * peripheral device type values are + * reserved for this peripheral + * qualifier. + */ +#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) + uint8_t dev_qual2; +#define SID_QUAL2 0x7F +#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) + uint8_t version; +#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07) +#define SCSI_REV_0 0 +#define SCSI_REV_CCS 1 +#define SCSI_REV_2 2 +#define SCSI_REV_SPC 3 +#define SCSI_REV_SPC2 4 + +#define SID_ECMA 0x38 +#define SID_ISO 0xC0 + uint8_t response_format; +#define SID_AENC 0x80 +#define SID_TrmIOP 0x40 + uint8_t additional_length; + uint8_t reserved[2]; + uint8_t flags; +#define SID_SftRe 0x01 +#define SID_CmdQue 0x02 +#define SID_Linked 0x08 +#define SID_Sync 0x10 +#define SID_WBus16 0x20 +#define SID_WBus32 0x40 +#define SID_RelAdr 0x80 +#define SID_VENDOR_SIZE 8 + char vendor[SID_VENDOR_SIZE]; +#define SID_PRODUCT_SIZE 16 + char product[SID_PRODUCT_SIZE]; +#define SID_REVISION_SIZE 4 + char revision[SID_REVISION_SIZE]; + /* + * The following fields were taken from SCSI Primary Commands - 2 + * (SPC-2) Revision 14, Dated 11 November 1999 + */ +#define SID_VENDOR_SPECIFIC_0_SIZE 20 + uint8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE]; + /* + * An extension of SCSI Parallel Specific Values + */ +#define SID_SPI_IUS 0x01 +#define SID_SPI_QAS 0x02 +#define SID_SPI_CLOCK_ST 0x00 +#define SID_SPI_CLOCK_DT 0x04 +#define SID_SPI_CLOCK_DT_ST 0x0C +#define SID_SPI_MASK 0x0F + uint8_t spi3data; + uint8_t reserved2; + /* + * Version Descriptors, stored 2 byte values. + */ + uint8_t version1[2]; + uint8_t version2[2]; + uint8_t version3[2]; + uint8_t version4[2]; + uint8_t version5[2]; + uint8_t version6[2]; + uint8_t version7[2]; + uint8_t version8[2]; + + uint8_t reserved3[22]; + +#define SID_VENDOR_SPECIFIC_1_SIZE 160 + uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE]; +}; + +struct scsi_vpd_unit_serial_number +{ + uint8_t device; + uint8_t page_code; +#define SVPD_UNIT_SERIAL_NUMBER 0x80 + uint8_t reserved; + uint8_t length; /* serial number length */ +#define SVPD_SERIAL_NUM_SIZE 251 + uint8_t serial_num[SVPD_SERIAL_NUM_SIZE]; +}; + +struct scsi_read_capacity +{ + uint8_t opcode; + uint8_t byte2; + uint8_t addr[4]; + uint8_t unused[3]; + uint8_t control; +}; + +struct scsi_read_capacity_data +{ + uint8_t addr[4]; + uint8_t length[4]; +}; + +struct scsi_report_luns +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[3]; + uint8_t addr[4]; + uint8_t control; +}; + +struct scsi_report_luns_data { + uint8_t length[4]; /* length of LUN inventory, in bytes */ + uint8_t reserved[4]; /* unused */ + /* + * LUN inventory- we only support the type zero form for now. + */ + struct { + uint8_t lundata[8]; + } luns[1]; +}; +#define RPL_LUNDATA_ATYP_MASK 0xc0 /* MBZ for type 0 lun */ +#define RPL_LUNDATA_T0LUN 1 /* @ lundata[1] */ + + +struct scsi_sense_data +{ + uint8_t error_code; +#define SSD_ERRCODE 0x7F +#define SSD_CURRENT_ERROR 0x70 +#define SSD_DEFERRED_ERROR 0x71 +#define SSD_ERRCODE_VALID 0x80 + uint8_t segment; + uint8_t flags; +#define SSD_KEY 0x0F +#define SSD_KEY_NO_SENSE 0x00 +#define SSD_KEY_RECOVERED_ERROR 0x01 +#define SSD_KEY_NOT_READY 0x02 +#define SSD_KEY_MEDIUM_ERROR 0x03 +#define SSD_KEY_HARDWARE_ERROR 0x04 +#define SSD_KEY_ILLEGAL_REQUEST 0x05 +#define SSD_KEY_UNIT_ATTENTION 0x06 +#define SSD_KEY_DATA_PROTECT 0x07 +#define SSD_KEY_BLANK_CHECK 0x08 +#define SSD_KEY_Vendor_Specific 0x09 +#define SSD_KEY_COPY_ABORTED 0x0a +#define SSD_KEY_ABORTED_COMMAND 0x0b +#define SSD_KEY_EQUAL 0x0c +#define SSD_KEY_VOLUME_OVERFLOW 0x0d +#define SSD_KEY_MISCOMPARE 0x0e +#define SSD_KEY_RESERVED 0x0f +#define SSD_ILI 0x20 +#define SSD_EOM 0x40 +#define SSD_FILEMARK 0x80 + uint8_t info[4]; + uint8_t extra_len; + uint8_t cmd_spec_info[4]; + uint8_t add_sense_code; + uint8_t add_sense_code_qual; + uint8_t fru; + uint8_t sense_key_spec[3]; +#define SSD_SCS_VALID 0x80 +#define SSD_FIELDPTR_CMD 0x40 +#define SSD_BITPTR_VALID 0x08 +#define SSD_BITPTR_VALUE 0x07 +#define SSD_MIN_SIZE 18 + uint8_t extra_bytes[14]; +#define SSD_FULL_SIZE sizeof(struct scsi_sense_data) +}; + +struct scsi_mode_header_6 +{ + uint8_t data_length; /* Sense data length */ + uint8_t medium_type; + uint8_t dev_spec; + uint8_t blk_desc_len; +}; + +struct scsi_mode_header_10 +{ + uint8_t data_length[2];/* Sense data length */ + uint8_t medium_type; + uint8_t dev_spec; + uint8_t unused[2]; + uint8_t blk_desc_len[2]; +}; + +struct scsi_mode_page_header +{ + uint8_t page_code; + uint8_t page_length; +}; + +struct scsi_mode_blk_desc +{ + uint8_t density; + uint8_t nblocks[3]; + uint8_t reserved; + uint8_t blklen[3]; +}; + +#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */ +#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */ + + +/* + * Status Byte + */ +#define SCSI_STATUS_OK 0x00 +#define SCSI_STATUS_CHECK_COND 0x02 +#define SCSI_STATUS_COND_MET 0x04 +#define SCSI_STATUS_BUSY 0x08 +#define SCSI_STATUS_INTERMED 0x10 +#define SCSI_STATUS_INTERMED_COND_MET 0x14 +#define SCSI_STATUS_RESERV_CONFLICT 0x18 +#define SCSI_STATUS_CMD_TERMINATED 0x22 /* Obsolete in SAM-2 */ +#define SCSI_STATUS_QUEUE_FULL 0x28 +#define SCSI_STATUS_ACA_ACTIVE 0x30 +#define SCSI_STATUS_TASK_ABORTED 0x40 + +struct scsi_inquiry_pattern { + uint8_t type; + uint8_t media_type; +#define SIP_MEDIA_REMOVABLE 0x01 +#define SIP_MEDIA_FIXED 0x02 + const char *vendor; + const char *product; + const char *revision; +}; + +struct scsi_static_inquiry_pattern { + uint8_t type; + uint8_t media_type; + char vendor[SID_VENDOR_SIZE+1]; + char product[SID_PRODUCT_SIZE+1]; + char revision[SID_REVISION_SIZE+1]; +}; + +struct scsi_sense_quirk_entry { + struct scsi_inquiry_pattern inq_pat; + int num_sense_keys; + int num_ascs; + struct sense_key_table_entry *sense_key_info; + struct asc_table_entry *asc_info; +}; + +struct sense_key_table_entry { + uint8_t sense_key; + uint32_t action; + const char *desc; +}; + +struct asc_table_entry { + uint8_t asc; + uint8_t ascq; + uint32_t action; + const char *desc; +}; + +struct op_table_entry { + uint8_t opcode; + uint16_t opmask; + const char *desc; +}; + +struct scsi_op_quirk_entry { + struct scsi_inquiry_pattern inq_pat; + int num_ops; + struct op_table_entry *op_table; +}; + +typedef enum { + SSS_FLAG_NONE = 0x00, + SSS_FLAG_PRINT_COMMAND = 0x01 +} scsi_sense_string_flags; + +extern const char *scsi_sense_key_text[]; + +/************************* Large Disk Handling ********************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +static __inline int aic_sector_div(u_long capacity, int heads, int sectors); + +static __inline int +aic_sector_div(u_long capacity, int heads, int sectors) +{ + return (capacity / (heads * sectors)); +} +#else +static __inline int aic_sector_div(sector_t capacity, int heads, int sectors); + +static __inline int +aic_sector_div(sector_t capacity, int heads, int sectors) +{ + /* ugly, ugly sector_div calling convention.. */ + sector_div(capacity, (heads * sectors)); + return (int)capacity; +} +#endif + +/**************************** Module Library Hack *****************************/ +/* + * What we'd like to do is have a single "scsi library" module that both the + * aic7xxx and aic79xx drivers could load and depend on. A cursory examination + * of implementing module dependencies in Linux (handling the install and + * initrd cases) does not look promissing. For now, we just duplicate this + * code in both drivers using a simple symbol renaming scheme that hides this + * hack from the drivers. + */ +#define AIC_LIB_ENTRY_CONCAT(x, prefix) prefix ## x +#define AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix) +#define AIC_LIB_ENTRY(x) AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX) + +#define aic_sense_desc AIC_LIB_ENTRY(_sense_desc) +#define aic_sense_error_action AIC_LIB_ENTRY(_sense_error_action) +#define aic_error_action AIC_LIB_ENTRY(_error_action) +#define aic_op_desc AIC_LIB_ENTRY(_op_desc) +#define aic_cdb_string AIC_LIB_ENTRY(_cdb_string) +#define aic_print_inquiry AIC_LIB_ENTRY(_print_inquiry) +#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate) +#define aic_calc_syncparam AIC_LIB_ENTRY(_calc_syncparam) +#define aic_calc_speed AIC_LIB_ENTRY(_calc_speed) +#define aic_inquiry_match AIC_LIB_ENTRY(_inquiry_match) +#define aic_static_inquiry_match AIC_LIB_ENTRY(_static_inquiry_match) + +/******************************************************************************/ + +void aic_sense_desc(int /*sense_key*/, int /*asc*/, + int /*ascq*/, struct scsi_inquiry_data*, + const char** /*sense_key_desc*/, + const char** /*asc_desc*/); +aic_sense_action aic_sense_error_action(struct scsi_sense_data*, + struct scsi_inquiry_data*, + uint32_t /*sense_flags*/); +uint32_t aic_error_action(struct scsi_cmnd *, + struct scsi_inquiry_data *, + cam_status, u_int); + +#define SF_RETRY_UA 0x01 +#define SF_NO_PRINT 0x02 +#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */ +#define SF_PRINT_ALWAYS 0x08 + + +const char * aic_op_desc(uint16_t /*opcode*/, struct scsi_inquiry_data*); +char * aic_cdb_string(uint8_t* /*cdb_ptr*/, char* /*cdb_string*/, + size_t /*len*/); +void aic_print_inquiry(struct scsi_inquiry_data*); + +u_int aic_calc_syncsrate(u_int /*period_factor*/); +u_int aic_calc_syncparam(u_int /*period*/); +u_int aic_calc_speed(u_int width, u_int period, u_int offset, + u_int min_rate); + +int aic_inquiry_match(caddr_t /*inqbuffer*/, + caddr_t /*table_entry*/); +int aic_static_inquiry_match(caddr_t /*inqbuffer*/, + caddr_t /*table_entry*/); + + +static __inline void scsi_extract_sense(struct scsi_sense_data *sense, + int *error_code, int *sense_key, + int *asc, int *ascq); +static __inline void scsi_ulto2b(uint32_t val, uint8_t *bytes); +static __inline void scsi_ulto3b(uint32_t val, uint8_t *bytes); +static __inline void scsi_ulto4b(uint32_t val, uint8_t *bytes); +static __inline uint32_t scsi_2btoul(uint8_t *bytes); +static __inline uint32_t scsi_3btoul(uint8_t *bytes); +static __inline int32_t scsi_3btol(uint8_t *bytes); +static __inline uint32_t scsi_4btoul(uint8_t *bytes); + +static __inline void scsi_extract_sense(struct scsi_sense_data *sense, + int *error_code, int *sense_key, + int *asc, int *ascq) +{ + *error_code = sense->error_code & SSD_ERRCODE; + *sense_key = sense->flags & SSD_KEY; + *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; + *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; +} + +static __inline void +scsi_ulto2b(uint32_t val, uint8_t *bytes) +{ + + bytes[0] = (val >> 8) & 0xff; + bytes[1] = val & 0xff; +} + +static __inline void +scsi_ulto3b(uint32_t val, uint8_t *bytes) +{ + + bytes[0] = (val >> 16) & 0xff; + bytes[1] = (val >> 8) & 0xff; + bytes[2] = val & 0xff; +} + +static __inline void +scsi_ulto4b(uint32_t val, uint8_t *bytes) +{ + + bytes[0] = (val >> 24) & 0xff; + bytes[1] = (val >> 16) & 0xff; + bytes[2] = (val >> 8) & 0xff; + bytes[3] = val & 0xff; +} + +static __inline uint32_t +scsi_2btoul(uint8_t *bytes) +{ + uint32_t rv; + + rv = (bytes[0] << 8) | + bytes[1]; + return (rv); +} + +static __inline uint32_t +scsi_3btoul(uint8_t *bytes) +{ + uint32_t rv; + + rv = (bytes[0] << 16) | + (bytes[1] << 8) | + bytes[2]; + return (rv); +} + +static __inline int32_t +scsi_3btol(uint8_t *bytes) +{ + uint32_t rc = scsi_3btoul(bytes); + + if (rc & 0x00800000) + rc |= 0xff000000; + + return (int32_t) rc; +} + +static __inline uint32_t +scsi_4btoul(uint8_t *bytes) +{ + uint32_t rv; + + rv = (bytes[0] << 24) | + (bytes[1] << 16) | + (bytes[2] << 8) | + bytes[3]; + return (rv); +} + +#endif /*_SCSI_SCSI_ALL_H*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/cam.h linux.21pre4-ac6/drivers/scsi/aic7xxx/cam.h --- linux.21pre4/drivers/scsi/aic7xxx/cam.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/cam.h 2003-02-07 15:49:47.000000000 +0000 @@ -29,13 +29,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#11 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#15 $ */ #ifndef _AIC7XXX_CAM_H #define _AIC7XXX_CAM_H 1 -/* Provide a mapping from CAM constructs to Linux SCSI constructs */ +#include #define CAM_BUS_WILDCARD ((u_int)~0) #define CAM_TARGET_WILDCARD ((u_int)~0) @@ -43,56 +43,34 @@ /* CAM Status field values */ typedef enum { - /* CCB request is in progress */ - CAM_REQ_INPROG = 0x3F, /* Some value unused by Linux */ - /* CCB request completed without error */ - CAM_REQ_CMP = DID_OK, - /* CCB request aborted by the host */ - CAM_REQ_ABORTED = DID_ABORT, - /* Unable to abort CCB request */ - CAM_UA_ABORT = DID_ERROR, - /* CCB request completed with an error */ - CAM_REQ_CMP_ERR = DID_ERROR, - /* CAM subsytem is busy */ - CAM_BUSY = DID_BUS_BUSY, - /* CCB request was invalid */ - CAM_REQ_INVALID = DID_BAD_TARGET, - /* Supplied Path ID is invalid */ - CAM_PATH_INVALID = DID_BAD_TARGET, - /* Target Selection Timeout */ - CAM_SEL_TIMEOUT = DID_NO_CONNECT, - /* Command timeout */ - CAM_CMD_TIMEOUT = DID_ERROR, /* - * Should never occur in Linux - * as the upper level code - * handles all timeout processing. - */ - /* SCSI error, look at error code in CCB */ - CAM_SCSI_STATUS_ERROR = DID_OK, /* Linux looks at status byte */ - /* SCSI Bus Reset Sent/Received */ - CAM_SCSI_BUS_RESET = DID_RESET, - /* Uncorrectable parity error occurred */ - CAM_UNCOR_PARITY = DID_PARITY, - /* Autosense: request sense cmd fail */ - CAM_AUTOSENSE_FAIL = DID_ERROR, - /* No HBA Detected Error */ - CAM_NO_HBA = DID_ERROR, - /* Data Overrun error */ - CAM_DATA_RUN_ERR = DID_ERROR, - /* Unexpected Bus Free */ - CAM_UNEXP_BUSFREE = DID_ERROR, - /* CCB length supplied is inadequate */ - CAM_CCB_LEN_ERR = DID_ERROR, - /* Unable to provide requested capability */ - CAM_PROVIDE_FAIL = DID_ERROR, - /* A SCSI BDR msg was sent to target */ - CAM_BDR_SENT = DID_RESET, - /* CCB request terminated by the host */ - CAM_REQ_TERMIO = DID_ERROR, - /* Unrecoverable Host Bus Adapter Error */ - CAM_UNREC_HBA_ERROR = DID_ERROR, - /* The request was too large for this host */ - CAM_REQ_TOO_BIG = DID_ERROR, + CAM_REQ_INPROG, /* CCB request is in progress */ + CAM_REQ_CMP, /* CCB request completed without error */ + CAM_REQ_ABORTED, /* CCB request aborted by the host */ + CAM_UA_ABORT, /* Unable to abort CCB request */ + CAM_REQ_CMP_ERR, /* CCB request completed with an error */ + CAM_BUSY, /* CAM subsytem is busy */ + CAM_REQ_INVALID, /* CCB request was invalid */ + CAM_PATH_INVALID, /* Supplied Path ID is invalid */ + CAM_SEL_TIMEOUT, /* Target Selection Timeout */ + CAM_CMD_TIMEOUT, /* Command timeout */ + CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */ + CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */ + CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */ + CAM_AUTOSENSE_FAIL, /* Autosense: request sense cmd fail */ + CAM_NO_HBA, /* No HBA Detected Error */ + CAM_DATA_RUN_ERR, /* Data Overrun error */ + CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */ + CAM_SEQUENCE_FAIL, /* Protocol Violation */ + CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */ + CAM_PROVIDE_FAIL, /* Unable to provide requested capability */ + CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */ + CAM_REQ_TERMIO, /* CCB request terminated by the host */ + CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */ + CAM_REQ_TOO_BIG, /* The request was too large for this host */ + CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */ + CAM_MSG_REJECT_REC, /* Message Reject Received */ + CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */ + CAM_RESRC_UNAVAIL, /* Resource Unavailable */ /* * This request should be requeued to preserve * transaction ordering. This typically occurs @@ -101,7 +79,8 @@ * requests for the target at the sim level * back into the XPT queue. */ - CAM_REQUEUE_REQ = DID_BUS_BUSY, + CAM_REQUEUE_REQ, + CAM_DEV_QFRZN = 0x40, CAM_STATUS_MASK = 0x3F } cam_status; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/CHANGELOG linux.21pre4-ac6/drivers/scsi/aic7xxx/CHANGELOG --- linux.21pre4/drivers/scsi/aic7xxx/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/CHANGELOG 2003-01-22 21:48:34.000000000 +0000 @@ -0,0 +1,23260 @@ +Change 1861 by scottl@scottl-template on 2003/01/21 18:26:00 + + Update driver version to 1.3.0 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#108 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#25 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#28 edit + +Change 1859 by scottl@scottl-template on 2003/01/21 15:27:08 + + readme.txt: + README.aic7xxx: + Convert tabs to spaces. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#4 edit +... //depot/linux_mod_devel/scsi.aic7xxx/readme.txt#4 edit + +Change 1858 by scottl@scottl-template on 2003/01/21 14:43:42 + + readme.txt: + README.aic79xx: + Fix the wording of the 1.3.0 version history line + Replace tabs with spaces. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#6 edit +... //depot/linux_mod_devel/scsi.aic79xx/readme.txt#18 edit + +Change 1856 by gibbs@bitkeeper-linux-2.5 on 2003/01/21 12:37:08 + + Update the embedded aic7xxx driver README. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#3 edit + +Change 1854 by gibbs@bitkeeper-linux-2.5 on 2003/01/21 12:12:27 + + Update aic79xx README used for embedding. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#5 edit + +Change 1851 by gibbs@bitkeeper-linux-2.5 on 2003/01/20 16:45:59 + + Bump aic7xxx driver to version 6.2.28. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#123 edit + +Change 1850 by scottl@scottl-template on 2003/01/20 16:29:28 + + Update driver version to 1.3.0.RC2 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#107 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#24 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#27 edit + +Change 1849 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 16:23:35 + + aic79xx_osm.c: + Correct the BUILD_SCSIID macro to take into account the + future removal of target, lun and channel from the + scsi_cmnd structure. + + Clean up ahd_linux_initialize_scsi_bus(). The indirection + was left over from the port from aic7xxx where twin + channel adapters come into play. The result in the aic79xx + driver just looked silly. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 edit + +Change 1848 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 16:20:47 + + aic79xx.c: + Fix a missed goal.period -> goal.offset change. In + this case, the bug resulted in comparing a period + against an offset. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#156 edit + +Change 1847 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 10:14:37 + + aic79xx.c: + aic7xxx.c: + Indicate the features, bugs, and flags set in the softc + that are used to control firmware patch download when + booting verbose. + + aic7xxx.c: + Fix an ifdef bug that caused sequencer debugging to + be enabled always. + + Clear the ultraenb flag in our tstate during startup. + The ultraenbled'ness of a device is recorded in the user + transfer settings. tstate->ultraenb bitmask indicates + which devices we have negotiated an ultra speed with. + Just after initialization, we are async. Setting the + ultraenb flag while async seems to be harmless, but it + was confusing to see the ULTRAENB flag set in the SCB. + + Allow ahc_dump_card_state() to be called when the sequencer + is not paused. Add dump card state markers as in the U320 + driver. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#155 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#112 edit + +Change 1846 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 09:53:07 + + aic79xx_osm.c: + aic7xxx_osm.c: + Dump card state on DV timeouts when SHOW_DV debug + option is set. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#114 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#179 edit + +Change 1845 by gibbs@bitkeeper-linux-2.4 on 2003/01/17 14:46:30 + + aic79xx.c: + aic7xxx.c: + Force an SDTR after a rejected WDTR if the + syncrate is unkonwn. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#154 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#111 edit + +Change 1844 by gibbs@bitkeeper-linux-2.5 on 2003/01/17 13:20:26 + + aic7xxx_osm.h: + Bump driver version to 6.2.27. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#122 edit + +Change 1843 by gibbs@overdrive on 2003/01/17 13:06:51 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#22 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#23 edit + +Change 1842 by scottl@scottl-template on 2003/01/17 12:39:50 + + Update driver version to 1.3.0.RC1 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#106 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#23 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#26 edit + +Change 1841 by gibbs@bitkeeper-linux-2.4 on 2003/01/17 12:39:21 + + aic7xxx.c: + aic7xxx.h: + aic7xxx_pci.c: + Take another stab at disabling PCI errors in the aic7xxx + driver. We now just clear the PERRRESEN bit in the command + register. This option is now enabled via a new flag in + ahc->flags: AHC_DISABLE_PCI_PERR. + + aic7xxx_osm.c: + Hook the already existing pci_parity option. Parity + defaults to off since so many Linux users have clunky + VIA chipsets that cause spurious warnings. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#110 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#70 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#178 edit + +Change 1840 by scottl@scottl-template on 2003/01/16 18:53:11 + + aic7xxx_osm.c: + Fix missed AHD->AHC substitutions from last commit. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#177 edit + +Change 1839 by scottl@scottl-template on 2003/01/16 18:51:20 + + aic7xxx_osm.c: + Traverse the array of targets and devices in + ahc_platform_free() and remove each device. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#176 edit + +Change 1838 by scottl@scottl-template on 2003/01/16 18:46:46 + + aic79xx_osm.c: + Traverse the arrays of targets and devices to free each + device when ahd_platform_free() is called. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#113 edit + +Change 1837 by gibbs@bitkeeper-linux-2.4 on 2003/01/16 16:24:58 + + aic79xx_osm.c: + aic79xx_osm.h: + aic7xxx_osm.c: + aic7xxx_osm.h: + Adapt to upcoming 2.5.X change. The host, target, channel, + and lun fields are disappearing from the scsi_cmnd structure. + We must instead get this data from the scsi_device structure + hung off the command. The only trick in this is an update + to how we fake up DV commands. We now need to fake up a + scsi_device too. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#112 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#105 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#175 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#121 edit + +Change 1836 by gibbs@bitkeeper-linux-2.4 on 2003/01/16 14:39:58 + + aic79xx.c: + Only send an async update to the luns affected by + the device reset now that ahd_handle_devreset is + called for lun resets too. + + aic79xx_osm.c: + Only bother dumping card state after we've determined + that the command to be aborted is still active on the + controller. + + aic79xx_osm.c: + aic7xxx_osm.c: + Have the AC_SENT_BDR handler manually set the was_reset + and expecting_cc_ua flags in all devices that are + affected by the target/lun reset. + + Never allow cmd->retries to go below zero. cmd->retries + is not incremented when a command goes through recovery. + This could allow the retry count to suddenly become a + very large number. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#153 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#111 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#174 edit + +Change 1834 by gibbs@aslan on 2003/01/15 21:32:22 + + aic7xxx.seq: + Correct a target mode regression that prevented the + driver from properly handling unexpected + messages (negotiation, etc). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 edit + +Change 1833 by gibbs@bitkeeper-linux-2.4 on 2003/01/15 21:27:13 + + aic79xx_osm.c: + Split out the abort handler from the dev reset handler. + The dev reset handler will now use a new SCB to issue + the dev reset. This avoids a potential problem with + SCB race issues for dev resets. + + Manually set the task management function now that + ahd_queue_scb() doesn't do this for us. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#110 edit + +Change 1832 by gibbs@bitkeeper-linux-2.4 on 2003/01/15 21:20:59 + + aic79xx.c: + Update copyright for 2003. + + Modify ahd_handle_devreset so that it can handle + lun resets in addition to target resets. + + Correct a bug in the illegal phase handler that + caused us to drop down to narrow when handling the + unexpected command phase case after 3rd party + reset of a packetized device. + + Add some diagnostics to the task management function code. + + Use ahd_handle_devreset for lun and target reset task + management functions. + + Handle the abort task TMF race case better. We now + wait until any current selections are over and then + set the TMF back to zero. This should cause the sequencer + to ignore the abort TMF completion should it occur. + + Correct a regression in ahd_sent_msg that caused it to fail + to recognize any 1byte messages other than identify. + + aic79xx_inline.h: + Allow callers to ahd_send_scb() to set the task management + function. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#152 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 edit + +Change 1831 by scottl@scottl-template on 2003/01/15 17:37:56 + + Move aic_error_action and aic_calc_speed out of the osm's and + into aiclib. Do slight header adjustment to make it work. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#69 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#109 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#104 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#173 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#120 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#6 edit + +Change 1830 by gibbs@bitkeeper-linux-2.4 on 2003/01/15 15:33:45 + + aic79xx_osm.c: + aic79xx_osm.h: + aic7xxx_osm.c: + aic7xxx_osm.h: + Correct use of AHD_EH_UP_SEMAPHORE. This should + unbreak the recovery handler. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#108 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#103 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#172 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#119 edit + +Change 1829 by gibbs@overdrive on 2003/01/15 11:18:20 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#54 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#35 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#55 edit + +Change 1828 by gibbs@bitkeeper-linux-2.5 on 2003/01/15 10:19:07 + + aic79xx_osm.c: + Continue to dump the card state on timeouts for the + time being. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#107 edit + +Change 1827 by gibbs@bitkeeper-linux-2.5 on 2003/01/15 10:18:44 + + aic7xxx.h: + Reformat a few comments to follow driver style. + + Add a controller flag that indicates that a controller + has not been initialized by the BIOS. + + aic7xxx.c: + Disable PCI error interrupts on PCI adapters prior + to the Ultra2 controllers. This brings us in line + with what the other Adaptec drivers do, but it is + still not clear exactly why this status reporting + might be broken. + + Don't set our width to unknown when forcing negotiation + on narrow controllers. This will confuse the negotiation + code into negotiating with a wide message on narrow + controllers. + + In ahc_reset(), record whether or not we found the + controller in a reset state. If the controller was + already reset, assume that no BIOS has initialized + the controller and ignore left over scratch ram + settings. + + In ahc_dump_card_state() fix a logic reversal. The + SCSIPHASE register only exists on U160 controllers. + The SCSISIGI register exists on all controllers. Not + the other way around. + + aic7xxx_osm.c: + Format sense diagnostic in 16 byte rows. + + Remove a superfluous diagnostic printf. + + aic7xxx_pci.c: + Ensure that the PCIERRGENDIS bit is set in the + PCIERRGEN config space register. Perhaps this + is a reason for the spurios parity errors reported + on U160 controllers. + + Honor the AHC_NO_BIOS_INIT flag. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#109 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#68 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#56 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#171 edit + +Change 1826 by gibbs@bitkeeper-linux-2.5 on 2003/01/15 10:10:47 + + aic79xx.reg: + Add SEQINT codes for handling task management + completions. + + aic79xx.seq: + Add notifications to the host of task management + completions as well as the completions for commands + that have a task management function pending but + not yet sent. + + Hold a critical section during select-out processing + until we have a fully identified connection. This + removes a race condition with the legacy abort handler. + + Correct a few spelling errors in some comments. + + aic79xx_core.c + Flush the good status FIFO in ahd_flush_qoutfifo. + This routine should now catch all completed commands + in their various locations and states. + + Add support for task management function completions. + + If we are a narrow controller, don't set the current + width to unknown when forcing a future negotiation. + This just confuses the code into attempting a wide + negotiation on a narrow bus. + + aic79xx_osm.c: + Enable recovery code. Behavior should be similar to + that of the aic7xxx driver for legacy devices. For + packetized devices, we will now queue the appropriate + task management function. + + When printing out sense information, format in 16 + byte rows. + + scsi_iu.h: + Add definitions for the task management codes sent + in SPI4 command information units. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#151 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#60 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#78 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#106 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#4 edit + +Change 1825 by gibbs@bitkeeper-linux-2.5 on 2003/01/10 16:42:54 + + aic79xx_osm.c: + aic7xxx_osm.c: + Short cicuit domain validation if the inquiry + data for the device shows that it does not support + sync or wide transfers. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#105 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#170 edit + +Change 1820 by gibbs@bitkeeper-linux-2.5 on 2003/01/07 19:47:06 + + aic79xx_osm_pci.c: + Always set the pci_dma_mask. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#20 edit + +Change 1819 by gibbs@bitkeeper-linux-2.5 on 2003/01/07 19:44:50 + + aic7xxx_osm_pci.c: + Always initialize the pci_dma_mask. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#43 edit + +Change 1818 by gibbs@overdrive on 2003/01/07 19:11:29 + + aic79xx_osm.h: + aic7xxx_osm.h: + Correct version numbers. We are now at aic7xxx 6.2.26, + and aic79xx 1.3.0_BETA2. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#102 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#118 edit + +Change 1817 by scottl@scottl-template on 2003/01/07 19:03:54 + + Update driver version to 6.2.24 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#117 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#10 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#14 edit + +Change 1815 by scottl@scottl-belfalas-template on 2003/01/07 18:58:15 + + Forward declare and static-ize aic7xxx_setup(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#169 edit + +Change 1814 by gibbs@bitkeeper-linux-2.5 on 2003/01/07 18:35:16 + + aic7xxx_osm.h: + Add PCIM_CMD_SERRESPEN definition. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#116 edit + +Change 1813 by gibbs@overdrive on 2003/01/07 18:32:44 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#22 edit + +Change 1812 by gibbs@aslan on 2003/01/07 17:38:33 + + aic79xx_pci.c: + aic7xxx_pci.c: + Disable SERR and pause the controller prior to performing + our mmapped I/O test. This should handle the case of + controllers that do not "auto-access pause". For legacy + controllers, use SCB ram instead of scratch ram since + the latter may contain settings left over from the BIOS + that we will use if an seeprom is not found. + + aic7xxx.h: + aic7xxx.c: + Remove the probe_stack code. The stack is always + 4 deep on legacy controllers, so probing is pointless. + This also avoids an issue where probing the stack would + upset the aic7770. + + aic7xxx.c: + Print out the ERROR register in ahc_dump_card_state(). + + aic7xxx.reg: + Add a constant for the controller's stack size. + + aic7xxx.seq: + Style nit. The source is implied to be the destination + unless overridden in an "and" instruction. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#61 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#108 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#67 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#55 edit + +Change 1811 by gibbs@aslan on 2003/01/07 14:20:42 + + aicasm_gram.y: + Remove the numerical_value portion of the grammer + which is no longer referenced. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 edit + +Change 1810 by scottl@scottl-template on 2003/01/07 09:29:00 + + Update driver version to 1.3.0.BETA1 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#101 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#21 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#24 edit + +Change 1808 by gibbs@bitkeeper-linux-2.5 on 2003/01/06 14:21:46 + + aic7xxx_osm.c: + Correctly account for twin channel adapters in + pre-allocating target devices for initial DV scan. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#168 edit + +Change 1807 by gibbs@bitkeeper-linux-2.5 on 2003/01/06 11:58:41 + + aic79xx.c: + Correct ahd_find_syncrate() so that the actual + syncrate and not the "maximum syncrate" is modified + by tests that limit syncrate based on PPR options. + + aic7xxx.c: + aic79xx.c: + Enhance residual diagnostic to indicate if the residual + if for sense information or normal data transfers. + + aic79xx_osm.c: + aic7xxx_osm.c: + For the initial DV scan, only instantiate target objects + for IDs that can exist (i.e. only up to ID 7 on narrow + + Record the maximum bus width for fallback in the target + structure and use this to ensure we never fallback to + wide on a narrow target. + channels). + + Add DV diagnostic for failed inquiry verification. + + aic79xx_osm.h: + aic7xxx_osm.h: + Add dv_max_width to target structures and shrink several + fields to 8bits. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#150 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#107 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#104 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#100 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#167 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#115 edit +... //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#5 edit + +Change 1805 by scottl@scottl-junior-freebsd on 2002/12/30 21:13:11 + + Convert the use of MAXBSIZE in the dma tag to more appropriate values. + Use BUS_SPACE_MAXSIZE_32BIT for the parent dma tags, and + (NSEGS - 1) * PAGE_SIZE for the data buffer tags. FreeBSD/sparc64 is + more strick about checking these values that other arches. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#149 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#106 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#10 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#12 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#12 edit + +Change 1804 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 18:59:49 + + aic79xx_osm.h: + Bump version number to 1.3.0_ALPHA6 + + aic7xxx_osm.h: + Bump version number to 6.2.25. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#99 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#114 edit + +Change 1803 by gibbs@bitkeeper-linux-2.4 on 2002/12/30 16:54:09 + + aic79xx_osm.c: + aic7xxx_osm.c: + Reorganize DV state machine so that full inquiry data + is retrieved prior to testing to see if the unit is ready. + We now use this full inquiry data to assume defaults if + for some reason the DV state machine fails to configure + the device. This failsafe mechanism should ensure that + these devices are at least configured in the same fashion + as they were before the addition of DV to these drivers. + + aic79xx_osm.h: + aic7xxx_osm.h: + Re-arrange DV state enum to reflect current state machine + transitions. + + Add additional target flags used to implement the DV + failsafe mechanism. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#103 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#98 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#166 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#113 edit + +Change 1802 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 14:59:22 + + aic7770_osm.c: + aic79xx_osm_pci.c: + aic7xxx_osm_pci.c: + Clean up check_region() usage. It is deprecated in 2.5.X + and 2.4.X, but is still required in earlier kernels. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#42 edit + +Change 1801 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 13:50:25 + + aiclib.c: + Ignore media not-present errors during DV. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#5 edit + +Change 1800 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 13:50:10 + + aic79xx_osm.c: + aic7xxx_osm.c: + Use down_interruptable() rather than down() to avoid + having our thread counted toward the load average. + We disable all signal sources to that the down_interruptable() + is not really interruptable(). Singals are not required for + the drivers to terminate the DV threads on unload. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#102 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#165 edit + +Change 1799 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:19:23 + + aicasm_symbol.c: + Fix the last reference to the reg_print.c file handle + in symtable_dump. This allows the assembler to operate + without generating this file. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 edit + +Change 1798 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:18:05 + + aiclib.h: + Restore driver style. All functions are declared prior + to being defined. The original bug was that the 2.4.X + declaration was used unconditionally. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#5 edit + +Change 1797 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:17:23 + + aic79xx_osm.c: + aic7xxx_osm.c: + Enable highmem_io on 2.5.X kernels. It turns out that + the CONFIG_HIGHIO option does not exist there. + + Call daemonize() on and provide a name for our dv threads. + + aic79xx_osm.h: + aic7xxx_osm.h: + Include smp_lock.h for (un)lock_kernel(). + + aic7xxx_osm.c: + Add a diagnostic, similar to that in the aic79xx driver, + for printing out sense information. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#101 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#97 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#164 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#112 edit + +Change 1796 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:14:42 + + aic7xxx.c: + Preface the "asserting atn" diagnostic with controller/target + information. + + Restore a call to ahc_assert_atn() that was inadvertantly + lost when the asserting atn diagnostic was added. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#105 edit + +Change 1795 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:13:06 + + aic79xx_core.c: + Print out target information to preface the asserting + attention diagnostic. + + Correct a compilation warning. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#148 edit + +Change 1792 by gibbs@bitkeeper-linux-2.5 on 2002/12/20 17:52:04 + + Bump to version 6.2.24. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#111 edit + +Change 1788 by gibbs@aslan on 2002/12/20 16:39:14 + + aic79xx.c: + Remove stray debugging code. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#147 edit + +Change 1787 by scottl@scottl-template on 2002/12/20 16:04:59 + + Update driver version to 1.3.0.ALPHA5 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#96 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#20 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#23 edit + +Change 1786 by gibbs@overdrive on 2002/12/19 16:10:05 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#53 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#34 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#54 edit + +Change 1785 by gibbs@aslan on 2002/12/19 16:08:47 + + aic79xx.c: + Add a statistics timer that decides when to enable + or disable interrupt coalessing based on load. + + Add ahd_flush_qoutfifo() which will run the qoutfifo + as well as complete any commands sitting on the + sequencer's COMPLETE_SCB lists. Use this routine in + several places that did similar things in an add-hoc, + but incomplete, fashion. A call to this routine was + also added to ahd_abort_scbs() to close a race. + + Add a routine, ahd_reset_cmds_pending() which is used + to update the CMDS_PENDING sequencer variable whenever + error recovery compeltes SCBs without notifying the + sequencer. Since ahd_reset_cmds_pending is called + during ahd_unpause() only if we've aborted SCBs, its + call to ahd_flush_qoutfifo should not cause recursion + through ahd_run_qoutfifo(). A panic has been added to + ensure that this recursion does not occur. + + In ahd_search_qinfifo, update the CMDS_PENDING sequencer + variable directly. ahd_search_qinififo can be called + in situations where using ahd_reset_cmds_pending() might + cause recursion. Since we can safely determine the + exact number to reduce CMDS_PENDING by in this scenario + without running the qoutfifo, the manual update is more + than adequate. + + Clean up diagnostics. + + aic79xx.h: + Update per-softc variables for the stats "daemon". + The defaults for interrupt coalessing have been updated + slightly, but these need additional tuning. A new + tunable paramter "minimum commands still outstanding + required to attempt coalessing" has been added. + + Add a debug option for interrupt coalessing activities. + + Add two new softc flags: + o AHD_UPDATE_PEND_CMDS + Run ahd_reset_cmds_pending() on the next unpause. + + o AHD_RUNNING_QOUTFIFO + Used to catch recursion through ahd_run_qoutfifo(). + + aic79xx.reg: + Break INTMASK in SEQITNCTL out into INTMASK1 and INTMASK2. + In at least the REV A, these are writable bits. We make + use of that for a swtimer workaround in the sequencer. + + Add sequencer variables to recovery the min-commands + still outstanding for coalessing and the current number + of commands outstanding. + + Since HS_MAILBOX autoclears, provide a sequencer variable + to store its contents. + + aic79xx.seq: + In idle_loop_cchan, update LOCAL_HS_MAILBOX everytime + we are notified of an HS_MAILBOX update via the + HS_MAILBOX_ACT bit in QOFF_CTLSTA. + + Enhance our coalessing algorithm. If we have more + SCBs to complete to the host (sitting in COMPLETE_SCB + lists), always try to coaless them up to our coalessing + limit. If coalessing is enabled, but we have fewer + commands oustantind than the hosts limit, complete the + command immediately. + + Since we cannot disable the swtimer's countdown, simply + mask its interrupt once we no longer care about it firing. + + Add code to track the number of commands outstanding. + Commands are outstanding from the time they are placed + into the execution queue until the DMA to post completion + is setup. + + Add a workaround for intvec_2 interrupts on the H2A4. + In H2A4, the mode pointer is not saved for intvec2, but + is restored on iret. This can lead to the restoration + of a bogus mode ptr. Manually clear the intmask bits and + do a normal return to compensate. + + aic79xx_inline.h: + Call ahd_reset_cmds_pending() in ahd_unpause if required. + + Update cmdcmplt interrupt statistics in our interrupt + handler. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#146 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#78 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#59 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#77 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#40 edit + +Change 1784 by gibbs@bitkeeper-linux-2.5 on 2002/12/18 10:33:25 + + aic79xx_osm.c: + Remove a stray ';' that was short cicuiting an if statement. + + aic79xx_osm.c: + aic7xxx_osm.c: + aic79xx_osm.h: + aic7xxx_osm.h: + Only allow slave_destroy() to destroy a real device + if that device has had slave_configure() called on it. + This prevents "silly deletions" caused by bogons in + the scsi_scan code from deleting DV state for devices + that are still attached and will have a slave_alloc() + called for them as soon as the slave_destroy() returns. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#100 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#95 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#163 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#110 edit + +Change 1783 by gibbs@bitkeeper-linux-2.5 on 2002/12/18 10:29:46 + + aic7xxx.c: + Don't clobber ppr_options when forcing a renegotiation. + The current ppr_options may be referenced while queuing + new commands. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#104 edit + +Change 1782 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:27:05 + + aic79xx_osm.c: + Add a prototype for ahd_linux_dv_fallback(). + + aic7xxx_osm.c: + Complete the merge of the new biosparam API from + Christoph Hellwig. + + aic79xx_osm.c: + aic7xxx_osm.c: + Move the setting of max_sectors to the host template + to quiet a warning in 2.5.X. + + Add slave_alloc calls and "bootverbose" diagnostics + for help in sorting out exactly how this slave_* + API functions. + + Move call to ahd_linux_device_queue_depth to within + the test to see if dev is NULL. + + Add code to actually destroy our data structures to + the slave_destroy routine instead of waiting for a + command that may not come to do so. + + Initialize the name field of the host structure. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#99 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#162 edit + +Change 1781 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:20:16 + + aic79xx.c: + Remove "Now packetized" diagnostic now that this + information is incorperated into the actual negotiation + messages that are displayed. + + When forcing renegotiation, don't clober the current + ppr_options. Much of the driver uses this information + to determine if we are currently packetized or not. + + Remove some stray spaces at column 1 and ahd_set_tags. + + When complaining about getting a host message loop + request with no pending messages, print out the + SCB_CONTROL register down on the card. + + Modify the ahd_sent_msg() routine to handle a search + for an outgoing identify message. Use this to detect + a msg reject on an identify message which typically + indicates that the target thought we were packetized. + Force a renegotiation in this case. + + In ahd_search_qinfifo(), wait more effectively for SCB + DMA activities to cease. We also clear out the state + that tells the sequencer that a DMA was in progress for + SCB fetch operations since we are about to change the + qinfifo. + + In ahd_pause_and_flush_work(), actually itterate through + the two Complete SCB lists. Ooops. + + In ahd_qinfifo_count(), fix the qinfifo empty case. + + In ahd_dump_card_state(), print out CCSCBCTL in the + correct mode. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#145 edit + +Change 1780 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:11:25 + + aic79xx.seq: + Add a missing ret to the last instruction in + load_overrun_buf. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#76 edit + +Change 1779 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:10:42 + + aic79xx.reg: + Correct address for the DFDBCTL register. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#58 edit + +Change 1774 by scottl@scottl-template on 2002/12/16 03:08:08 + + Update driver version to 1.3.0.ALPHA4 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#94 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#19 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#22 edit + +Change 1772 by scottl@scottl-belfalas-template on 2002/12/16 02:43:36 + + ahd_linux_fallback can't aquire the ahd lock since it might be + called from the completion handler. Create a wrapper called + ahd_linux_dv_fallback that aquires and releases the ahd lock so + that is can be called from the DV code and still satisfy it's locking + needs. + Move the error stat code into ahd_linux_queue_cmd_complete so it + can catch more error conditions. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#98 edit + +Change 1771 by scottl@scottl-belfalas-template on 2002/12/16 02:39:22 + + aic79xx_proc.c: + Add a newline when printing the renegotiation pending message. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#11 edit + +Change 1770 by scottl@scottl-belfalas-template on 2002/12/15 23:38:06 + + aic79xx_osm.c: + Don't grab the ahd lock when updating error stats since + it's already held. + When deciding to do a fallback because of an error, don't + alias the existing devinfo struct with a new one. Why + the compiler didn't catch this is beyond me. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#97 edit + +Change 1769 by scottl@scottl-hobbiton-0b47 on 2002/12/15 22:24:16 + + Regen firmware + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#52 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#33 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#53 edit + +Change 1768 by scottl@scottl-hobbiton-0b47 on 2002/12/15 22:24:02 + + aic79xx_osm.c: + aic79xx_osm.h: + Switch to a bucket-based method of counting the number off + good commands in between bad ones. Use only a single bucket + right now for simplicity, though this can grow in the future. + This also removes the stats timer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#96 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#93 edit + +Change 1767 by scottl@scottl-hobbiton-0b47 on 2002/12/15 21:23:38 + + aic79xx_osm.h: + Move the errors_detected field to the target structure, and + add new_errors_detected field for doing stats decay. + + aic79xx_osm.c: + If a transmission error is detected, increment the + new_errors_detected counter. If it's passed the threshold, + call for a speed fallback. + Update the errors_detected field with new_errors_detected and + reset new_errors_detected on every stats timeout call. + + aic79xx_proc.c: + Display the per-target errors detected field. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#95 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#92 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#10 edit + +Change 1766 by gibbs@aslan on 2002/12/15 19:32:13 + + Add interrupt coalessing hooks. + + aic79xx.c: + Keep a copy of the hs_mailbox in our softc so that + we can perform read/modify/write operations on the + hs_mailbox without having to pause the sequencer to + read the last written value. Use the ENINT_COALESS + flag in the hs_mailbox to toggle interrupt coalessing. + + Add entrypoints for enabling interrupt coalessing and + setting both a timeout (how long to wait for commands + to be coalessed) and a maximum commands to coaless value. + + In ahd_pause_and_flushwork() only return one selections + are safely disabled. We now also flush the two sequencer + lists of completed commands. + + aic79xx.h: + Add coalessing and HS_MAILBOX fields. + + aic79xx.reg: + Correct register addresses related to the software timer. + + Add constants paramaterizing the software timer. + + Add scratch ram locations for storing interrupt coalessing + tunables. + + aic79xx.seq: + Use the software timer and a commands completed count to + implement interrupt coalessing. The command complete is + deferred until either the maximum command threshold or a + timer since the first command completed since the last + completion expires. + + Move the test for the cfg4istat interrupt up an instruction + to hopefully close a race between the next outgoing selection + and our disabling of selections. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#144 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#77 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#57 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#75 edit + +Change 1765 by gibbs@aslan on 2002/12/15 17:48:29 + + aicasm_gram.y: + Allow constants to be complex expressions so long + as those expressions can be fully evaluated during + assembly. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#28 edit + +Change 1764 by scottl@scottl-hobbiton-0b47 on 2002/12/13 18:09:34 + + aic79xx_osm.c: + aic79xx_osm.h: + Start of runtime fallback and interrupt caolescing stat + gathering. Run ahd_linux_stats_update() every + AHD_LINUX_STATS_INTERVAL period. Consense the packetized + and non-packetized autosense code and start some logic to + figure out what to do with the sense information. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#94 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#91 edit + +Change 1762 by gibbs@bitkeeper-linux-2.5 on 2002/12/13 13:08:43 + + aic79xx_osm.c: + aic7xxx_osm.c: + Remove *slave_alloc declarations as we don't need or + export this entry point. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#93 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#161 edit + +Change 1761 by gibbs@bitkeeper-linux-2.4 on 2002/12/12 14:31:11 + + aiclib.h: + Add aic_sector_div macro. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#4 edit + +Change 1760 by gibbs@bitkeeper-linux-2.4 on 2002/12/12 14:30:40 + + aic79xx_osm.h: + aic7xxx_osm.h: + Complete adjustment for host template changes. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#90 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#109 edit + +Change 1759 by gibbs@bitkeeper-linux-2.5 on 2002/12/12 14:25:19 + + aic79xx_osm.h: + Remove a stray reference to aic79xx_host.h. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#89 edit + +Change 1754 by gibbs@bitkeeper-linux-2.4 on 2002/12/12 11:45:59 + + aic79xx_host.h: + aic7xxx_host.h: + aic79xx_osm.c: + aic7xxx_osm.c: + Eliminate separate Linux host template files and move + all host template entry ponts to one section of the Linux + osm.c file. + + aic79xx_osm.c: + aic7xxx_osm.c: + Add support for larger disks under 2.5.X. + + Changes prodded by: Christoph Hellwig + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#14 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#92 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#16 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#160 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#41 edit + +Change 1751 by scottl@scottl-template on 2002/12/10 21:41:30 + + Update driver version to 6.2.23 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#108 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#9 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#12 edit + +Change 1750 by gibbs@bitkeeper-linux-2.4 on 2002/12/10 20:51:23 + + aic79xx_host.h: + aic7xxx_host.h: + Set single_sg_okay for RH AS 2.1 too. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#15 edit + +Change 1749 by gibbs@bitkeeper-linux-2.4 on 2002/12/10 20:45:35 + + aic79xx_host.h: + aic7xxx_host.h: + Use CONFIG_HIGHIO as the gating define for whether + the highmem_io host template field is present. Also + assume that if the kernel version is less than 2.4.18, + then we must be under RedHat and need to call this field + can_dma_32. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#14 edit + +Change 1748 by scottl@scottl-template on 2002/12/10 19:54:55 + + Update driver version to 1.3.0.ALPHA3 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#88 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#18 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#20 edit + +Change 1747 by gibbs@bitkeeper-linux-2.4 on 2002/12/10 18:49:21 + + aic79xx_host.h: + aic7xxx_host.h: + Enable the highmem_io option on kernels with the + new highmem bouncing code. + + aic79xx_osm.c: + aic7xxx_osm.c: + Fix compilation error in the non-debug enabled case. + + aic7xxx_osm.c: + Remove leftover #if 0'd code from DV merge. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#91 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#159 edit + +Change 1746 by gibbs@bitkeeper-linux-2.5 on 2002/12/10 12:05:15 + + aic79xx_osm.c: + aic7xxx_osm.c: + Disable the shutdown hook for 2.5.X since it is called + to early to be useful. Some other strategy will need to + be found. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#90 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#158 edit + +Change 1745 by gibbs@bitkeeper-linux-2.5 on 2002/12/09 16:29:02 + + aic79xx_host.h: + aic79xx_osm.c: + aic79xx_osm_pci.c + aic7xxx_host.h: + aic7xxx_osm.c: + aic7xxx_osm_pci.c: + Conform to latest 2.5.X API changes. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#89 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#157 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#40 edit + +Change 1743 by gibbs@bitkeeper-linux-2.4 on 2002/12/09 15:16:31 + + aic79xx.c: + Limit the syncrate after all option conformance + changes have taken place in ahd_devlimited_syncrate. + Changes in options may change the final syncrate we + accept. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#143 edit + +Change 1741 by gibbs@bitkeeper-linux-2.4 on 2002/12/09 14:11:44 + + Makefile: + Turn off -g. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#10 edit + +Change 1740 by scottl@scottl-template on 2002/12/09 10:15:50 + + Update driver version to 6.2.22 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#107 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#8 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#11 edit + +Change 1737 by scottl@scottl-template on 2002/12/06 16:14:24 + + Update driver version to 1.3.0.ALPHA2 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#87 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#17 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#19 edit + +Change 1736 by gibbs@overdrive on 2002/12/06 16:04:51 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#51 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#32 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#52 edit + +Change 1735 by gibbs@bitkeeper-linux-2.4 on 2002/12/06 16:03:54 + + aic79xx.h: + Use consistent names for AH?_ASYNC_XFER_PERIOD. + + aic79xx.c: + aic79xx_proc.c: + Print out IU, QAS, and RTI features when showing + transfer options. + + aic79xx.c: + Save and restore the NEGOADDR address when setting + new transfer settings. The sequencer performs lookups + in the negotiation table too and it expects NEGOADDR + to remain consistent across pause/unpause sessions. + + Consistently use "offset" instead of "period" to determine + if we are running sync or not. + + Add a SHOW_MESSAGES diagnostic for when we assert ATN + during message processing. + + aic79xx_osm.c: + aic7xxx_osm.c: + In ah?_devlimited_syncrate enforce that we can never + attempt DT transfers if we are narrow. + + Remove the ALLOW_MEMIO config option. + + Modify ah?_linux_filter_inquiry to assume that the + inquiry buffer is large enough and has been setup + correctly (i.e. memset to 0 prior to command issue) + so that range checks are unecessary. + + Remove comments about the need to perform short inquiry + requests. The code does this now. + + Split out the bottom half handling of DV inquiry results + to make the code clearer. + + Re-arrange the DV state machine so that: + + o REB descriptor fetching is performed ASYNC so we + don't confuse a failure with the need to fallback. + o Devices using Level 2 DV don't bother with Level 1 + DV. + o REB collisions are retried after a delay randomized + by our ID on the bus. + o Level 2 DV is only attempted on devices that support + DT transfers. + + Fix ah?_linux_fallback to always favor the fastest + speed during fallback and to favor sync over async speeds. + + Don't let a target reponding to a PPR message with 0 + options set fool us into falling back to far. We still + must try to negotiate without using PPR to get by some + expanders. + + Use the SCB_SILENT flag on DV commands. + with 0 PPR options set + + Fix large inquiry size calculation. It was off by one. + We need to add 5 and not 4. + + aic79xx_osm_pci.c: + Tell the user that our failure of the MMAP test is non + fatal. We're just dropping back to PIO. + + aiclib.c: + aiclib.h: + Add flags for a randomized delay in response to an error. + + Include table entries for REB collisions. + + Add the proper response codes for sense codes indicating + inquiry data has changed. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#142 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#76 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#103 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#66 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#88 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#86 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#156 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#106 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#39 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#3 edit + +Change 1734 by gibbs@bitkeeper-linux-2.4 on 2002/12/06 15:49:37 + + Config.in: + With the advent of our command line option and the + new memory mapped register test, there is no need + for a kernel compile time option to allow memory + mapped I/O. Remove it. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#10 edit + +Change 1733 by gibbs@bitkeeper-linux-2.4 on 2002/12/06 15:31:31 + + aic79xx.seq: + Correct ignore wide residue processing check for + a wide negotiation being in effect. We must be + in the SCSI register window in order to access the + negotiation table. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#74 edit + +Change 1732 by gibbs@aslan on 2002/12/06 15:14:01 + + aicasm_gram.y: + Add two missing ';'s that for some reason yacc/bison + never complained about as a syntax error. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#27 edit + +Change 1730 by cde@haywire on 2002/12/05 17:55:31 + + Add AHD_DV_STATE_INQ_SHORT_ASYNC to probe inquiry buff len + + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#87 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#85 edit + +Change 1729 by gibbs@aslan on 2002/12/05 17:23:45 + + aic7xxx.h: + AHD -> AHC. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#65 edit + +Change 1728 by gibbs@aslan on 2002/12/05 17:21:45 + + aic79xx.c: + aic79xx.h: + aic7xxx.c: + aic7xxx.h: + Cleanup usage of the SCB_SILENT flag by using + a new macro SCB_IS_SILENT(scb). + + Apply the silent treatment to outgoing LQ CRC + errors. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#141 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#75 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#102 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#64 edit + +Change 1727 by gibbs@aslan on 2002/12/05 17:01:15 + + aic79xx.c + aic7xxx.c: + aic79xx.h: + aic7xxx.h: + Implement the SCB_SILENT flag. This is useful for + hushing up the driver during DV or other operations + that we expect to cause transmission errors. The + messages will still print if the SHOW_MASKED_ERRORS + debug option is enabled. + + aic7xxx_inline.h: + aic7xxx_pci.c: + Implement ahc_[in|out][w|l|q]. This removes the need + for manual 'or and shift" type operations through out + the driver. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#140 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#74 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#101 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#63 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#39 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#54 edit + +Change 1726 by gibbs@overdrive on 2002/12/04 17:33:18 + + Regenerate Linux firmware + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#21 edit + +Change 1725 by gibbs@aslan on 2002/12/04 17:32:26 + + aic7xxx.reg: + Add a definition for MAX_OFFSET. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#36 edit + +Change 1724 by gibbs@overdrive on 2002/12/04 16:35:11 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#50 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#31 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#51 edit + +Change 1723 by gibbs@aslan on 2002/12/04 16:34:34 + + aic79xx.seq: + The sequencer downloading code assumes that all jump + labels are acurate in relation to a fully compiled + sequencer program (all patches downloaded). Correct + a few occurances of a relative jump across a macro + that ended up jumping us into the last instruction + of the macro. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#73 edit + +Change 1722 by scottl@scottl-via-freebsd on 2002/12/04 15:40:08 + + ahd_pci.c: + Add a newline to the MEMIO printf. + + aic79xx_pci.c: + Set the mode correctly for writing to SRAM_BASE in the MEMIO + test. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#60 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#11 edit + +Change 1721 by scottl@scottl-junior-freebsd on 2002/12/04 14:49:34 + + aic79xx_pci.c: + Use SRAM and the 0xaa55 pattern for the MEMIO test. + + ahd_pci.c: + Go along with ahc_pci.c and retrieve the allow_memio hint + from the resource manager and act on it. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#59 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#10 edit + +Change 1719 by gibbs@bitkeeper-linux-2.4 on 2002/12/03 17:04:22 + + aic79xx_pci.c: + Don't attempt to set reserved bits in memio test. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#58 edit + +Change 1718 by gibbs@overdrive on 2002/12/03 16:16:46 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#49 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#30 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#50 edit + +Change 1717 by gibbs@scottl-via-freebsd on 2002/12/03 15:29:57 + + aic79xx_pci.c: + Use the TYPEPTR register as a base for our + memory mapped I/O test. The Rev B. will allow + multi-byte access to Scratch Ram, so it is not + a good test of write-combining or other bad + behavior. + + User CLRPCIINT and CLRSPLTINT in their respective + handlers. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#57 edit + +Change 1716 by gibbs@scottl-via-freebsd on 2002/12/03 15:27:24 + + aic79xx.reg: + Correct the location of the TARGPCISTAT register. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#56 edit + +Change 1715 by gibbs@aslan on 2002/12/03 10:34:23 + + aic79xx_pci.c: + Revamp memory mapped I/O test to match the algorithm + used in the aic7xxx driver. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#56 edit + +Change 1714 by scottl@scottl-via-freebsd on 2002/12/02 19:12:42 + + aic7xxx_pci.c: + In the memio test, clear the FAILDIS bit of the SEQCTL + before running the tests so that PCI errors will be + flagged. + + Write only 4 bytes to the SRAM to prevent VIA chipsets + from generating a burst transaction on the bus. + + Clear the PCIR_STATUS register and restore the SEQCTL + register before exiting. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#53 edit + +Change 1713 by gibbs@aslan on 2002/12/02 13:04:29 + + aic79xx_pci.c: + Properly report the aic7901A as an aic7901A. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#55 edit + +Change 1710 by scottl@scottl-junior-freebsd on 2002/11/27 02:05:18 + + Fix a spelling mistake and a whitespace goof. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#52 edit + +Change 1709 by scottl@scottl-junior-freebsd on 2002/11/26 22:12:00 + + Strip down the $FreeBSD$ + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 edit + +Change 1708 by scottl@scottl-junior-freebsd on 2002/11/26 21:56:03 + + Revert whitespace changes in ahc_syncrates[] to reduce diffs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#100 edit + +Change 1699 by gibbs@bitkeeper-linux-2.4 on 2002/11/20 14:14:13 + + aic79xx_osm_pci.c: + aic7xxx_osm_pci.c: + Make use of the new Core PCI routine for testing memory + mapped register access. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#38 edit + +Change 1698 by gibbs@bitkeeper-linux-2.4 on 2002/11/20 14:13:40 + + aic79xx_osm.c: + aic7xxx_osm.c: + Make the "ALLOW_MEMIO" config option actually work for + the "disabled" case. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#86 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#155 edit + +Change 1697 by gibbs@bitkeeper-linux-2.4 on 2002/11/20 14:12:43 + + aic79xx.h: + aic79xx_pci.c: + aic7xxx.h: + aic7xxx_pci.c: + Add a routine for testing memory mapped register access. + This will hopefully detect things like buggy via chipsets + so that the OSM can fallback to using I/O mapped access + when memory mapped I/O simply will not work. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#73 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#54 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#62 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#51 edit + +Change 1696 by gibbs@bitkeeper-linux-2.5 on 2002/11/19 11:43:33 + + aiclib.h: + Don't include the definition for REPORT_LUNS. It conflicts + with the native Linux definition. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#2 edit + +Change 1695 by scottl@scottl-template on 2002/11/18 16:45:04 + + Update driver version to 1.3.0.ALPHA1 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#84 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#16 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#18 edit + +Change 1690 by scottl@scottl-template on 2002/11/14 18:31:41 + + Fix type from previous commit + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#154 edit + +Change 1689 by scottl@scottl-template on 2002/11/14 18:26:58 + + Update driver version to 6.2.21 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#105 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#7 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#10 edit + +Change 1688 by scottl@scottl-template on 2002/11/14 17:38:10 + + Update driver version to 1.2.0 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#83 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#14 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#17 edit + +Change 1687 by scottl@scottl-template on 2002/11/14 17:36:51 + + Remove the previous change for falling back in narrow. It doesn't + seem to work. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#85 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#153 edit + +Change 1686 by scottl@scottl-template on 2002/11/14 12:40:42 + + Update driver version to 1.1.14 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#82 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#13 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#16 edit + +Change 1685 by scottl@scottl-template on 2002/11/14 12:40:17 + + aic79xx_osm.c + aic7xxx_osm.c + Add a minimum bus settle delay after doing a bus reset from + the DV timeout handler. + + Limit the max period allowed for narrow when figuring out + the narrow fallback speed. + + aic7xxx.h + Add AHD_ULTRA2_XFER_PERIOD for narrow fallback calculations + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#61 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#84 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#152 edit + +Change 1683 by scottl@scottl-template on 2002/11/13 20:49:54 + + Update driver version to 1.1.13 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#81 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#12 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#15 edit + +Change 1680 by gibbs@vas2209a on 2002/11/13 19:08:38 + + aic7xxx_osm.c: + Use ahc_set_tags rather than ahc_platform_set_tags so + that the core can be appraised of any tag type or depth + changes. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#151 edit + +Change 1679 by gibbs@vas2209a on 2002/11/13 19:03:23 + + aic7xxx_osm.c: + Add a back in a missing ahc_done_unlock() that was + lost in the last change. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#150 edit + +Change 1678 by gibbs@bitkeeper-linux-2.5 on 2002/11/13 18:26:28 + + aic79xx_osm.c: + aic7xxx_osm.c: + Requeue deferred command completions so that when the + timer does expire the entries are actually sent. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#83 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#149 edit + +Change 1676 by gibbs@bitkeeper-linux-2.5 on 2002/11/13 16:26:07 + + aic79xx_osm.c: + aic7xxx_osm.c: + Move a FALLTHROUGH label to the correct + location in the code. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#82 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#148 edit + +Change 1675 by gibbs@vas2209a on 2002/11/13 15:43:19 + + aic79xx.c: + Set WIDERESEN for Rev B which ensures that an + expected wide residue does not prevent the + FIFO from reporting FIFOEMP. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#139 edit + +Change 1674 by gibbs@vas2209a on 2002/11/13 14:27:15 + + aic79xx_host.h: + aic79xx_osm.c: + aic7xxx_osm.c: + Correct a few minor compile issues that fell out of + the port to 2.5.X. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#81 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#147 edit + +Change 1673 by gibbs@bitkeeper-linux-2.5 on 2002/11/13 13:43:15 + + aic79xx_host.h: + aic79xx_osm.c: + aic79xx_osm.h: + aic7xxx_host.h: + aic7xxx_osm.c: + aic7xxx_osm.h: + Complete the port to Linux 2.5.X. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#80 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#80 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#146 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#104 edit + +Change 1672 by gibbs@bitkeeper-linux-2.4 on 2002/11/13 13:02:15 + + aic79xx_osm.c: + aic7xxx_osm.c: + Remove fallback from the Read Echo Buffer Descriptor + DV state. This avoids issues with tape drives that + just hang if you issue the command. We should really + be issuing the command async, but that is too complicated + a fix for PH1.2. Defer that fix to PH1.3. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#79 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#145 edit + +Change 1671 by gibbs@aslan on 2002/11/13 12:10:23 + + aic79xx.c: + Correct code that restore the STACK. It was + always placing a 0 in the high byte of the stack + address. + + aic7xxx.c: + Remove unecessary restoration of the STACK for older + chips. + + aic7xxx.h: + aic79xx.h: + Collapse SCB flag entries so they are bit contiguous. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#138 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#72 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#99 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#60 edit + +Change 1670 by gibbs@bitkeeper-linux-2.4 on 2002/11/13 11:46:51 + + aic79xx_osm.c: + aic7xxx_osm.c: + To avoid stack explosion in the mid-layer, only complete + AH?_LINUX_MAX_RETURNED_ERRORS commands that have errors + at a time. Any deferred entries will be returned via + a timer that runs the queue. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#78 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#144 edit + +Change 1669 by gibbs@vas2209a on 2002/11/13 00:14:42 + + aic79xx_osm.c: + aic79xx_osm.h: + aic7xxx_osm.c: + aic7xxx_osm.h: + Don't allow the eh_sem to be up'ed twice in the + case of the eh timer expiring and the command completing + due to a future recovery action such as a bus reset. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#77 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#79 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#143 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#103 edit + +Change 1668 by gibbs@vas2209a on 2002/11/13 00:01:03 + + aic79xx.c: + Add DFFSTAT in mode 3 to ahd_dump_card_state(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#137 edit + +Change 1667 by gibbs@overdrive on 2002/11/12 23:57:48 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#48 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#29 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#49 edit + +Change 1666 by gibbs@aslan on 2002/11/12 23:55:24 + + aic79xx.reg: + aic79xx.seq: + Workaround Rev B issue with CURRFIFO_0 having the + same value in "enhanced mode" as "standard mode" + for "writes". Reads of the register behave as + expected. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#55 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#72 edit + +Change 1662 by gibbs@overdrive on 2002/11/12 14:59:39 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#47 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#28 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#48 edit + +Change 1661 by gibbs@vas2209a on 2002/11/12 14:58:23 + + aicasm_gram.y: + Use a direct move from allzeros to emulate a + mvi of 0. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#26 edit + +Change 1660 by gibbs@vas2209a on 2002/11/12 10:33:25 + + aic7xxx.h: + Add a missing typedef. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#59 edit + +Change 1659 by gibbs@overdrive on 2002/11/11 23:37:31 + + Regenerate Linux Firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#46 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#27 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#47 edit + +Change 1658 by gibbs@overdrive on 2002/11/11 23:35:30 + + aic79xx_pci.c: + Set the PREQDIS bit in DEVCONFIG1 for the B. The + bit is misnamed, but seems to disable a work-around + that breaks on the B on PCI busses. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#53 edit + +Change 1657 by gibbs@overdrive on 2002/11/11 23:34:43 + + aic79xx.seq: + Return to the SCSI mode prior to re-allocating a FIFO. + The alloc-FIFO routine assume we are in the SCSI mode. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#71 edit + +Change 1656 by gibbs@bitkeeper-linux-2.4 on 2002/11/11 15:37:54 + + aic79xx.c: + Printout the SAVED_MODE scratch ram location in ahd_dump_card_state. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#136 edit + +Change 1655 by gibbs@bitkeeper-linux-2.4 on 2002/11/11 14:22:01 + + aic79xx_osm.c: + aic79xx_osm.h + aic7xxx_osm.c: + aic7xxx_osm.h + Add a timer for deferred running of the completion + queue. We use this to return commands back to the OS + when our queue is frozen that happen to arrive before + Linux sees that our host queue is blocked. This avoids + a deadlock issue that occurs should we attempt to simply + scsi_done the command immediately. This strategy also + guarantees that the commands are returned almost imediately + instead of having to wait for either a DV command or simq + release to occur. + + Add the ability to reset a command's timeout from within + the core. We use this to give RequestSense operations + a new timer. + + Always perform DV thread operations while our ah?_lock + is held. + + aic79xx.c: + aic7xxx.c: + Make use of the new ah?_scb_timer_reset() api. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#135 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#98 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#76 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#78 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#142 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#102 edit + +Change 1654 by scottl@scottl-belfalas-rh72as on 2002/11/08 19:15:45 + + aic79xx_osm.c: + Remove unused variable. + + Move ahd_linux_thread_run_complete_queue() to its + proper location in the file. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#75 edit + +Change 1653 by scottl@scottl-belfalas-rh72as on 2002/11/08 19:10:04 + + aic79xx_osm.c: + Fix deadlock in ahd_linux_queue() when we want to + return a command immediately to the system because + our queue is blocked. We now defer the return of + the command until either the simq is released or + the dv thread has an oportunity to flush the queue. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#74 edit + +Change 1652 by scottl@scottl-template on 2002/11/07 23:34:47 + + Update driver version to 6.2.20 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#101 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#6 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#8 edit + +Change 1650 by gibbs@aslan on 2002/11/07 13:55:31 + + aic79xx.c: + Avoid infinite loop in restoration of STACK contents + in ahd_dump_card_state(). Our interrator must be + signed. + + aic79xx.c: + aic7xxx.c: + Remove a diagnostic printf. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#134 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#97 edit + +Change 1649 by gibbs@bitkeeper-linux-2.4 on 2002/11/07 13:33:07 + + aic79xx.c: + Workaround printf format and integer sizing issues. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#133 edit + +Change 1648 by gibbs@bitkeeper-linux-2.4 on 2002/11/07 13:23:23 + + aic79xx.c: + Remove extraineous include of stdint.h. The OSM + header file should be doing this. + + Remove unused variable warnings for debuging code. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#132 edit + +Change 1647 by gibbs@bitkeeper-linux-2.4 on 2002/11/07 13:19:35 + + aic79xx_osm.c: + aic7xxx_osm.c: + Mark devices as "configured" once the OS calls + select queue_depths. This is required now that we + are no longer sniffing all inquiry cmds that the + OS performs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#73 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#141 edit + +Change 1646 by scottl@scottl-template on 2002/11/06 23:07:03 + + Update driver version to 1.1.12 + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#131 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#77 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#11 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#12 edit + +Change 1645 by scottl@scottl-template on 2002/11/06 23:05:33 + + Follow the aic79xx driver and extend the timeout amount when + debug printing is enabled. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#140 edit + +Change 1644 by gibbs@bitkeeper-linux-2.4 on 2002/11/06 11:03:48 + + aic79xx_osm.c: + Be even more pessimistic about how long negotiation + messages take by bumping up the DV timeout a whole + 1 second should negotiation debugging be enabled. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#72 edit + +Change 1643 by scottl@scottl-template on 2002/11/05 23:40:18 + + Update driver version to 6.2.19 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#100 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#5 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#7 edit + +Change 1642 by scottl@scottl-template on 2002/11/05 17:58:47 + + Update driver version to 1.1.11 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#76 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#10 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#11 edit + +Change 1641 by gibbs@bitkeeper-linux-2.4 on 2002/11/05 16:33:24 + + aic79xx_osm.c: + aic7xxx_osm.c: + Not all Linux kernel versions honor the return value + from the queue_command driver entry point. To deal with + these older kernels, always return "rejected" commands + via the scsi_done handler. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#71 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#139 edit + +Change 1640 by gibbs@bitkeeper-linux-2.4 on 2002/11/05 15:33:08 + + aic79xx_osm.c: + aic7xxx_osm.c: + Avoid taking the io_request lock twice. This is a + regression from our port to 2.5.X. + + aic79xx_osm.c: + Put some more diagnostics under AHD_SHOW_RECOVERY. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#70 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#138 edit + +Change 1639 by gibbs@aslan on 2002/11/05 13:13:20 + + aic79xx.c: + aic79xx.h: + aic7xxx.c: + aic7xxx.h: + Save and restore stack contents during diagnostics. + Some chip variants overwrite stale entries on a + stack "pop". + + Don't use 0 to probe the stack depth. 0 is the typical + value used to backfill the stack if entries are overwritten + on a "pop". + + aic79xx.c: + aic79xx.h: + Add the AHD_SHOW_RECOVERY debug option and use it to + control some diagnostic messages related to error recovery. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#130 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#71 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#96 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#58 edit + +Change 1638 by scottl@scottl-template on 2002/11/01 18:16:08 + + Update driver version to 1.1.10 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#75 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#9 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#10 edit + +Change 1637 by gibbs@overdrive on 2002/11/01 17:17:04 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#45 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#26 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#46 edit + +Change 1636 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:14:53 + + cam.h: + Add CAM_DEVQ_FROZEN to the cam_status enum. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#15 edit + +Change 1635 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:14:34 + + Make "empty_string" static so it can be included in both the + aic7xxx and the aic79xx drivers. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#3 edit + +Change 1634 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:14:08 + + aic7xxx.c: + aic7xxx.h: + Just for safety, have the aic7xxx driver probe + the stack depth too. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#95 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#57 edit + +Change 1633 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:13:33 + + aic79xx_osm.c: + Correct a compile error. The updated handling of + CAM_CMD_TIMEOUT was placed in the wrong routine. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#69 edit + +Change 1632 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:12:22 + + aic79xx.seq: + Revert de-optimization in the fifo polling loop. + Our problem was caused by the larger stack size on + Rev B. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#70 edit + +Change 1631 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:11:33 + + aic79xx.c: + Move ahd_probe_stack_size() so it matches the location + of its declaration. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#129 edit + +Change 1630 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 16:19:58 + + aic79xx_osm.c: + aic79xx_osm.h: + aic7xxx_osm.c: + aic7xxx_osm.h: + Actually freeze the device queue in response to a request + to do so from the Core. This closes a race in the case + of things like QUEUE FULL or BUSY handling where the + OSM may be able to queue additional commands prior to + seeing the SCB that should have frozen or otherwise altered + the execution queue. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#68 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#74 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#137 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#99 edit + +Change 1629 by gibbs@overdrive on 2002/11/01 16:17:55 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#44 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#25 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#45 edit + +Change 1628 by gibbs@aslan on 2002/11/01 16:11:16 + + aic79xx.c: + aic79xx.h: + aic79xx.reg: + Add a routine to dynamically determine the size + of the sequencer stack. It turns out that RevB + has a 9 entry stack rather than the 8 entry stack + of the A4. Determining the stack depth programatically + should protect us from any future changes in this area. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#128 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#70 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#54 edit + +Change 1626 by scottl@scottl-template on 2002/10/31 16:38:49 + + Update driver version to 1.1.9 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#73 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#8 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#9 edit + +Change 1625 by scottl@scottl-template on 2002/10/31 15:47:57 + + Update driver version to 6.2.18 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#98 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#4 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#6 edit + +Change 1623 by scottl@scottl-template on 2002/10/31 14:47:46 + + Define SCSI_NOSENSE_STRINGS to elimiate the asc/ascq description + strings. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#2 edit + +Change 1622 by scottl@scottl-template on 2002/10/31 14:44:19 + + Don't lock the io_request_lock until after calling + ahd_linux_register_host(). + Release the ahd lock when calling kernel_thread() + + This fixes a deadlock when launching the DV thread in + older 2.4 SMP kernels. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#136 edit + +Change 1621 by scottl@scottl-template on 2002/10/31 14:17:54 + + Don't lock the io_request_lock until after calling + ahd_linux_register_host(). + Release the ahd lock when calling kernel_thread() + + This fixes a deadlock when launching the DV thread in + older 2.4 kernels. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#67 edit + +Change 1618 by scottl@scottl-template on 2002/10/30 19:48:52 + + Update driver version to 1.1.8 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#72 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#7 edit +... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#8 edit + +Change 1616 by scottl@scottl-template on 2002/10/30 19:05:51 + + Update driver version to 6.2.17 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#97 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#3 edit +... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#3 edit + +Change 1615 by gibbs@overdrive on 2002/10/30 18:35:23 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#43 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#44 edit + +Change 1614 by gibbs@aslan on 2002/10/30 18:34:26 + + aic79xx.seq: + Rearrange idle_loop_service_fifo: I have a hunch + that the sequencer does not like the optimized version + of this routine should we be paused at the start of + a longjmp handler. We now change this to look just + as it did in PH 1.1. + + Clear the longjmp address of the p_data handler just + after we call disable_ccsgen. Otherwise the longjmp + handler may not be deregistered until an extra call + into the handler or a new handler is installed. The + first behavior might be dangerous if the FIFO is not + active. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#69 edit + +Change 1613 by gibbs@overdrive on 2002/10/30 16:52:10 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#42 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#23 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#43 edit + +Change 1612 by gibbs@aslan on 2002/10/30 16:50:11 + + aic79xx.seq: + Test for SCSIPERR instead of relying on SCSIPHASE + not setting on a SCSI parity error. It seems that + this is not the case and that we occassionally coast + out of routines like phase_lock when a parity error + is pending. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#68 edit + +Change 1611 by gibbs@aslan on 2002/10/30 12:55:46 + + aic7770.c: + Add IDs for some Olivetti OEM aic7770 based cards. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#27 edit + +Change 1610 by gibbs@bitkeeper-linux-2.4 on 2002/10/30 12:27:14 + + aic7xxx.c: + Don't disable ENBUSFREE when single stepping on + a DT capable controller. We cannot re-enable unexpected + busfree detection, so we must clear BUSFREE on each + step instead. + + Correct the lookup of the SCB ID in ahc_handle_proto_error. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#94 edit + +Change 1609 by gibbs@aslan on 2002/10/30 12:25:51 + + aic79xx.h: + Remove redundant declaration of ahd_print_devinfo(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#69 edit + +Change 1608 by gibbs@bitkeeper-linux-2.4 on 2002/10/30 11:38:28 + + aic7xxx_osm.c: + Bring in DV state machine enhancements from the U320 + driver. + + aic79xx_osm.c: + Remove a left over diagnostic. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#66 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#135 edit + +Change 1607 by gibbs@bitkeeper-linux-2.4 on 2002/10/30 10:13:52 + + Pull DV branch into the mainline. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#127 integrate +... //depot/aic7xxx/aic7xxx/aic79xx.h#68 integrate +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#39 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx.c#93 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx.h#56 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#65 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#71 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#8 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#134 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#96 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#23 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#14 integrate + +Change 1604 by gibbs@overdrive on 2002/10/29 18:59:13 + + aic79xx_osm.c: + Correct module description to properly identify the + driver as AIC79XX. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#64 edit + +Change 1597 by gibbs@overdrive on 2002/10/29 14:09:41 + + aic79xx_osm_pci.c: + Remove redundant check for PCI-X controller. The bug + flag should be enough. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#14 edit + +Change 1596 by gibbs@overdrive on 2002/10/29 14:09:13 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#41 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#22 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#42 edit + +Change 1592 by gibbs@aslan on 2002/10/29 11:05:58 + + Implement work around for the Interrupt collission problem + on the 7902B. + + aic79xx.c: + When a sequencer interrupt occurs on the B, unpause + the sequencer and allow it to clear SEQINTCODE with + a second SEQINT prior to processing the "real" seqint. + This clears SEQINTCODE without requiring an extra + interrupt. + + Convert the SAW_HWERR sequencer interrupt into a + call to ahd_handle_hwerrint(). + + aic79xx.h: + Add AHD_INTCOLLISION_BUG. + + Add NO_SEQINT, which is the special value that we + use to initialize SEQINTCODE so that the host can + tell if there is a real SEQINT pending. + + aic79xx.reg: + Add SET_SEQINTCODE() macro to special case sequencer + interrupt processing based on AHD_INTCOLLISION_BUG. + + aic79xx.seq + Whenever the sequencer is restarted, insure that + SEQINTCODE is properly initialized. + + Convert a non-zero ERROR status to a SAW_HWERR + sequencer interrupt. + + Add set_seqint_work_around which will clear SEQINTCODE + after every SEQINT. + + Use SET_SEQINTCODE throughout the firmware. + + aic79xx_inline.h: + Use a read of HCNTRL to flush our write to CLRCMDCMPLT + on the RevB. This allows us to check to see if the sequencer + is paused and to initiate the interrupt collision workaround + without incuring an extra read. + + aic79xx_pci_c: + Set AHD_INTCOLLISIONT_BUG for the Rev B. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#126 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#67 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#53 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#67 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#38 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#52 edit + +Change 1590 by gibbs@overdrive on 2002/10/28 18:12:32 + + Regernerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#40 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#41 edit + +Change 1588 by gibbs@aslan on 2002/10/28 14:39:15 + + aic79xx_inline.h: + Add our controller name to the front of our + diagnostic "Setting Mode" messages. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#37 edit + +Change 1587 by gibbs@aslan on 2002/10/28 14:38:45 + + aic79xx.c: + aic79xx.reg: + Some 160 devices incorrectly accept 0xfe as a + sync offset, but will overrun this value. Limit + to 0x7f for speeds lower than U320 which will + avoid the persistent sync offset overruns. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#125 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#52 edit + +Change 1574 by gibbs@overdrive on 2002/10/26 20:42:36 + + aic7xxx_osm.c: + Add "paused = TRUE" in ahc_queue_recovery_cmd which + was lost in the conversion to use ahc_pause_and_flush_work(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#133 edit + +Change 1572 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/26 01:10:28 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#70 edit + +Change 1570 by gibbs@aslan on 2002/10/25 23:53:19 + + aic79xx_pci.c: + Remove stray/random extra 7901A generic PCI + table entry. Also switch the correct 7901A + generic entry to use ID_ALL_MASK since we + can only differentiate the 7901A from the + 7902 by checking for a "type field" of 0xE. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#51 edit + +Change 1565 by gibbs@overdrive on 2002/10/25 20:45:29 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#39 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#40 edit + +Change 1564 by gibbs@aslan on 2002/10/25 20:44:25 + + aic79xx.h: + Add "feature" AHD_NEW_DFCNTRL_OPTS for SCSIENWRDIS. + + aic79xx.reg: + Add the SCSNENWRDIS field and the PLLDELAY register + definitions. + + aic79xx.seq: + Use SCSIENWRDIS when setting PRELOADEN on all + SG element writes save the first one on chips + that support this feature so that SCSIEN does + not get corrupted. + + Correct a bug in the legacy bitbucket handler. + We must save and restore our mode pointer now + that we can be using both FIFOs. + + aic79xx_pci.c: + PREQDIS in DEVCONFIG1 went away after the A2. + Remove all code that references this bit. This + is especially important since this bit was reused + in the B for a different HW fix workaround. + + Properly set the AHD_NEW_IOCELL_OPTS and + AHD_NEW_DFCNTRL_OPTS features for the B. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#66 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#51 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#66 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#50 edit + +Change 1540 by gibbs@bitkeeper-linux-2.4 on 2002/10/23 12:53:14 + + Make it possible for both the aic7xxx and the aic79xx driver + to rely on scsi_all.c yet still be built into the same kernel. + Since we can't use a module dependency to have a "library module", + symbols are renamed and the code included in each driver. + +Affected files ... + +... //depot/aic7xxx-dv/aic7xxx/aic79xx.c#8 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#9 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#8 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#3 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#30 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#13 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#3 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/cam.c#2 delete +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/cam.h#4 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/scsi_all.c#2 edit +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/scsi_all.h#2 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#9 edit + +Change 1538 by gibbs@aslan on 2002/10/22 21:45:34 + + aic79xx.c: + Modify use_ppr handling in ahd_build_transfer_message + to match the aic7xxx driver. + + aic7xxx.c: + Move a comment and remove a useless clearing of use_ppr. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#124 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#92 edit + +Change 1537 by gibbs@aslan on 2002/10/22 21:38:02 + + aic7xxx.c: + Bring back "use_ppr". We need to use_ppr anytime + doppr is true or we have non-zero protocol options. + The later case was not handled in the recent removal + of use_ppr. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#91 edit + +Change 1528 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/22 12:00:33 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#69 edit + +Change 1526 by gibbs@bitkeeper-linux-2.4 on 2002/10/22 11:54:03 + + Integrate from Head into aic7xxx-dv. + +Affected files ... + +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#6 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#6 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#6 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#3 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#3 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#8 edit + +Change 1525 by gibbs@overdrive on 2002/10/22 11:53:24 + + Regerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#38 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#39 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#20 edit + +Change 1520 by gibbs@aslan on 2002/10/21 20:40:11 + + aic7xxx.c: + Add a newline to ahc_dump_card_state() output. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#90 edit + +Change 1519 by gibbs@aslan on 2002/10/21 20:39:23 + + aic7xxx.c: + Update ahc_reg_print() to handle a NULL cur_col. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#89 edit + +Change 1518 by gibbs@aslan on 2002/10/21 20:37:24 + + aic7xxx.c: + Add additional diagnostic output to ahc_dump_card_state(), + and have it use the register pretty printing functions. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#88 edit + +Change 1517 by gibbs@aslan on 2002/10/21 16:30:21 + + aic7xxx.seq: + Move data fifo CLRCHN to mesgin_rdptrs which is a safer + location for doing this operation. This also saves a + sequencer instruction. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#52 edit + +Change 1516 by gibbs@aslan on 2002/10/21 16:18:49 + + aic79xx.seq: + Clarify a comment in the mesgin_rdptrs handler. + We need to clear the data fifo for CMD retries too. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#65 edit + +Change 1515 by gibbs@overdrive on 2002/10/21 16:06:12 + + aic7xxx_osm.c: + Adapt to conversion from IDENTIFY_SEEN to NO_IDENTIFIED. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#132 edit + +Change 1514 by gibbs@aslan on 2002/10/21 15:58:42 + + aic79xx.c: + Move "false parity error due to REQ release glitch" + workaround to the packetized busfree handler. We + now only look to see if this is the potential cause + of the error if we have ruled out all other causes. + Before, it might be possible for this workaround + to trigger on "real" busfrees. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#123 edit + +Change 1513 by gibbs@overdrive on 2002/10/21 15:53:19 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#37 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#38 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#19 edit + +Change 1512 by gibbs@aslan on 2002/10/21 15:51:41 + + aic79xx.c: + aic79xx.seq: + Handle unexpected command phases in the protocol violation + handler. Right now we treat these just like data phase + protocol violations. + + aic79xx.seq: + Optimize out a few instructions by using a common label + for protocol violations in mesgin and status phases. One + more instruction was removed by factoring out the status + received check in the mesgin_complete handler. + + aic7xxx.c: + aic7xxx.h: + aic7xxx.reg: + aic7xxx.seq: + Bring in the protocol violation handler from the U320 + driver and replace the NO_IDENT sequencer interrupt code + with the PROTO_VIOLATION code. Support for this code + required the following changes: + + SEQ_FLAGS: + IDENTIFY_SEEN -> NOT_IDENTIFIED + Added NO_CDB_SENT + + SCB_CONTROL: + TARGET_SCB == STATUS_RCVD for initiator mode + + scb->flags: + Added SCB_TARGET_SCB since we cannot rely on + TARGET_SCB as a target/initiator differentiator + due to it being overloaded in initiator mode to + indicate that status has been received. + + aic7xxx.seq: + Reset the FIFO whenever a short CDB transfer occurs + so that the FIFO contents do not corrupt a future CDB + transfer retry. + + Add support for catching the various protocol violations + handled by ahc_handle_protocol_violation. + + Reformat some comments. + + aic7xxx_osm.c: + Handle changes to SCB_CONTROL, scb->flags and SEQ_FLAGS. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#122 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#64 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#87 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#55 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#35 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#51 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#12 edit + +Change 1511 by gibbs@overdrive on 2002/10/18 17:37:10 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#36 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#37 edit + +Change 1509 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/18 17:33:40 + + Remove the DV framework from aic79xx. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#63 edit + +Change 1508 by scottl@scottl-template on 2002/10/18 15:27:23 + + Update to 6.2.13 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#95 edit + +Change 1505 by scottl@scottl-template on 2002/10/17 18:48:26 + + Integrate from aic7xxx-dv branch. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#86 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx.h#54 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#62 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#131 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#94 integrate + +Change 1491 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:51:15 + + aic79xx.reg: + Remove duplicate field. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#50 edit + +Change 1490 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:44:45 + + aic79xx.reg: + Bring in Rev B SNAPSHOT and SLOWCRC bit fields from + the DV branch. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#49 integrate + +Change 1488 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:38:54 + + README.aic79xx: + Correct rd_strm section to match correct syntax. + + Add amplitude, precomp, and slewrate options. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#4 edit + +Change 1487 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:30:42 + + aic79xx_osm.c: + aic79xx_osm.h: + Add code to set precomp, slewrate, and amplitude on + a per-controller basis. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#61 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#68 edit + +Change 1486 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:30:16 + + aic79xx.h: + aic79xx_pci.c: + SLEW -> SLEWRATE + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#65 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#49 edit + +Change 1484 by gibbs@overdrive on 2002/10/15 17:00:52 + + Regenerate Linux firmware and register definitions. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#35 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#36 edit + +Change 1483 by gibbs@aslan on 2002/10/15 14:53:35 + + Move IOCell paramters into softc and add a hook for the + OSM to modify these as well as other settings prior to + committing them to the chip. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#121 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#64 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#48 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#48 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#15 edit + +Change 1482 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 10:05:36 + + aic79xx_osm.c: + aic7xxx_osm.c: + Promote si.memsize to 64 bits pefore shifting by + PAGE_SIZE so that the returned value is not truncated + to 64GB. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#60 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#130 edit + +Change 1481 by scottl@scottl-template on 2002/10/15 00:59:37 + + Integrate debugging info nit from aic7xxx-dv + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#129 integrate + +Change 1480 by scottl@scottl-template on 2002/10/15 00:57:33 + + Update to version 6.2.12 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#93 edit + +Change 1478 by scottl@scottl-template on 2002/10/15 00:22:14 + + Integrate from the aic7xxx-dv branch + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#53 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#128 integrate + +Change 1474 by scottl@scottl-template on 2002/10/14 10:57:29 + + Integrate the aic7xxx dv work into head + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#85 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#127 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#92 edit + +Change 1465 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/10 16:11:43 + + Add three new insmod tunables for the IO Cell. They let you control + the slewrate, precomp, and amplitude. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#120 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#59 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#67 edit + +Change 1462 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/09 21:49:56 + + Add updated H2B identifiers + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#47 edit +... //depot/linux_mod_devel/scsi.aic79xx/dud/redhat/pcitable#2 edit + +Change 1457 by gibbs@bitkeeper-linux-2.4 on 2002/10/09 15:56:51 + + Integrate from aic7xxx -> aic7xxx_dv. + +Affected files ... + +... //depot/aic7xxx-dv/aic7xxx/aic79xx.c#3 integrate +... //depot/aic7xxx-dv/aic7xxx/aic79xx.reg#3 integrate +... //depot/aic7xxx-dv/aic7xxx/aic79xx.seq#3 integrate +... //depot/aic7xxx-dv/aic7xxx/aic79xx_pci.c#3 integrate +... //depot/aic7xxx-dv/aic7xxx/aic7xxx.c#2 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#2 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#3 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#3 integrate +... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#7 edit + +Change 1455 by gibbs@bitkeeper-linux-2.4 on 2002/10/09 15:08:23 + + aic7xxx.c: + Only force a renegotiation on a selection timeout + if the SCB was valid. Doing otherwise may be dangerous + as the connection was not valid for an unknown reason. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#84 edit + +Change 1454 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/09 14:45:23 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#66 edit + +Change 1453 by gibbs@overdrive on 2002/10/09 14:44:21 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#34 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#35 edit + +Change 1452 by gibbs@aslan on 2002/10/09 14:43:31 + + The double write workaround for CURRSCB is only required if + abort pending is set. Remove this work around and set the + abort pending bug bit on the B at least until we have better + confirmation that the double write is always safe. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#63 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#46 edit + +Change 1450 by gibbs@overdrive on 2002/10/09 00:32:41 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#33 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#14 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#34 edit + +Change 1449 by gibbs@aslan on 2002/10/09 00:31:44 + + aic79xx.c: + Enhance the packetized overrun handler to cover the + case of a data phase for an SCB that is not active. + + Update the comment on how CRC errors should be handled + in Harpoon2A and B. The comment is still not fully + accurate. We'll need more input from the hardware developers + before we can make the CRC handling really robust. + + Add diagnostics for unexpected busfrees that we take to + mean a negotiation message has been rejected. + + Fix several bugs in the iocell option setting code. For + starters, the amplitude setting is in ANNEXCOL 6. The + amplitude should also be set regardless of connection + speed. The negotiation table is now updated in the + chip reset code which occurs after the profile information + is stored in our softc. This avoids the problem of having + the chip reset code clear the neg table after the profile + code has written to it. Lastly, only clear the negtable + manually on chip reset if we are on rev A. + + Remove the redundant setting of the ABORTPENDING bit. + I have yet to verify that aborts actually work on the B. + + Have ahd_qinfifo_requeue_tail() save and restore the + current mode and operate in the command channel mode. + ahd_qinfifo_count requires this mode and some of the + latest callers to ahd_qinfifo_requeue_tail() are not + already in the command channel mode. + + Allow register pretty printing with a NULL cur_column. + + Add a space in a register diagnostic and print out SIMODE0 + in ahd_dump_card_state(). + + aic79xx.reg: + Add a macro RESTORE_MODE that sets the current mode to + the value stored in the register passed to it. + + Add the DFFBITBUCKET bit for packetized bitbucket. + + Correct the definition of AHD_ANNEXCOL_IOCELL_OPT1. + + aic79xx.seq: + Clean up the structure of our idle loop. This adds + a few instructions since the idle loop has been broken + into the following sub-routines that can be assembled + into customized idle loops: + + idle_loop_gsfifo - Service the Good Status FIFO + idle_loop_service_fifos - Run any LONGJMP handlers + idle_loop_cchan - Run command channel operations + + One or more of these routines are now called from the + main idle loop, the legacy idle loop, and the allocate_fifo + routine. This removes a bunch of duplicated code and hopefully + clarifies the code flow. + + Optimize out a few instructions. + + Write to CURRSCB twice in a row since it seems that these + writes are sometimes flakey. + + Use the MK_MESSAGE bit in SCB_CONTROL as our abort bit. + We now set MK_MESSAGE on every SCB completion so that + reselections to idle SCBs trigger an automatic abort. + + Now that the other FIFO may be active doing packetized + things during a legacy connection, have the legacy + idle loop use a LONGJMP handler and process LONGJMP + handlers for both FIFOs. + + Have the CFG4OVERRUN handler use packetized bitbucket + if it is available. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#119 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#47 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#62 edit + +Change 1445 by gibbs@overdrive on 2002/10/05 00:10:28 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#32 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#33 edit + +Change 1444 by gibbs@aslan on 2002/10/05 00:07:22 + + aic79xx.c: + Add 4 TRACEPOINT sequencer interrupts useful for debugging. + + Record busfree time prior to clearing any critical sections + since we now clear any busfree interrupts while stepping. + + Add support for supressing unexpected busfree warnings + when we reject a QAS request after delivering a CRC + related message. + + Rev B hardware will not step with pending, pausing, + sequencer interrupts. Turn off the interrupt enables + for all pausing interrupts save ENBUSFREE. ENBUSFREE + must not be disabled or we will lose the ability to + detect unexpected busfree events until the start of + the next connection. Diagnostics have also been added + to track the stepping process under the MISC debug category. + + Add CLROVERRUN to the list of interrupts cleared by + ahd_clear_intstat(). + + Update PPR message conformance rules. RTI must be + disabled for non-paced transfers. + + Don't apply RevA negtable corrections to the B. + + First pass at supporting RevB IOCELL settings. Currently + the settings for precomp are the same for Rev A and B, + so they share code. This will have to change if these + numbers are adjusted further. It may be possible to remove + the RevA HP_BOARD options, but I still need to verify that + with Brandon Aubrey. + + If a device rejects a PPR message after the full PPR + message has been sent, assume it does not understand + SPI-4 PPR options and negotiate without them. This + allows us to negotiate U160 with certain Fujitsu + U160 drives. + + Use enhanced DFFSTAT CURRFIFO status and adjust code + appropriately. + + CPQ->HP + + Set LQONOCHKOVER in LQOSCSCTL to avoid spurious LQO + overrun conditions. + + Negotiate RTI if it is available. + + aic79xx.h: + Add RTI and NEW_IOCELL_OPTS as AHD options enabled on + the B. + + Document each ahd_bug entry in the enumeration for quick + reference and add the AHD_LQOOVERRUN_BUG and + AHD_PACED_NEGTABLE_BUG entries. + + CPQ-HP + + Add the expect QAS reject busfree flag in ahd_msg_flags. + + aic79xx.reg: + Add four tracepoint sequencer interrupts. + + Modify CURRFIFO definition for Rev A backwards compatibility + while using Rev B enhanced mode. + + Add the LQOSCSCTL register. + + Correct spelling of CURRFIFODEF in SCSCHKN. + + Add new IOCELL option ANNEX column definitions. + + Update CCSGCTL to move of CCSGEN in Rev B. This + definition allows backwards compatibility, but may + change should we decide to optimize code due to this + change. + + Align QOUTFIFO_NEXT_ADDR on a 4 byte boundary since on + the B, this is required of any location that will be used + as the source for a block move to SCB/SGHADDR. + + aic79xx.seq: + Hit CCSCBRESET after setting the target address in + SCBHADDR to mirror what the CHIM sequencer does. I + don't believe this has any real effect but was a holdover + from debugging command channel DMA operations up to + the host on the B. + + Simplify the run down of the qoutfifo loop by rearranging + it a bit. We no longer special case loading first element. + + Allow non-pack transactions to use either FIFO without + waiting for the other FIFO to clear on Rev B. + + Remove an unecessary clear of SHCNT[1] and SHCNT[2] in + the embedded cdb transmission case. + + Do not rely on SCSIENACK being visible until at least one + sequencer instruction after it is written. While this + is safe on RevA, the wait is required on RevB. + + Adapt to changes in the definition of CCSGCTL. + + Always perform aligned, 4byte block moves to SCB/SGHADDR. + Single RMW operations are still okay too. + + aic79xx_pci.c: + HP -> CPQ + + Rearrange IDs to better match which chips they use. + + Convert to uniform product description strings. + + Simplify 7901A setup function. + + Add the NONPACKFIFO_BUG and PACED_NEGTABLE_BUG entries + for the A. + + Add rev B bugs and features. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#118 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#63 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#46 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#61 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#45 edit + +Change 1441 by gibbs@overdrive on 2002/10/04 16:29:18 + + Add missing "{}"s around diagnostic code so that status packet + information is not printed unless the SHOW_SENSE debug flag is + set. The message is only printed if the driver is compiled with + debug code enabled. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#117 edit + +Change 1432 by gibbs@overdrive on 2002/10/02 15:12:35 + + oder -> order. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#2 edit + +Change 1427 by gibbs@bitkeeper-linux-2.4 on 2002/10/01 18:56:39 + + Have the Makefile do all the relative path including instead of + putting this in all of the include directives in the Linux OSMs. + This will make the module building framework happy on 8.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#58 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#65 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#126 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#91 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#6 edit + +Change 1425 by gibbs@aslan on 2002/10/01 14:45:04 + + Add a space to the end of the ahc/ahd_print_devinfo routines + so that it behaves as expected by the code that uses it. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#116 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#83 edit + +Change 1424 by gibbs@bitkeeper-linux-2.4 on 2002/10/01 13:20:47 + + If the initial bus reset is diabled, attempt to negotiate async + rather than the fastest non-ppr rate below the user setting. We + will negotiate up to the user setting once inquiry information is + available. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#57 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#125 edit + +Change 1423 by gibbs@aslan on 2002/10/01 13:13:22 + + aic79xx.c: + Fix a style nit. + + Attempt to recover from a selection timeout that + occurs with an invalid SCB. This should never + happen, but its best to try and keep the machine + going. + + Force a renegotiation to a particular target after + a selection timeout. This handles the case of a + temporary interruption in the cable that the target + might notice and switch back to async without creating + a unit attention condition. + + Add code to ignore busfree interrupts which are in + fact parity errors resulting from a glitchy REQ + release of the free running clock by a target transitioning + to the bus free phase. This code needs to be tested by + FTL. A diagnostic will be printed if the debugging code + is enabled with the AHD_SHOW_MASKED_ERRORS bit set in + the debugging bitmask. + + Remove a redundant setting of the mode in the busfree + handler. + + aic79xx.c: + aic79xx.h: + aic7xxx.c: + aic7xxx.h: + Change ahc/ahd_upate_neg_request() to take a "negotiation + type" enum that allows us to negotiate: + o only if the goal and current parameters differ. + o only if the goal is non-async + o always - even if the negotiation will be for async. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#115 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#62 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#82 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#52 edit + +Change 1422 by gibbs@aslan on 2002/09/30 17:09:13 + + Don't panic (as a diagnostic to catch bugs) if we decided to + force the renegotiation of async even if we believe we are + already async. This should allow us to negotiate async instead + of the full user goal rate during startup if bus resets are disabled. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#114 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#81 edit + +Change 1420 by gibbs@aslan on 2002/09/30 13:49:47 + + Remove a left over '&' from the conversion to using our + softc referenced seeprom store. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#26 edit + +Change 1419 by gibbs@bitkeeper-linux-2.5 on 2002/09/27 16:44:04 + + Add a missing pair of curly braces to a conditional debug + statement. This ensures that debug code doesn't trigger if + it isn't enabled. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#80 edit + +Change 1418 by gibbs@bitkeeper-linux-2.5 on 2002/09/27 14:46:02 + + Reset commands_since_idle_or_otag in the mid-layer induced otag + case. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#56 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#124 edit + +Change 1417 by gibbs@bitkeeper-linux-2.5 on 2002/09/27 14:36:27 + + Honor ordered tagged requests from the mid-layer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#55 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#123 edit + +Change 1416 by gibbs@aslan on 2002/09/26 21:19:05 + + Remove redundant inclusion of inttypes.h in aicasm_gram.y + and properly sort inttypes.h into list of includes. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#25 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#23 edit + +Change 1415 by gibbs@aslan on 2002/09/26 16:02:22 + + Correct another BE issue in a printf. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#113 edit + +Change 1404 by gibbs@overdrive on 2002/09/24 17:27:07 + + Correct a spelling error. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#54 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#122 edit + +Change 1403 by gibbs@aslan on 2002/09/24 17:06:41 + + Correct a spelling mistake. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#79 edit + +Change 1400 by gibbs@overdrive on 2002/09/24 14:29:16 + + Make version numbers match what the driver prints on startup. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#2 edit + +Change 1399 by gibbs@overdrive on 2002/09/24 13:54:33 + + Add README files for embedded Linux drivers. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#1 add + +Change 1398 by gibbs@bitkeeper-linux-2.5 on 2002/09/24 12:50:32 + + Bump Linux driver versions: + aic7xxx = 6.2.10 + aic79xx = 1.1.1 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#64 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#90 edit + +Change 1397 by gibbs@bitkeeper-linux-2.4 on 2002/09/23 12:02:16 + + Add memory mapped I/O compile time option. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#9 edit + +Change 1396 by gibbs@bitkeeper-linux-2.4 on 2002/09/23 12:01:01 + + Add memory mapped I/O option to both the aic7xxx and aic79xx drivers. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#53 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#63 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#121 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#89 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#37 edit + +Change 1395 by gibbs@overdrive on 2002/09/23 11:19:47 + + aic79xx_osm.c: + aic7xxx_osm.c: + Remove two spurious but benign if statements that + probably appeared due to an editing botch. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#52 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#120 edit + +Change 1393 by gibbs@bitkeeper-linux-2.5 on 2002/09/20 14:58:43 + + aic7xxx_host.h: + Port to 2.5.X. + - Adapt to "biosparam" driver method specification + + aic7xxx_osm.c: + Port to 2.5.X. + - Include scsicam.h for disk partition functions. + - Switch from strtok to strsep. Strtok is no longer + available in 2.5.X. + - Adapt to the removal of the io_request lock and the + mid-layer acquiring our own lock prior to calling us. + This comes in the form of a new inline, + ahc_midlayer_entrypoint_lock(). For 2.5.X, this is + no-op since our lock is already held prior to entry + into the driver. + - Make use of scsi_assign_lock so that we can have our + lock held before we have our host structure. If we + used the host lock in the host structure, we would + not be able to acquire our lock in our interrupt handler + should a shared interrupt occur before we allocated + our host structure. + - Added comments indicating why it is that we don't do + the same ahc_unlock()/ahd_done_lock() dance in 2.5.X. + Since the done lock and the ahc_lock are one and the + same, it doesn't make sense to release and reacquire + the same lock. For older kernels, this dance is required + to avoid lock order reversals. + - In our error recovery entry points, move unlock_irq() + calls down to where we sleep so it is more obvious why + they are required. Add some comments about this too. + - Adapt to changes in the biosparam method specification. + + Turn runq scheduling into an inline to remove lots of + #ifdef clutter. + + aic7xxx_osm.h: + Make register pretty printing and option. + + Add ahc_midlayer_entrypoint_lock() inlines to help + manage the latest Linux mid-layer locking fiasco. + + ahc_done_lock/unlock are no-ops for 2.5.X. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#119 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#88 edit + +Change 1392 by gibbs@bitkeeper-linux-2.5 on 2002/09/20 14:47:28 + + Config.in: + Bring both the aic7xxx and aic79xx sections of this + file up to date in regards to the latest options. + aic79xx_host.h: + Port to 2.5.X. + - Adapt to "biosparam" driver method specification + - Modify driver template to be 2.5.X compatible + + aic79xx_osm.c: + Port to 2.5.X. + - Include scsicam.h for disk partition functions. + - Switch from strtok to strsep. Strtok is no longer + available in 2.5.X. + - Adapt to the removal of the io_request lock and the + mid-layer acquiring our own lock prior to calling us. + This comes in the form of a new inline, + ahd_midlayer_entrypoint_lock(). For 2.5.X, this is + no-op since our lock is already held prior to entry + into the driver. + - Make use of scsi_assign_lock so that we can have our + lock held before we have our host structure. If we + used the host lock in the host structure, we would + not be able to acquire our lock in our interrupt handler + should a shared interrupt occur before we allocated + our host structure. + - Added comments indicating why it is that we don't do + the same ahd_unlock()/ahd_done_lock() dance in 2.5.X. + Since the done lock and the ahd_lock are one and the + same, it doesn't make sense to release and reacquire + the same lock. For older kernels, this dance is required + to avoid lock order reversals. + - In our error recovery entry points, move unlock_irq() + calls down to where we sleep so it is more obvious why + they are required. Add some comments about this too. + - Adapt to changes in the biosparam method specification. + + Turn runq scheduling into an inline to remove lots of + #ifdef clutter. + + aic79xx_osm.h: + Make register pretty printing and option. + + Add ahd_midlayer_entrypoint_lock() inlines to help + manage the latest Linux mid-layer locking fiasco. + + ahd_done_lock/unlock are no-ops for 2.5.X. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#51 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#62 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#8 edit + +Change 1386 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/17 19:10:33 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#61 edit + +Change 1385 by gibbs@overdrive on 2002/09/17 18:48:09 + + aic79xx_osm.c: + Correct a case in the aic79xx_rd_strm_info code where + it was referencing the tag_info array by mistake. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#50 edit + +Change 1380 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/16 14:46:03 + + Include to get uint8_t definitions + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#24 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#6 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#17 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#22 edit + +Change 1378 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/16 12:49:34 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#60 edit + +Change 1377 by gibbs@aslan on 2002/09/16 12:47:19 + + Print out LQOSTAT* registers in ahd_dump_card_state. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#112 edit + +Change 1373 by gibbs@aslan on 2002/09/12 12:33:53 + + aic79xx.c: + Cover the ENBUSFREE case for bus resets too. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#111 edit + +Change 1372 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/12 11:26:37 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#59 edit + +Change 1371 by gibbs@aslan on 2002/09/12 11:24:42 + + aic79xx.c: + With the BUSFREEREV bug in effect, we must + muck with the ENBUSFREE toggle if the busfree + occurred in a non-pack connection. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#110 edit + +Change 1370 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/11 18:39:38 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#58 edit + +Change 1369 by gibbs@overdrive on 2002/09/11 18:38:24 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#31 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#32 edit + +Change 1368 by gibbs@aslan on 2002/09/11 18:37:30 + + Implement workaround for broken busfree-rev in the A4. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#109 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#61 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#60 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#44 edit + +Change 1364 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/11 10:02:19 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#57 edit + +Change 1363 by gibbs@overdrive on 2002/09/11 10:01:38 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#30 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#31 edit + +Change 1362 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/10 19:43:30 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#56 edit + +Change 1361 by gibbs@aslan on 2002/09/10 18:57:05 + + aic79xx.c: + Aesthetic changes to the dump_sglist routine. + We now indicate that the LAST flag was set in + the last SG element. + + aic79xx_inline.h: + Don't use ahd_htole64 on a variable that may not + be 64bits wide. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#108 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#36 edit + +Change 1360 by gibbs@aslan on 2002/09/10 18:52:55 + + aicasm_gram.y: + Adjust support for mvi with immediate of 0 to + handle the downloaded constant case. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#23 edit + +Change 1354 by gibbs@aslan on 2002/09/10 15:09:50 + + aic79xx.h: + Add two new bug defines that only apply to the A: + + o AHD_REG_SLOW_SETTLE_BUG + - Some Host registers take a few clocks to settle. + + o AHD_SET_MODE_BUG + - Interrupts must be disabled when changing the mode + + aic79xx.reg: + Modify SET_MODE and add a new TOGGLE_DFF_MODE macro + to optimize out the AHD_SET_MODE_BUG workaround. + + Make P_BUSFREE a field instead of a member of an + enum with a mask that doesn't apply to its bit location. + + aic79xx.seq: + Optimize code based on the two new bug defines. We + also iimplement, for the first time, the SLOW_REG + bug workaround. + + SET_MODE and TOGGLE_DFF_MODE can't have ';'s after + them now due to if/else clauses. + + Correct a ';' -> ':' syntax error. + + aic79xx_pci.c: + Add the two new bug defines to the list of bugs + that apply to the A4. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#60 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#45 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#59 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#43 edit + +Change 1352 by gibbs@aslan on 2002/09/10 14:44:31 + + aicasm_gram.y: + Allow mvi immediates of zero and have the assembler + convert these to the equivalent of a clr instruction. + This allows macros that do not know the value of the + immediate they are given DTRT. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#22 edit + +Change 1349 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/09 15:09:57 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#55 edit + +Change 1347 by gibbs@aslan on 2002/09/09 15:08:20 + + aic79xx.seq: + In pkt_saveptrs, wait for FIFOEMP before issuing + the clearchn. This seems to be the easiest way + to ensure that we don't complete the command to + the host prior to all data draining. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#58 edit + +Change 1346 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/08 17:46:07 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#54 edit + +Change 1345 by gibbs@overdrive on 2002/09/08 17:41:10 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#29 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#30 edit + +Change 1344 by gibbs@aslan on 2002/09/08 17:40:23 + + aic79xx.seq: + Correct a comment. + + In pkt_saveptrs, only clear the saveptrs interrupt + status once the pointers are saved. Otherwise we + may allow a cfg4data in the other FIFO to proceed + with incorrect data pointers. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#57 edit + +Change 1343 by gibbs@aslan on 2002/09/08 17:13:36 + + aic79xx.c: + Add diagnostic messages for DSPDATACTL workarounds. + + Negotiate HOLD_MCS for U320 transfers. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#107 edit + +Change 1342 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/06 17:46:11 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#53 edit + +Change 1341 by gibbs@overdrive on 2002/09/06 17:45:16 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#28 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#29 edit + +Change 1340 by gibbs@aslan on 2002/09/06 17:44:20 + + aic79xx.seq: + Fix syntax error. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#56 edit + +Change 1339 by gibbs@aslan on 2002/09/06 17:42:26 + + aic79xx.seq: + aic79xx.reg: + Fix SCBPTR corruption during mixed pack/non-pack + processing. When allocating a FIFO, an SCB can + complete using MODE3's SCBPTR. Save the SCBID + requesting the allocation into a new scratch ram + location that is unused by any other code prior + to running any FIFO threads and restore it once + allocation is complete. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#44 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#55 edit + +Change 1338 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/05 22:06:27 + + Update driver version + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#52 edit + +Change 1337 by gibbs@overdrive on 2002/09/05 21:48:01 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#27 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#28 edit + +Change 1336 by gibbs@overdrive on 2002/09/05 20:58:55 + + aic79xx.c: + Restart the sequencer prior to scheduling our + reset polling timer. We want to be sure the + sequencer is reset prior to the timer firing. + + In ahd_reset_poll(), put us in the SCSI mode + prior to tweaking registers. + + aic79xx.reg: + Use consistent case in defining register addresses. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#106 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#43 edit + +Change 1335 by gibbs@overdrive on 2002/09/05 20:19:00 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#26 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#27 edit + +Change 1334 by gibbs@aslan on 2002/09/05 18:26:26 + + aic79xx.h: + Give AHD_SHOW_SG it's own value. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#59 edit + +Change 1333 by gibbs@aslan on 2002/09/05 18:25:32 + + aic79xx.c: + Remove a redundant ahd_update_modes(); + + Only print scb path information in our SELTO handler + once we've verified that the SCB is not NULL. + + Fix formatting nits. + + Convert transmission error diagnostic code to ahd_reg_print(). + + Correct the comment for ahd_handle_pkt_busfree(). We + can enter this routine in any of modes 0, 1 and 3. + + In ahd_handle_pkt_busfree(), ensure we are in mode 3 + for dealing with LQOBUSFREE events, save and restore + the current SCBPTR in that mode, and use CURRSCB to + determine the SCB affected by the busfree rather than + the quite bogus SCBPTR. + + In ahd_abort_scbs(), operate in the SCSI mode so that + busy and clear TCL functions use that mode. It is + the only safe mode to use for temporary changes to + the SCBPTR register unless you have guaranteed that + no SCB fetches are inprogress in which case the command + channel mode is safe. + + Add assertions in the busy_tcl code to ensure we are + in the SCSI mode. + + Save and restore the SCBPTR in ahd_dump_card_state(). + We were always leaving SCBPTR pointing to the last + SCB traversed in our debug output. + + Use ahd_get_scbptr() in all cases. + + Cleanup some nits in ahd_dump_cardstate() output. + + Save and restore the scbptr in ahd_dump_scbs(). + + aic79xx.reg: + Remove the SCB_DMA field in SEQ_FLAGS2. It is not + needed for Harpoon's SCB dma fetch abort algorithm. + + aic79xx.seq: + Add a critical section around the SCB dma complete + code. It was possible for the host driver to "abort" + this SCB fetch while the sequencer was in the process + of handling the completion. The critical section + ensures that the SCB fetch is either aborted, or on + the waiting queue once we are outside of the critical + section. + + Complete the removal of the SCB_DMA flag. + + Fix the PDATA_REINIT case. We neglected to jump + to the dma_loop once the kernel had completed the + reinitialization. + + Fix the non-packetized bitbucket handler. We were not + properly waiting until the data phase was over. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#105 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#42 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#54 edit + +Change 1332 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/04 23:44:52 + + Version 1.0.12 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#51 edit + +Change 1331 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/04 23:43:46 + + Regen aic79xx firmware + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#25 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#26 edit + +Change 1330 by gibbs@aslan on 2002/09/04 18:04:26 + + aic79xx.c: + Don't call ahd_clear_intstat from our busfree handler. + The bus may well have moved on and we don't want to + clear state that pertains to the current connection. + If we get stray PERR status, it will now be handled + by the "catch-all" case in the SCSIINT handler. + + In ahd_clear_intstat(), deal with the AHD_CLRLQO_AUTOCLR_BUG. + This may have been the cause for the really strange + problems with mixed pack/non-pack configuratons. + + When clearing ENSELO in SCSISEQ0, make sure we are + in a known and safe mode. + + Remove "nonpkt_tag" from the "task_attribute_nonpkt_tag" + HSCB field. We no longer need nonpkt_tag information + in the SCB. + + Another update from Gordon for the bus reset quiet + the controller algorithm. + + Print the current byte on the bus in ahd_dump_card_state(). + + Remove spurious ','s from the printing of the pending list. + + Include SCB_TAG in pending list dumps. + + aic79xx.h: + Put SCB_TAG on a 4 byte boundary just to be paranoid. + + task_attribute_nonpkt_tag -> task_attribute + + aic79xx.reg: + Put SCB_TAG on a 4 byte boundary just to be paranoid. + + aic79xx.seq: + Remove extra AHD_MDFF_WSCBPTR_BUG code. The failure + can never occur since, in the A, only the non-pack + FIFO can ever be active during non-pack processing. + + Clear the busfree status when entering non-pack processing + so we can rely on it in await_busfree. + + aic79xx_inline.h: + Remove what is hopefully the last chunk of untagged queue + code from the driver. + + Don't bother setting the nonpack_tag since it is always + the same as the low byte of SCBPTR. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#104 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#58 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#41 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#53 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#35 edit + +Change 1328 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/03 17:30:10 + + Version 1.0.11 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#50 edit + +Change 1327 by gibbs@overdrive on 2002/09/03 17:21:56 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#25 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#18 edit + +Change 1326 by gibbs@aslan on 2002/09/03 17:20:25 + + Remove a spuriously expanded $FreeBSD$. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#5 edit + +Change 1325 by gibbs@aslan on 2002/09/03 17:14:43 + + aic79xx.c: + Add a missing space in the pending list + debug output code. + + aic79xx.h: + Add AHD_MDFF_WSCBPTR_BUG. + + aic79xx.reg: + Reserve mode specific scratch location + REG2 for interrupt handler use only. + This avoids any potential races between + normal and interrupt contexts. + + Put target mode bits after initiator bits + so that the initiator mode ones are printed + during diagnostics. We don't currently + support target mode. + + aic79xx.seq: + Add duplicate writes to SCBPTR when in modes + 0 and 1. + + Switch one section of ISR code over to using + REG_ISR. + + Perform clear target state after releasing the + FIFO so the FIFO is free as soon as possible. + + aic79xx_pci.c: + Turn on AHD_MDFF_WSCBPTR_BUG. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#103 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#57 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#40 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#52 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#42 edit + +Change 1323 by gibbs@aslan on 2002/08/30 23:06:40 + + Strip back down to $FreeBSD$. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#25 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#78 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#51 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#34 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#38 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#50 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#8 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#8 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#22 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#10 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#10 edit + +Change 1322 by gibbs@aslan on 2002/08/30 23:06:24 + + aic7xxx.seq: + Correct a bug in target mode handling of non-disconnected + transactions. The host would indicate the correct SCB to + DMA by setting the SCB id in the currently selected hardware + SCB. Unfortunately, we would then immediated allocate a + hardware SCB which, depending on the access patern might not + be the same hardware SCB that the host setup for us. Avoid + this by having the host put the SCBID into scratch ram. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#50 edit + +Change 1321 by gibbs@aslan on 2002/08/30 23:00:30 + + Strip back down to $FreeBSD$ + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#21 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#16 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#21 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aicasm/Makefile#1 add + +Change 1320 by gibbs@aslan on 2002/08/30 20:47:28 + + Expands revision tags. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#21 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#13 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#20 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#10 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#15 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#20 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#16 edit + +Change 1317 by gibbs@aslan on 2002/08/30 20:18:37 + + aic7xxx.c: + Make use of ahc_print_devinfo in the non-AHC_DEBUG case + to quiet GCC. We'll be adding more non-debug uses later + anyway. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#77 edit + +Change 1316 by gibbs@aslan on 2002/08/30 17:37:39 + + Expand Ids. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#24 edit +... //depot/aic7xxx/aic7xxx/aic79xx.c#102 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#56 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#39 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#51 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#34 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#41 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#76 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#50 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#33 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#49 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#16 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#37 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#49 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#6 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#6 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#6 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#21 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#13 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#9 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#8 edit + +Change 1313 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/29 16:44:35 + + Version 1.0.10 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#49 edit + +Change 1312 by gibbs@overdrive on 2002/08/29 16:17:01 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#23 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#17 edit + +Change 1311 by gibbs@aslan on 2002/08/29 16:08:39 + + aic79xx.c: + Correct negotiation regression in 1.0.9. We need to + cancel the negotiations for any unstarted SCBs to avoid + the "AWAITING MSG with no waiting message" assertion. + In the packetized world, it is safe to cancel negotiations + so long as we are active on the bus preventing the execution + queue from being run. Restore ahd_update_pending_scbs() to + update SCBs on the controller and have all callers only call + it for negotiation changes when the transaction is active. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#101 edit + +Change 1310 by gibbs@aslan on 2002/08/29 14:34:09 + + aic79xx.c: + aic7xxx.c: + Print pathing information with some diagnostics. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#100 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#75 edit + +Change 1309 by gibbs@aslan on 2002/08/29 14:01:21 + + aic7xxx.c: + aic7xxx.h: + Add support for AHC_SHOW_MESSAGES. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#74 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#49 edit + +Change 1308 by gibbs@aslan on 2002/08/29 14:00:48 + + aicasm.c: + aicasm.h: + aicasm_gram.y: + aicasm_scan.l: + aicasm_symbol.h: + Update copyrights. + + aicasm_symbol.c: + Update cpyright. + + Allow print reg functions for registers with + no fields. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#20 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#12 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#19 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#14 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#19 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#15 edit + +Change 1307 by gibbs@aslan on 2002/08/29 13:57:31 + + Update copyrights. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#50 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#33 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#40 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#20 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#11 edit + +Change 1306 by gibbs@aslan on 2002/08/29 13:56:41 + + aic79xx.c: + Use ahd_print_path() for selection timeout messages. + + Clear all interrupt sources, via ahd_clear_intstat(), + if we get an expected or unexpected busfree. It turns + out that the hardware clears some of them, but not all + of them when a busfree occurs which can confuse our SCSIINT + handler down the road. + + Update ahd_clear_intstat() to clear LQO/LQI type interrupts. + + Remove duplicate phase printing in the AHD_SHOW_MESSAGES + code. + + Update ahd_dump_card_state to use more of the "reg print" + functions. + + Conditionalize SG list printing under AHD_SHOW_SG. + + aic79xx.h: + Add AHD_SHOW_SG. + + aic79xx.reg: + Add several changes for Rev. B. These still need + to be verified. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#99 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#55 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#38 edit + +Change 1305 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/29 10:27:03 + + limit per-drive tags to 32 + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#7 edit + +Change 1304 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/29 10:26:10 + + Sync up with the linux-aic79xx-2.4.18_rc4 version of this in order to + get the new aic79xx_reg_print.o dependency. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#5 integrate + +Change 1302 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/28 10:55:57 + + Version 1.0.9 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#48 edit + +Change 1301 by gibbs@overdrive on 2002/08/27 16:50:51 + + Regen Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#22 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#23 edit + +Change 1300 by gibbs@aslan on 2002/08/27 16:49:33 + + aic79xx.c: + Print out both bytes of SINDEX in a diagnostic. + + Remove redundant pausing of the sequencer prior + to calls to ahd_update_pending_scbs(). It performs + its own pause management. + + In ahd_update_pending_scbs(), don't mess with SCBs + already DMA'ed down to the card. Fields in the + SCB control byte are referenced by the select out + code to determine queue state, so it is best to + leave them alone. The U320 cards don't embed + negotiation information in the SCBs anyway, so + the update was of little use. + + Protect against freezing the SIM Q multiple times + should a second bus reset be initiate prior to the + completed processing of a previous bus reset event. + + Print out some additional registers in ahd_dump_card_state(). + + Don't rely on the flexport seeprom type detection to + determine if an seeprom is present. The logic is not + present on all board types (e.g. mule boards). + + aic79xx.h: + Add bit for AHD_RESET_POLL_ACTIVE. + + aic79xx.seq: + Correct a few comments about how the sequencer operates. + + Always clear SG_STATE in disable_ccsgen. Leaving stale + info in there was confusing the non-packetized path. + + Inline the effect of a call to disable_ccsgen in the + S/G fetch code path. + + aic79xx_pci.c: + If bootverbose, indicate STPWLEVEL. + + aic79xx_osm.c: + Properly drop to a sync rate that does not require + information unit transfers if tagged queuing or the + disconnect privledge are not available. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#98 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#54 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#49 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#39 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#19 edit + +Change 1296 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/22 17:40:40 + + 1.0.8 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#47 edit + +Change 1295 by gibbs@overdrive on 2002/08/22 17:35:03 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#22 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#16 edit + +Change 1293 by gibbs@aslan on 2002/08/22 15:14:44 + + aic79xx.c + Style nits. + + Print out REG0 in the NO_MATCH case. It is more + interesting than ARG_1. + + Use AHD_NUM_LUNS_NONPKT for loops over the busy + target table. Packetized luns don't use the table. + + Use BUILD_TCL_RAW rather than rolling our own in + combination with BUILD_TCL in a few places. + + aic79xx.h: + Allow TCLs to store all lun bits. + + Lower bus reset hold time to 25us. + + aic79xx.seq: + Correct grammer in a comment. + + Simplify busy table operatins in mesgin_identify. + + Remove a commented-out diagnostic. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#97 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#53 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#48 edit + +Change 1292 by gibbs@aslan on 2002/08/22 15:10:03 + + aic7xxx.h: + Drop reset hold duration to 25us. + + aic7xxx.seq: + Correct the grammer in a comment. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#48 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#48 edit + +Change 1291 by gibbs@aslan on 2002/08/22 14:04:12 + + aicasm_symbol.c: + aicasm_symbol.h: + Fix symbol sorting logic. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#18 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#14 edit + +Change 1289 by gibbs@aslan on 2002/08/21 18:45:16 + + aic79xx.c: + aic7xxx.c: + Handle field values that can be 0 in ahd_print_register(). + The code would get into an infinite loop before. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#96 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#73 edit + +Change 1288 by gibbs@aslan on 2002/08/21 16:30:00 + + aic79xx.reg: + Remove unused SEQINTCODEs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#37 edit + +Change 1287 by gibbs@aslan on 2002/08/21 16:29:36 + + aic79xx.c: + It turns out that we can single step even if a + SCSIINT is pending. Remove clearing/restoring of + SCSIINT interrupt enables. This fixes an issue + with busfree detection getting turned off without + the possibility of re-enabling it. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#95 edit + +Change 1286 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/20 18:32:08 + + Update to 1.0.7, add required makefile changes + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#46 edit +... //depot/linux_mod_devel/scsi.aic79xx/Makefile#2 edit + +Change 1285 by gibbs@aslan on 2002/08/20 18:30:47 + + aic79xx.c: + Implement the latest bus reset card shutdown procedure. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#94 edit + +Change 1282 by gibbs@overdrive on 2002/08/20 17:18:57 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#45 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#87 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#14 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#15 edit + +Change 1280 by gibbs@aslan on 2002/08/20 14:15:29 + + aic79xx.seq: + Add a PREFIX for ahd generated definitions. + + Clean up more code related to the now defunct + disconnected lists. + + Use *stable* references to the current scsiid + and lun (SAVED_SCSIID/SAVED_LUN) for indexing + into the busy targets table. We were referring + to the possibly uninitialzied SCB_LUN of the + SCB we had indexed into. Bad. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#47 edit + +Change 1279 by gibbs@aslan on 2002/08/20 14:13:20 + + aic7xxx.c: + aic7xxx.h: + Fix a few typos. + + Implement ahc_print_register. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#72 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#47 edit + +Change 1278 by gibbs@aslan on 2002/08/20 14:12:23 + + aic79xx.c: + aic79xx.h: + More work on the ahd_print_register routine. + + Use the pretty print register routines in a few places. + + Fix a few typos. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#93 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#52 edit + +Change 1277 by gibbs@aslan on 2002/08/20 14:10:38 + + aic7xxx.seq: + Add a PREFIX designator for use in making assembler + generated definitions, unique. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#47 edit + +Change 1276 by gibbs@aslan on 2002/08/20 14:09:03 + + aic79xx.reg: + aic7xxx.reg: + Adapt to new assembler syntax. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#36 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#32 edit + +Change 1275 by gibbs@aslan on 2002/08/20 14:06:35 + + aicasm.c: + aicasm_gram.y: + aicasm_scan.l: + aicasm_symbol.c: + aicasm_symbol.h: + Add support for generating register field tables for + use in pretty-printing register values. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#19 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#18 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#13 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#17 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#13 edit + +Change 1272 by gibbs@overdrive on 2002/08/14 14:16:46 + + aic79xx_osm_pci.c: + Move warning about failures to memory map our controller + under bootverbose. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#12 edit + +Change 1271 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/14 08:02:15 + + Version 1.0.6 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#44 edit + +Change 1270 by gibbs@overdrive on 2002/08/13 16:02:05 + + aic79xx_osm.c: + aic7xxx_osm.c: + Use MSG_EXT_PPR_QAS_REQ rather than SID_SPI_QAS + when dealing with PPR options. The latter is used + when looking at inquiry information. Ooops. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#49 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#118 edit + +Change 1269 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/09 13:09:26 + + veriosn 1.0.5 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#43 edit + +Change 1264 by gibbs@aslan on 2002/08/08 15:19:58 + + aic79xx.c: + Use CAM_SEQUENCE_FAIL for protocol violations. + + Add first cut at a register printing function. + + Use better markers for the beginning and end + of ahd_dump_card_state. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#92 edit + +Change 1263 by gibbs@aslan on 2002/08/08 15:18:52 + + aicasm.c: + aicasm.h: + aicasm_gram.y: + aicasm_scan.l: + aicasm_symbol.c: + aicasm_symbol.h: + First cut at outputing register printing tables. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#18 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#11 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#17 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#12 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#16 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#12 edit + +Change 1262 by gibbs@overdrive on 2002/08/08 14:21:43 + + cam.h: + Add a mapping for CAM_SEQUENCE_FAIL. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#13 edit + +Change 1261 by gibbs@overdrive on 2002/08/08 10:56:31 + + aic79xx_osm.c: + aic7xxx_osm.c: + If QAS is not supported by a target, be sure to clear + the QAS flag in the ppr_options. Otherwise we may + attempt a PPR on a device that does not support it. + + Use prot_version rather than the protocol version in + the tstate as the latter is not initialized until later + in the routine and will be 0 the first time an inquiry + is sent to a device. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#48 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#117 edit + +Change 1259 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/07 09:36:00 + + Version 1.0.4 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#42 edit + +Change 1258 by gibbs@aslan on 2002/08/06 16:58:52 + + aic79xx.c: + Move expected bus free handling code to ahd_set_syncrate() + so that it will work for message types other than PPR. + + Test for expected bus frees if the last phase was either + MESGIN or MESGOUT. SPI4 dictates that the bus free will + occur once message phases are over, so we must handle the + case of other messages occuring prior to the bus going free. + We filter out other causes for the bus free (abort tag, etc.) + prior to treating this as an expected busfree. + + Wait a bus reset delay prior to performing the chip reset + for outgoing bus resets *just in case* this helps with the + stray arb issue. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#91 edit + +Change 1250 by gibbs@overdrive on 2002/08/05 14:23:13 + + aic7xxx_osm.c: + aic79xx_osm.c: + Fix off-by-one errors in calculations using the inquiry + data's additional_length field. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#47 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#116 edit + +Change 1248 by gibbs@overdrive on 2002/08/03 12:26:50 + + aic7xxx_proc.c: + Explicitly test for VLB and PCI cards in seeprom_write() + so we don't try this on EISA cards. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#22 edit + +Change 1246 by gibbs@overdrive on 2002/08/03 12:06:45 + + aic7xxx_proc.c: + AHC_PCI_CONFIG is always defined. Test for > 0 instead. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#21 edit + +Change 1244 by gibbs@overdrive on 2002/08/03 12:01:55 + + aic7xxx_osm.c: + ahc_pause_and_flush_work() -> ahc_pause_and_flushwork(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#115 edit + +Change 1243 by gibbs@overdrive on 2002/08/03 11:57:55 + + aic7xxx_proc.c: + Allow this to compile if PCI support is not + configured into the system. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#20 edit + +Change 1242 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/02 19:43:45 + + Version 1.0.3 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#41 edit + +Change 1240 by gibbs@aslan on 2002/08/02 17:47:26 + + aic79xx.c: + Force scb to be NULL if we have not been fully identified + in ahd_handle_protocol_violation(). + + Use MSG_ABORT_TASK for invalid reselections as per the + SPI4 spec. + + Push the waiting for the bus transceivers to setting into + ahc_chip_init(). This makes the wait occur for bus reset + operations too. Perform this wait prior to setting up + any of our iocell workarounds just in case the chip clobbers + them when the bus settles. + + Don't rely on the chip remaining paused while we wait for + the bus reset line to fall. We simply perform most of + the reconfiguration of the chip prior to starting to poll + for the reset line to fall. + + Fix a bug in ahd_reset_poll() in the case of the reset + line not falling. We would not exit the function to wait + again for the reset line to fall. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#90 edit + +Change 1228 by gibbs@overdrive on 2002/07/31 16:33:59 + + aic79xx_osm.c: + aic79xx_osm.h: + aic7xxx_osm.c: + aic7xxx_osm.h: + cam.h: + Emulate CAM_REQUEUE_REQ by returning check condition + status with the ABORTED COMMAND sense key. This works + even if we happen to be requesting an error recovery + command to be unconditionally requeued. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#46 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#40 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#114 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#86 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#12 edit + +Change 1227 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/31 12:12:00 + + version 1.0.2 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#39 edit + +Change 1226 by gibbs@overdrive on 2002/07/30 17:12:07 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#14 edit + +Change 1225 by gibbs@aslan on 2002/07/30 17:10:40 + + aic79xx.c: + When a selection timout occurs, we need not play with + ENBUSFREE. The busfree interrupt is a pulse so simply + clearing that interrupt source is sufficient. + + Fixup some curly braces. + + LASTPHASE -> PREVPHASE. LASTPHASE is a register + in scratch ram and not the bit in the PERRDIAG register + that indicates if the error has occurred before the + current phase. + + When setting the SCSI reset line, clear ENSELO and + ENARBO just in case they are set. We don't want the + chip to decide it need to perform a select out as + soon as the reset is over. + + Add a line of '='s prior to dumping card state. It + makes traces easier to follow. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#89 edit + +Change 1224 by gibbs@aslan on 2002/07/29 17:06:54 + + aic79xx.c: + When auto-sense fails due to non-0 scsi status, + we still need to release the selection queue. + Rearrange the code so that we do this step prior + to checking to see if this was an auto-sense + command. + + aic79xx.seq: + Be more careful about detection of protocol violations + flagged on command complete messages. The command complete + is valid even if the CDB was never fully sent if the + target has given us non-zero status. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#88 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#46 edit + +Change 1223 by gibbs@aslan on 2002/07/29 12:00:22 + + aic79xx.c: + Move handler for protocol violations to its own funciton. + Make another attempt to handle protocol violations that + occur before we have a fully identified connection. + + Add ahd_print_devinfo() to simplify diagnostics for + scenarios without a fully identified connection. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#87 edit + +Change 1221 by gibbs@overdrive on 2002/07/26 13:54:57 + + aic79xx_osm.c: + aic7xxx_osm.c: + When we get a QUEUE_FULL with only the transaction + returning QUEUE FULL outstanding, tell Linux that + the transaction received BUSY status. Linux doesn't + understand how to deal with QUEUE FULL correctly in + this situation and will leave the device frozen forever. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#45 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#113 edit + +Change 1217 by gibbs@overdrive on 2002/07/25 13:35:10 + + aic7xxx_osm.c: + Rely on ahc_pause_and_flushwork() instead of rolling our own. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#112 edit + +Change 1216 by gibbs@aslan on 2002/07/25 13:34:21 + + aic7770.c: + Remove an unused variable. + + aic7xxx.c: + Mask qoutfifonext in printf to avoid promotion + issues when printing its value. + + When we experience a dual edge error, send an + initiator detected error message regardless of + data direction. This is an error we can detect + either way. + + Cast the return from malloc. + + Use the SCSI offset as an indication that we have + a sync negotiation setup, not the period. + + In ahc_fetch_devinfo(), test for a few more bits + in SEQ_FLAGS to determine if we are acting as a + target that has been selected. Depending on how + far we are along in the transaction one or all + of them may be set. + + Align our S/G data structures on an 8byte boundary. + This already was occuring by luck, but using the + correct parameter to bus_dma_tag_create formalizes + this requirement. + + Guard against pending (re)selections in + ahc_pause_and_flushwork(). + + If SEARCH_REMOVE removes an SCB from an untagged queue, + clear its SCB_UNTAGGEDQ flag. + + When enabling a lun for target mode on a controller without + MULTARGID support, complain when an attempt is made to + enable another ID. + + aic7xxx.h: + Remove external declaration of the syncrate table. It + is no longer accessed directly by the OSM. + + aic7xxx.reg: + Add a definition for SXFRCTL2. This is just to serve + as documentation since we don't currently use this + register. + + Alias MWI_RESIDUAL with TARG_IMMEDIATE_SCB. This new + field is used for a more robust immediate target mode + SCB delivery scheme. + + aic7xxx.seq: + Adapt to TARG_IMMEDIATE_SCB scheme. + + Correct a problem with immediate target mode SCBs on + controllers without a command channel. We neglected + to CLRCHN before continuing the connection. + + Grammer nits. + + aic7xxx_pci.c: + Remove an unused variables. + + Simplify the code to read the SCB2 data. + + When checking termination on 785X cards, force + the wide termination to be off since these chips + do not support wide SCSI. + + aic7xxx_osm.c: + Use offset not period for sync rate negotiation decissions. + + Adapt to TARG_IMMDEDIATE_SCB scheme. + + Properly cast our softc in ahc_poll(). + + Remove test for P_BUSFREE when trying to determine if + an active SCB is valid. The SCB may be valid long + before we see the first phase. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#23 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#71 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#46 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#31 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#46 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#48 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#8 edit + +Change 1209 by gibbs@overdrive on 2002/07/24 16:53:31 + + aic79xx_osm.c: + Remove one last multi-line string constant. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#44 edit + +Change 1208 by scottl@scottl-hobbiton-mod_devel_aic7xxx on 2002/07/24 16:00:02 + + Fix compiliation errors + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#111 edit + +Change 1207 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/24 15:57:30 + + remove hard printf's + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#38 edit + +Change 1206 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/24 14:17:12 + + Driver is now at version 1.0.1 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#38 edit + +Change 1205 by gibbs@overdrive on 2002/07/24 14:09:02 + + aic79xx_osm.c: + Allow MODULE_LICENSE to work on 7.2AS. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#43 edit + +Change 1203 by scottl@scottl-linux-ia64 on 2002/07/23 11:18:20 + + Clear any bogus bus reset flags while the transceivers are settling + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#86 edit + +Change 1202 by scottl@scottl-linux-ia64 on 2002/07/22 19:10:49 + + Move the debugging printf in ahd_alloc to the end, avoiding a junk + pointer reference. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#85 edit + +Change 1201 by gibbs@aslan on 2002/07/22 17:53:37 + + aic7xxx_inline.h: + If chip interrupts are disabled, just return from our + interupt handler. In these cases, the interrupts are + likely disabled because we don't want any entry into + our interrupt handler, even those caused by a shared + interrupt handler. + + aic7770.c: + aic7xxx_pci.c: + aic7xxx_osm.c: + Allow the OSM to decide when to initially enable interrups. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#36 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#47 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#7 edit + +Change 1200 by gibbs@overdrive on 2002/07/22 17:51:33 + + aic7xxx_osm.c: + Allow the OSM to decide when to initially enable + interrupts. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#110 edit + +Change 1199 by gibbs@overdrive on 2002/07/22 17:46:04 + + aic79xx_osm.c: + Add a missing \n" + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#42 edit + +Change 1198 by gibbs@aslan on 2002/07/22 17:40:37 + + aic79xx_inline.h + If interrupts are not enabled, just return + from the interrupt handler. Interrupts are + usually disabled on the chip when we *don't* + want our interrupt handler entered which can + happen if the interrupt is shared. + + aic79xx_pci.c: + aic79xx_osm.c: + Let the OSM decide when to initially enable interrupts. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#32 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#37 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#18 edit + +Change 1197 by gibbs@overdrive on 2002/07/22 17:38:44 + + aic79xx_osm.c: + Use explicit newlines in multi-line string constants to + quiet GCC. + + Let the OSM enable interrupts once it is ready to + receive them. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#41 edit + +Change 1196 by gibbs@aslan on 2002/07/22 16:39:46 + + aic79xx.c: + Don't mask off the OVERRUN bit in sstat0 since + we do enable it. + + Assert that we are in a know mode other than MODE_CFG + when calling clear_intstat. + + To simplify logic, set the collision index in all + SCBs of a collision chain. + + AHD_BUILD_SCB_COL_IDX -> AHD_GET_SCB_COL_IDX + + CLRSCSIINT immediately after clearing any NTRAMPERRs + that occur during ahd_chip_init(). + + aic79xx.h: + aic79xx_inline.h: + Move COL_IDX macros to aic79xx.h. + + Optimize collision chain head table for multiple + targets, not multiple luns. The chain heads should + fit in 1 or 2 cache lines instead of an almost guaranteed + 1 per target. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#84 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#51 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#31 edit + +Change 1195 by gibbs@overdrive on 2002/07/22 11:00:46 + + aicasm_gram.y: + Remove an extranious break; + + The syntax for a C label is: identifier ':' statement + label: } is not valid syntax even though GCC has allowed + it for years. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#16 edit + +Change 1194 by gibbs@overdrive on 2002/07/22 10:57:44 + + aic7xxx_osm.c: + Quiet GCC 3.X warnings by using explicit newlines in + long string constants. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#109 edit + +Change 1192 by gibbs@overdrive on 2002/07/19 19:51:02 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#13 edit + +Change 1191 by gibbs@overdrive on 2002/07/19 19:50:13 + + aic79xx_osm.c: + Remove references to the untagged queues. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#40 edit + +Change 1190 by gibbs@aslan on 2002/07/19 19:48:44 + + aic79xx.c: + Remove untagged queue support code. + + Set SCB_ACTIVE when it is allocated rather than + let the OSM set it some time later. This closes + a race condition with collision list code that looks + for the active flag. + + aic79xx.h: + Move untagged queue cleanup. + + aic79xx.seq: + Remove the last reference to the SCB_NONPACKET_TAG + field. This field will be removed shortly. + + aic79xx_osm.c: + Remove untagged queue support code. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#83 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#50 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#45 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#17 edit + +Change 1189 by gibbs@aslan on 2002/07/19 19:18:20 + + aic79xx.c: + Pause the sequencer prior to updating the negotiation + tables if "paused" is false. + + Add the collision scb to the collision list, not + the just allocated scb, in ahd_get_scb(). + + Use the correct collision index when adding a just freed + scb back into a collision list. + + aic79xx.seq: + Simplify the mesgin_identify path now that we will + never have full disconnection lists. This also removes + a bug where we could select the wrong SCB as the + valid SCB for the connection. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#82 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#44 edit + +Change 1187 by gibbs@overdrive on 2002/07/19 17:27:05 + + aic79xx_osm.c: + Correct typo: simple_strltoul -> simple_strtoul. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#39 edit + +Change 1186 by gibbs@overdrive on 2002/07/19 17:19:45 + + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#12 edit + +Change 1185 by gibbs@overdrive on 2002/07/19 17:19:24 + + aic7xxx.seq: + Revert attempt to improve stuck PCI retry workaround + code. This was only generated as a test and should + never have been committed in the first place. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#45 edit + +Change 1184 by gibbs@overdrive on 2002/07/19 17:14:13 + + aic79xx_osm.c: + Get a collision index prior to getting an SCB to use. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#38 edit + +Change 1183 by gibbs@aslan on 2002/07/19 17:04:52 + + aic79xx.c: + Add string for the aic7901A. + + Implement new SCB free list management so that + all 512 scbs can be used in non-packetized + environments. + + Implement new command completion mechanism that + uses a toggling bit 15 to indicate that a new + entry has arrived. This avoids the kludgy writes + to the qoutfifo that may not work on processors + with certain types of cache retirement policies. + + Print out data structure sizes if AHD_DEBUG and + AHD_SHOW_MEMORY. + + Allocate the "sentinal" hardware SCB used for + queuing commands to the card separately so + that one of the 512 valid SCBs is not consumed + for this function. + + Add a space so we report "Wide Channel" instead of + "WideChannel". + + Cleanup allocation of the shared data area so that + the qoutfifo is always first. + + Add a fix for the RevA packetized Lun bug. The driver + will now setup a full 8byte lun in the previously + "spare" portion of the SCB and the SCB transfer size + is incremented if the bug is present. This required a + change in the layout of the disconnected SCB table to + make room for the larger lun field. + + aic79xx.h: + Add constants for the new qoutfifo scheme. + + Bump AHD_MAX_QUEUE up to 512 now that we have removed + all of the issues that previously restricted it to + a much lower value. + + Add a chip entry for the 7901A. + + Add the pkt_long_lun field to the hardware scb. + + SCB and ahc_softc updates for our new free scb + management algorithm. + + Stop inlining ahd_get_scb() and ahd_free_scb(). + The get routine also take a collision index so + as t make an optimum choice in which free SCB to + pick. + + aic79xx.reg: + Add QOUTFIFO_ENTRY_VALID_TAG which is or'd into the + top byte of each completed SCB's tag id to effect + the new completion scheme. + + Define the SCB_PKT_LUN field and new SCB transfer + sizes required to use this field.. + + aic79xx.seq: + Implement the new command completion scheme. + + Effect disconnected SCB table format change. + + aic79xx_inline.h: + When queuing a packetized SCB, update pkt_long_lun + in case we need it for the PKT_LUN workaround. + + Uninline ahd_get_scb() && ahd_free_scb(). + + Adjust for the change from storing an SCB to an HSCB + as the next "SCB" in the softc. + + Update for changes in the command completion scheme. + + aic79xx_pci.c: + Fix a few issues with detecting the 7901A. + + aic79xx_osm.c: + Determine the type of transaction prior and the + necessary collision index prior to allocating + an SCB. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#81 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#49 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#35 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#43 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#30 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#36 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#16 edit + +Change 1182 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/19 16:34:50 + + Add the global_tag_depth variable to the aic79xx driver + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#37 edit + +Change 1181 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/19 13:45:22 + + Update PCI tables for the 29320 and 7901 variants. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#48 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#35 edit + +Change 1180 by gibbs@aslan on 2002/07/18 17:08:50 + + aic79xx_pci.c: + Remove A3 support. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#34 edit + +Change 1179 by scottl@scottl-hobbiton-mod_devel_aic7xxx on 2002/07/18 15:46:45 + + Version 6.2.9: + Add new command-line argument global_tag_depth:, which + allows you to set the tag depth for every target on every + channel. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#108 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#85 edit + +Change 1172 by gibbs@overdrive on 2002/06/12 12:32:49 + + aic7xxx_osm.c: + Define use MODULE_LICENSE should it be defined instead + of testing against a specific kernel version. This + should allow 7.2AS driver diskettes to work. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#107 edit + +Change 1171 by gibbs@overdrive on 2002/06/06 17:40:00 + + aic79xx_osm.h: + Try two. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#37 edit + +Change 1170 by gibbs@overdrive on 2002/06/06 17:38:12 + + aic79xx_osm.h: + Convert to using AHD_DEBUG_OPTS. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#36 edit + +Change 1166 by gibbs@aslan on 2002/06/06 10:18:11 + + Cleanup AHD_DEBUG. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#80 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#47 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#29 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#33 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#14 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#8 edit + +Change 1164 by gibbs@aslan on 2002/06/06 10:05:23 + + aicasm_symbol.c: + Remove another multi-line string literal. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#15 edit + +Change 1163 by gibbs@aslan on 2002/06/05 16:49:30 + + aicasm.c: + Remove wrapping strings. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#17 edit + +Change 1159 by gibbs@bitkeeper-linux-2.4 on 2002/05/30 23:23:01 + + Config.in: + Makefile: + Cleanup our config data and makefiles. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#6 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#4 edit + +Change 1157 by gibbs@overdrive on 2002/05/30 22:15:02 + + aic79xx_osm.h: + Bump to version 1.0.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#35 edit + +Change 1156 by gibbs@overdrive on 2002/05/30 22:14:09 + + aic79xx_inline.h: + Rearrange code to setup hscb->dataptr so our operations + are not truncated to 32bits. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#28 edit + +Change 1154 by gibbs@aslan on 2002/05/30 21:53:39 + + aic79xx_inline.h: + Include the top 7 bits of address when setting up + hscb->dataptr for the 39BIT addressing mode. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#27 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#44 edit + +Change 1153 by gibbs@aslan on 2002/05/30 20:09:22 + + aic79xx.h: + union -> struct for the cdb_plus_sense structure. + This was missed in the re-arrangement of the hscb + declaration. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#46 edit + +Change 1151 by gibbs@overdrive on 2002/05/30 18:24:34 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#17 edit + +Change 1150 by gibbs@aslan on 2002/05/30 14:26:20 + + aic79xx_inline.h: + aic79xx_inline.h: + Break dataptr into u_int sized chucks for + printing to avoid compiler errors. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#26 edit + +Change 1149 by gibbs@aslan on 2002/05/30 14:25:13 + + aic79xx.c: + Panic if our hardware scb definition is not 64 bytes. + Hopefully this will catch agressive compiler padding + in the future. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#79 edit + +Change 1145 by gibbs@overdrive on 2002/05/30 13:51:24 + + aic79xx_osm.c: + Upate for change in hardware SCB definition. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#36 edit + +Change 1144 by gibbs@aslan on 2002/05/30 13:50:02 + + aic79xx.c: + aic79xx.h: + aic79xx_inline.h: + aic79xx_osm.c: + Rearrange hardware SCB definition to avoid + 64bit alignment/packing problems on native + 64bit platforms. Everything was aligned + correctly, but the compiler was not smart + enough to see this with how the structures + were previously defined. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#78 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#45 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#25 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#12 edit + +Change 1143 by gibbs@aslan on 2002/05/29 20:55:06 + + aic79xx.c: + aic79xx.h: + aic79xx_pci.c: + aic7xxx.c: + Convert a few straglers to inttypes. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#77 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#44 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#32 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#70 edit + +Change 1141 by gibbs@overdrive on 2002/05/29 20:27:14 + + aic79xx_osm.c: + Bring back an "int i;" that was removed to fix a + compile warning. It is used in debug code, so move + it to where it is used. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#35 edit + +Change 1139 by gibbs@overdrive on 2002/05/29 20:23:18 + + aic79xx_osm.c: + aic79xx_osm.h: + aic79xx_osm_pci.c: + aic7xxx_osm.c: + aic7xxx_osm.h: + aic7xxx_osm_pci.c: + Bring back the hack to force consistent memory to + be below 4GB. The IA64 platform only enforces this + if your PCI device's dma mask is set to 4GB. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#34 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#34 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#106 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#84 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#36 edit + +Change 1138 by gibbs@overdrive on 2002/05/28 14:19:38 + + aic79xx_osm.c: + And another. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#33 edit + +Change 1137 by gibbs@overdrive on 2002/05/28 14:17:46 + + aic79xx_osm.c: + Kill a few compile warnings. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#32 edit + +Change 1135 by gibbs@aslan on 2002/05/28 13:35:41 + + aic79xx.c: + aic79xx.h: + Enable ahd_fini_scbdata(). + + Change some #if 0's to AHD_DEBUG logs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#76 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#43 edit + +Change 1133 by gibbs@overdrive on 2002/05/28 12:58:11 + + aic79xx_osm.c: + Clean up some 'XXX' and #if 0 stuff. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#31 edit + +Change 1132 by gibbs@overdrive on 2002/05/28 12:51:44 + + aic79xx_osm_pci.c: + More typos. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#10 edit + +Change 1130 by gibbs@overdrive on 2002/05/28 12:45:53 + + aic7xxx_osm_pci.c: + Remove stray '{' + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#35 edit + +Change 1129 by gibbs@overdrive on 2002/05/28 12:43:47 + + aic79xx_osm_pci.c: + aic7xxx_osm_pci.c: + Restore inadvertantly removed #endif. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#34 edit + +Change 1128 by gibbs@overdrive on 2002/05/28 12:39:12 + + aic7xxx_osm.c: + Remove one more stray use of hw_dma_mask. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#105 edit + +Change 1127 by gibbs@overdrive on 2002/05/28 12:37:22 + + aic7xxx_osm.c: + aic7xxx_osm.h: + aic7xxx_osm_pci.c: + Don't bother messing with the dma mask during + alloc consistent calls. Linux guarantees that + the mappings will be below 4GB. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#104 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#83 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#33 edit + +Change 1126 by gibbs@overdrive on 2002/05/28 12:32:23 + + aic79xx_osm.c: + aic79xx_osm.h: + aic79xx_osm_pci.c: + Hook up 64BIT S/G support for Linux. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#30 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#33 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#8 edit + +Change 1125 by gibbs@aslan on 2002/05/24 17:11:19 + + aic79xx.h: + Pad ahd_dma64_seg to 16 bytes so we can still use + the ODD_SEG bit in the SG_CACHE. Otherwise we'd + be able to shrink the SG element down to 12 bytes. + + aic79xx.seq: + Complete 64bit S/G data address support and inline + sg advance. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#42 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#42 edit + +Change 1121 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/24 14:01:42 + + Beta 6 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#32 edit + +Change 1120 by gibbs@aslan on 2002/05/24 13:58:41 + + aic79xx.c: + Fix some big endian bugs. + + Set SPLTSTADIS in PCIXCTL so we don't issue a target + abort when we abort an SG element fetch. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#75 edit + +Change 1117 by gibbs@overdrive on 2002/05/23 16:44:08 + + aic79xx_osm.h: + Bump version number to 0.5.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#31 edit + +Change 1115 by gibbs@overdrive on 2002/05/23 16:41:47 + + aic79xx_osm.h: + Add PCIX configuration space definitions. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#30 edit + +Change 1114 by gibbs@aslan on 2002/05/23 16:39:32 + + aic79xx_pci.c: + First shot at PCI-X error reporting. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#31 edit + +Change 1113 by gibbs@aslan on 2002/05/23 16:36:13 + + aic79xx_inline.h: + We always need to run the qoutfifo even if only + doing target mode. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#24 edit + +Change 1112 by gibbs@aslan on 2002/05/22 13:38:33 + + aic7xxx_pci.c: + Allow autoterm if we have SCB based config data. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#46 edit + +Change 1110 by gibbs@overdrive on 2002/05/22 11:41:08 + + aic7xxx_reg.h: + aic7xxx_seq.h: + Regenerate firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#11 edit + +Change 1109 by gibbs@aslan on 2002/05/22 11:40:28 + + aic7xxx.c: + Remove some unecessary ahc_flush_device_writes(). + + aic7xxx.reg: + Remove redundant definition for SOFTCMDEN. + + aic7xxx_pci.c: + Only attempt auto-term if we have seeprom (or like) + data. + + For SPIOCAP based controllers, be sure that external + board control logic is enabled for termination control. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#69 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#45 edit + +Change 1108 by gibbs@aslan on 2002/05/21 16:51:16 + + aic79xx_pci.c: + SRAM_BASE -> SCB_BASE for reading SCB configuration + options. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#30 edit + +Change 1106 by gibbs@overdrive on 2002/05/21 15:03:07 + + Regenerate Linux aic79xx firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#16 edit + +Change 1105 by gibbs@overdrive on 2002/05/21 15:01:39 + + aic79xx_osm.c: + AHC -> AHD. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#29 edit + +Change 1103 by gibbs@overdrive on 2002/05/21 14:57:59 + + aic79xx_osm.c: + aic79xx_osm.h: + Add queue full and busy status timer to the aic79xx driver. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#28 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#29 edit + +Change 1102 by gibbs@overdrive on 2002/05/21 14:48:16 + + aic7xxx_osm.c: + Fix a few more compile errors. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#103 edit + +Change 1101 by gibbs@overdrive on 2002/05/21 14:45:36 + + aic7xxx_osm.c: + Really get the right timer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#102 edit + +Change 1100 by gibbs@overdrive on 2002/05/21 14:39:27 + + aic7xxx_osm.c: + Use the correct timer for busy and queue full handling. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#101 edit + +Change 1099 by gibbs@overdrive on 2002/05/21 14:36:05 + + aic7xxx_osm.h: + aic7xxx_osm.c: + Perform a 500ms delay for single command queue full status + and busy status since Linux does not delay in this case. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#100 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 edit + +Change 1098 by gibbs@aslan on 2002/05/21 13:37:36 + + aic79xx.c: + aic79xx.reg: + aic79xx.seq: + Switch over to a more generic "protocol violation" + handler. Use this to now catch cases where a + disconnect or command complete message is not + valid. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#74 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#34 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#41 edit + +Change 1091 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/17 14:35:15 + + Put a blank line before the Serial EEPROM text + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#7 edit + +Change 1090 by gibbs@overdrive on 2002/05/17 14:19:14 + + aic79xx_osm.h: + Bump to Beta 4. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#28 edit + +Change 1089 by gibbs@overdrive on 2002/05/17 14:18:47 + + aic79xx_seq.h: + aic79xx_reg.h: + Regenerate firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#14 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#15 edit + +Change 1088 by gibbs@aslan on 2002/05/17 14:16:58 + + aic79xx.c: + aic79xx.reg: + aic79xx.seq: + aic79xx_osm.c: + IDENTIFY_SEEN -> NOT_IDENTIFIED. + + Add NO_CDB_SENT flag to SEQ_FLAGS. Use this + to protect against DATA phases prior to having + a completed cdb transfer. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#73 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#33 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#40 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#11 edit + +Change 1087 by gibbs@aslan on 2002/05/17 13:32:27 + + aic79xx.c: + aic79xx.h: + aic79xx.reg: + aic79xx_pci.c: + Add Compaq special write bias and slewrate. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#72 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#41 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#32 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#29 edit + +Change 1086 by gibbs@overdrive on 2002/05/17 12:30:27 + + aic79xx_proc.c: + Adapt to ahd interface changes for seeprom routines. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#6 edit + +Change 1085 by gibbs@overdrive on 2002/05/17 12:28:21 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate Linux firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#14 edit + +Change 1083 by gibbs@overdrive on 2002/05/17 12:25:01 + + aic7xxx_proc.c: + Add a prototype. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#19 edit + +Change 1082 by gibbs@overdrive on 2002/05/17 12:24:49 + + aic79xx_proc.c: + Add write seeprom support. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#5 edit + +Change 1081 by gibbs@aslan on 2002/05/17 12:22:15 + + aic79xx.c: + aic79xx.h: + aic79xx.reg: + aic79xx_pci.c: + Add logic for writing to serial eeproms. + + Move all flexport logic into the core. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#71 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#40 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#31 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#28 edit + +Change 1080 by gibbs@aslan on 2002/05/17 11:43:50 + + aic79xx.c: + aic79xx.h: + aic79xx_pci.c: + Switch over to using a buffer to store seeprom contents. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#70 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#39 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#27 edit + +Change 1078 by gibbs@overdrive on 2002/05/17 11:31:05 + + aic79xx_proc.c: + Protect the aic79xx proc code with the ahd_list_lock. + + aic7xxx_proc.c: + Release the ahc_list_lock when errors are encountered. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#18 edit + +Change 1077 by gibbs@overdrive on 2002/05/17 11:16:59 + + aic79xx_osm.c: + ':' -> ';' + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#27 edit + +Change 1076 by gibbs@overdrive on 2002/05/17 11:14:48 + + aic79xx_osm.c: + aic79xx_osm.h: + Kill a few stray ahcs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#26 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#27 edit + +Change 1074 by gibbs@overdrive on 2002/05/17 11:08:38 + + aic79xx_osm.c: + aic79xx_osm.h: + aic79xx_osm_pci.c: + Linux implementation of the ahd_list_lock. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#25 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#26 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#7 edit + +Change 1073 by gibbs@aslan on 2002/05/17 10:57:35 + + Implement and use the ahd_list_lock. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#69 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#26 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#10 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#6 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#6 edit + +Change 1071 by gibbs@overdrive on 2002/05/17 10:23:20 + + aic7xxx_reg.h: + aic7xxx_seq.h: + Regenerate firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#10 edit + +Change 1070 by gibbs@overdrive on 2002/05/17 10:22:28 + + aic7xxx.seq: + Defer clearing SELDO until we have set IDENTIFY_SEEN. + This closes another race in the abort code. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 edit + +Change 1069 by gibbs@overdrive on 2002/05/17 10:21:50 + + aic7xxx_osm.c: + Treat IDENTIFY_SEEN flag as an indication that we + are still on the bus but still waiting for the first + REQ. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#99 edit + +Change 1068 by gibbs@overdrive on 2002/05/17 09:42:25 + + aic7xxx_osm.c: + aic7xxx_osm_pci.c: + Guard the two avenues for detach with the ahc_list_lock. + + Disable card interrupts prior to attempting detach. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#98 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#32 edit + +Change 1067 by gibbs@aslan on 2002/05/17 09:36:18 + + aic7770.c: + aic7xxx_pci.c: + Guarantee that the ahc_list_lock is not required + across the calls to the different config calls by + only putting the softc into the list if the config + is successful. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#21 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#44 edit + +Change 1066 by gibbs@aslan on 2002/05/17 09:30:44 + + aic7770.c: + aic7xxx.c: + aic7xxx_pci.c: + aic7xxx_osm.c: + Make sure that the ahc_list_lock is always aquired + ahead of the ahc_lock to prevent lock order reversals. + + Protect insertions of the ahc_softc into the ahc_list + with the ahc_list_lock. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#20 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#68 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#43 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#5 edit + +Change 1064 by gibbs@overdrive on 2002/05/16 22:36:00 + + aic7xxx_osm.c: + Don't register our reboot notifier twice. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#97 edit + +Change 1062 by gibbs@aslan on 2002/05/16 17:36:58 + + aic79xx.c: + Set HOST_MSG in the command complete with no status + case so that when we go to message out, the sequencer + will notify the host. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#68 edit + +Change 1061 by gibbs@overdrive on 2002/05/16 14:55:36 + + aic7xxx.c: + Freeze the untagged queues from within + ahc_search_untaggd_queues() in addition to + ahc_search_qinfifo(). There are other callers + to ahc_search_untagged_queues(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#67 edit + +Change 1059 by gibbs@overdrive on 2002/05/16 14:18:12 + + aic7xxx_osm.h: + Bump version number to 6.2.8. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#81 edit + +Change 1058 by gibbs@overdrive on 2002/05/16 14:17:45 + + aic7xxx_reg.h: + aic7xxx_seq.h: + Regenerate firmware for Linux. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#9 edit + +Change 1057 by gibbs@overdrive on 2002/05/16 14:16:41 + + aic7xxx_proc.c: + Perform a read after the write to the serial eeprom + to refresh our eeprom buffer. This allows the user + to verify that the write was good. + + Only acquire and release the seeprom if we are not + a VLB card. + + Be less strick in allowing writes. We want the user to + be able to overwrite an EEPROM that was previously corrupted. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#17 edit + +Change 1056 by gibbs@overdrive on 2002/05/16 14:13:32 + + aic7xxx_pci.c: + Set seep_config to NULL after freeing the seep buffer. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#42 edit + +Change 1055 by gibbs@aslan on 2002/05/16 13:59:01 + + aic7770.c: + aic7xxx.reg: + Add support for configuration extended translation + on the 274X. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#19 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#29 edit + +Change 1054 by gibbs@aslan on 2002/05/16 12:57:59 + + aic7xxx.h: + aic7xxx_pci.c: + Record if the BIOS config left over in SCB2 is used. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#45 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#41 edit + +Change 1053 by gibbs@aslan on 2002/05/16 12:57:24 + + aic79xx.h: + Reduce AHD_MAX_QUEUE to 255 until support for using + all SCBs is added. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#38 edit + +Change 1052 by gibbs@overdrive on 2002/05/16 11:23:12 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#13 edit + +Change 1051 by gibbs@aslan on 2002/05/16 11:06:00 + + aic79xx.c: + Correct some #if AHD_TARGET_MODE code. + + aic79xx.seq: + If we do not find a matching SCB when snooping + the bus, don't "double ack" the last byte. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#67 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#39 edit + +Change 1050 by gibbs@aslan on 2002/05/16 10:55:25 + + aic7xxx.c: + aic7xxx.h: + aic7xxx_pci.c: + Record if we are in large SCB mode and use this + to fully initialize all SCBs so that reads in + our debuging routines don't cause inadvertent + parity errors. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#66 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#44 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#40 edit + +Change 1049 by gibbs@aslan on 2002/05/16 10:41:35 + + aic7xxx.c: + Flush device writes after doing any CLRREQINITs. + + Protect ahc frees via the list lock. + + aic7xxx_osm.h: + FreeBSD implementation of the list lock. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#65 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#5 edit + +Change 1048 by gibbs@overdrive on 2002/05/16 10:29:21 + + aic7xxx_osm.c: + Set "paused" from within the "get the controller in + a consistent state" loop in ahc_queue_recovery_cmd(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#96 edit + +Change 1046 by gibbs@overdrive on 2002/05/15 17:53:13 + + aic7xxx_reg.h: + aic7xxx_seq.h: + Regenerate firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#8 edit + +Change 1045 by gibbs@aslan on 2002/05/15 17:51:20 + + aic7xxx.seq: + Only clear SELDO after we have removed the + active SCB from the waiting list. This allows + the host to use this as a confirmation that + the WAITING_SCB list is free of a just selected + SCB. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#42 edit + +Change 1044 by gibbs@overdrive on 2002/05/15 17:48:42 + + aic7xxx_osm.c: + aic7xxx_osm.h: + Add ahd_list_lock implementation for Linux. + + Protect against a pending selection in our recovery + queuing routine. + + aic7xxx_proc.c: + Use the buffer in the softc for seeprom access. Add + preliminary write support for VLB cards. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#95 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#80 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#16 edit + +Change 1043 by gibbs@overdrive on 2002/05/15 17:07:06 + + aic7xxx.c: + Clear out SCB_SCSIID and SCB_LUN when setting up + the SCB free list. We don't want a parity error + if we dump these out in ahc_dump_card_state(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#64 edit + +Change 1042 by gibbs@aslan on 2002/05/15 15:39:00 + + aic7770.c: + Seeprom config is now a pointer. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#18 edit + +Change 1040 by gibbs@aslan on 2002/05/15 14:47:38 + + aic7770.c: + aic7xxx.c: + aic7xxx.h: + aic7xxx_pci.c: + Store seeprom information in a buffer hung + off the softc. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#17 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#63 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#43 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#39 edit + +Change 1039 by gibbs@overdrive on 2002/05/15 13:05:07 + + Merge latest aic79xx driver into linux-aic79xx-2.4.0. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/Makefile#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd640.c#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/Makefile#2 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#5 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#3 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.reg#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.seq#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_core.c#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_host.h#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_inline.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.c#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.h#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_pci.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_proc.c#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_reg.h#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_seq.h#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.reg#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.seq#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_core.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_host.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.c#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.h#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_pci.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_proc.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_reg.h#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_seq.h#4 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/Makefile#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/scsi_iu.h#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sd.c#3 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr.c#3 integrate + +Change 1038 by gibbs@overdrive on 2002/05/15 12:50:49 + + aic79xx_osm.c: + aic79xx_osm.h: + Next pass at timer support in the Linux OSM. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#25 edit + +Change 1037 by gibbs@overdrive on 2002/05/15 12:48:28 + + aic79xx.c: + Move two variables into #ifdef AHD_TARGET_ROLE. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#66 edit + +Change 1036 by gibbs@overdrive on 2002/05/14 17:16:57 + + Regenerate firmware. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#7 edit + +Change 1035 by gibbs@overdrive on 2002/05/14 17:15:44 + + aic79xx_osm.c: + Register our reboot notifier on the first allocation + of a platform softc rather than in our module parameter + parsing routine. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#23 edit + +Change 1034 by gibbs@overdrive on 2002/05/14 17:08:01 + + aic79xx_osm.h: + First cut at ahd timer facility for linux. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#24 edit + +Change 1033 by gibbs@aslan on 2002/05/14 15:54:32 + + aic79xx.c: + aic79xx.h: + aic79xx.seq: + aic79xx_osm.h: + Poll for SCSI bus reset going away from a timer + context rather than deferring the re-enabling + of the SCSIRSTI interrupt to the sequencer. We + have to catch *every* bus reset due to the reset + behavior of the negotiation table. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#65 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#37 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#38 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#5 edit + +Change 1032 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/13 17:21:47 + + Regenerate firmware + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#11 edit + +Change 1031 by gibbs@overdrive on 2002/05/13 17:14:19 + + aic79xx_osm.h + Bump version to 0.3.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#23 edit + +Change 1030 by gibbs@aslan on 2002/05/13 17:11:08 + + aic79xx.c: + aic79xx.seq: + Have the sequencer re-enable incoming scsi reset + interrupts if, prior to starting an outgoing selection, + this interrupt is disabled. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#64 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#37 edit + +Change 1029 by gibbs@aslan on 2002/05/13 16:47:29 + + aic79xx.c: + Handle non-packetized phase unexpected busfree + events via the non-packetized handler regardless + of the packetized negotiation agreement in effect. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#63 edit + +Change 1028 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/11 22:55:03 + + Bump the version to 0.2.1. We missed 0.2.0, and the driver is + about to be re-released to address yet another script bug. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#22 edit + +Change 1026 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/10 22:38:10 + + Regenerate firmware + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#10 edit + +Change 1024 by gibbs@aslan on 2002/05/10 20:19:25 + + aic79xx.c: + Add an error handler for receiving a command complete + message without having received status. We will attempt + to abort the command. + + Enable the OVERRUN interrup and add a handler for it. + + Include lun information when compiling devinfo for the + unexpected bus free handler. + + Mask off the correct number of length bits when printing + S/G elements. + + Always update the neg table when setting bus width. + + Don't bother clearing the last three bytes of the annex + table on every update of the neg table. These are cleared + explicitly on chip reset and will, in the B, contain training + info. + + Reset the chip on third party resets. It is hoped that this + is the cause of some of the host basher issues related to + transferring into and out of emulation mode. + + Factor out more S/G printing code. + + aic79xx.reg: + Add a new sequencer interrupt code for a command complete + message with no status phase. + + aic79xx.seq: + Add checking for whether status has been delivered or not + in the command complete handler. + + Correct a test for a necessary bitbucket prior to having + the host reinitialize our data pointers. + + aic79xx_osm.h: + Change the AHD_DEBUG value for FreeBSD to 0x3FF. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#62 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#30 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#36 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#4 edit + +Change 1018 by gibbs@bitkeeper-linux-2.4 on 2002/05/08 17:21:24 + + aic7xxx_osm.c: + Replace SEARCH_REMOVE with SEARCH_COMPLETE in the search + of the untagged queue. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#94 edit + +Change 1017 by gibbs@overdrive on 2002/05/07 17:45:57 + + aic7xxx_osm.c: + Remove entries from the untagged queue prior to + doing a more general abort in ahd_linux_queue_recovery_cmd(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#93 edit + +Change 1016 by gibbs@aslan on 2002/05/07 17:34:02 + + aic7xxx.c: + aic7xxx.h: + Break out the search for entries in the untagged + queue into its own routine. Allow the user to + search based on io_ctxt too. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#62 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#42 edit + +Change 1015 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/07 14:54:52 + + Beta 1 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#21 edit + +Change 1014 by gibbs@aslan on 2002/05/07 14:53:39 + + aic79xx.h: + Limit max queue to 256 until nonpacketized tag + management is added to the driver. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#36 edit + +Change 1013 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/07 14:26:20 + + Add semicolon, initialize a variable before use. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#22 edit + +Change 1012 by gibbs@overdrive on 2002/05/07 14:25:46 + + aic79xx.h: + Change ahd_debug to be a uint32_t. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#35 edit + +Change 1011 by gibbs@overdrive on 2002/05/07 14:01:41 + + aic79xx.c: + Make ahd_debug a uint32_t. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#61 edit + +Change 1010 by gibbs@overdrive on 2002/05/07 13:59:31 + + aic79xx_osm.c: + Ignore short inquiry information for devices that + are already configured and seem to allow spi3/4 + ppr options. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#21 edit + +Change 1009 by gibbs@aslan on 2002/05/07 13:07:06 + + aic79xx.c: + Expand on our unexpected busfree handling. + We now have a better chance of getting the + packetized vs. non-packetized status correct. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#60 edit + +Change 1008 by gibbs@aslan on 2002/05/07 11:22:51 + + aic79xx.h: + Add a debug option for QFull messages. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#34 edit + +Change 1007 by gibbs@overdrive on 2002/05/07 11:22:04 + + aic79xx_osm.c: + Add a loging option for displaying Queue Full info. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#20 edit + +Change 1005 by gibbs@aslan on 2002/05/06 17:20:00 + + aic79xx.c: + Complete port of the ignore wide residue and + data pointers reinitialization routines. + + Create ahd_dump_sglist() and use it to factor out + some code. + + Use SCB_GET_TAG to access hscb->tag. This fixes + the first of many big endian issues in the driver. + + In the busfree handler, busfree time is valid even + for non-packetized phases. We now assume that a + packetized phase is active if lastphase is P_BUSFREE. + + If a parity error occurred in the current phase, + ack the current byte so long as it is not currently + a data phase. + + Print out the number of SCBs aborted during + non-packetized busfree handling. + + aic79xx.h: + Add definition for SCB_GET_TAG. + + Add a new debug entry for AHD_SHOW_QUEUE. + + Add prototype for ahd_dump_sglist. + + aic79xx.seq: + In our restore data pointers handler, release + and reacquire our FIFO to flush out any state + info before a possible return to data phase. + + When coming back to the data phase handler after + having already handled at least one data phase, + only bother with the PDATA_REINIT sequencer + interrupt if we think more data needs to be sent. + + aic79xx_inline.h: + More SCB_GET_TAG() cleanup. + + Add SHOW queue code. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#59 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#33 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#35 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#23 edit + +Change 1004 by gibbs@aslan on 2002/05/06 17:07:11 + + Sync FreeBSD Ids. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#61 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#41 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#28 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#41 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#35 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#38 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#16 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#10 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#15 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#9 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#11 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#14 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#11 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#5 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#5 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#9 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#4 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#4 edit + +Change 1002 by gibbs@overdrive on 2002/05/02 19:05:23 + + aic79xx_osm.c: + aic7xxx_osm.c: + Release the io_request lock in our detect routines + to avoid deadlock with other portions of the system + (possibly PCI) that may try to acquire a spin lock. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#92 edit + +Change 1001 by gibbs@overdrive on 2002/05/02 17:24:12 + + aic79xx_osm.c: + Put sense printing behind AHD_DEBUG. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#18 edit + +Change 1000 by gibbs@aslan on 2002/05/02 17:22:05 + + aic79xx.c: + Put even more messages behind AHD_DEBUG type stuff. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#58 edit + +Change 999 by gibbs@overdrive on 2002/05/02 16:59:43 + + aic79xx_osm.h: + Bump version to Alpha 8. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#20 edit + +Change 998 by gibbs@overdrive on 2002/05/02 16:59:16 + + aic79xx_osm.c: + aic79xx_osm.h: + Add options for enabling debugging code. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#19 edit + +Change 997 by gibbs@overdrive on 2002/05/02 16:58:22 + + Config.in: + Add compile time options to control AHD_DEBUG. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#4 edit + +Change 996 by gibbs@aslan on 2002/05/02 16:42:23 + + aic79xx.c: + Put sense and S/G mapping printfs under AHD_DEBUG. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#57 edit + +Change 995 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/02 15:37:38 + + Remove HD_DEBUG block that doesn't compile on Linux and doesn't + make much sense anyways. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#56 edit + +Change 994 by gibbs@overdrive on 2002/05/02 15:34:00 + + scsi_iu.h: + Pull in the latest from FreeBSD. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#3 edit + +Change 993 by gibbs@overdrive on 2002/05/02 15:19:13 + + aic79xx_reg.h: + aic79xx_seq.h: + aic7xxx_reg.h: + aic7xxx_seq.h: + Regenerate firmware for Linux. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#6 edit + +Change 992 by gibbs@aslan on 2002/05/02 15:03:26 + + aic79xx.c: + Save and restore modes in ahd_clear_fifo. + Also reset our long jump address. + + At the beginning of every message loop, + reset LQIPHASE_OUTPKT via LQIRETRY if + this condition is set. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#55 edit + +Change 991 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/02 12:55:04 + + Document the read streaming config switch + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/Documentation/Configure.help#4 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#3 edit + +Change 990 by gibbs@overdrive on 2002/05/01 22:03:06 + + aic79xx_osm.c: + First pass at read stream user tunables. Still + needs an update to the config file. + + Bump limited tag count to 64. Maxtor drives + still have issues with higher tag counts. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#16 edit + +Change 989 by gibbs@aslan on 2002/05/01 21:29:56 + + aic79xx.seq: + Restore an END_CRITICAL that was lost in the last + revision. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#34 edit + +Change 988 by gibbs@overdrive on 2002/05/01 21:23:18 + + aic79xx.seq: + Remove workarounds that only apply to chips <= A3. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#33 edit + +Change 987 by gibbs@aslan on 2002/05/01 21:19:06 + + aic79xx.c: + Split DFF reseting out of ahd_restart() and into + the routine ahd_clear_fifo(). This allows us to + safely restart the sequencer even if a FIFO has + been allocated to a new transaction. + + Add ahd_clear_fifo() calls as appropriate. + + Don't set PERRORDIS in SEQCTL0. + + Clean out sequencer interrupt codes that + are no longer in use. + + Add a handler for the ENTERING_NONPACK sequencer + interrupt. This is used to handle the message + phases usually related to CRC errors in packetized + connections. + + Clean up saved mode handling. The driver now + keeps the mode state as of when the interrupt + handler was entered in the softc as a separate + variable. ahd_unpause() will now restore these + values whenever it is called. This allows us to + remove several layers of saves and restores of + the mode register. + + Ensure we are in the SCSI mode when cleaning SCSI + interrupts. Some of these clear bits are only + available in that mode. + + Port a few more non-pack sequencer interrupt code + handlers. + + Remove a few non-pack sequencer interrupt code + handlers that don't apply in a non-SCB paging + world. + + Complete framework for handling CRC errors. + + In our busfree handler, clear whichever fifo + was active at the time of the busfree. + + Only force a renegotiation for busfrees in a + non-packetized connection. + + In ahd_clear_critical_sections(), turn off all + of the interrupt enables that might prevent stepping. + Make sure that we unpause the sequencer in its + original mode during the stepping process. + + Rely on ATNO instead of ATNI. + + Handle "expected" busfrees after delivering an + INITIATOR_DET_ERROR message. + + Remove pausing code in the ahd_alloc_scbs() since + we no longer touch the hardware in this routine. + + Add additional AHD_DEBUG logging. + + Correct ahd_index_busy_tcl. The target mask used + to set the SCBPTR was not correct. This broke + non-packetized operations. + + Add code to print out the value of the packetized + failures field in status packets should it be set. + + Have ahd_dump_card_state() report the sequencer's + saved mode, not the current mode. + + aic79xx.h: + Add message handler flags for packetized CRC error + handling. + + Add fields for storing the sequencer's mode pointer + as found before setting any modes in host code. + + Add additional AHD_DEBUG values. + + aic79xx.reg: + Clean up SEQINTCODEs. + + Fix typo in BUSFREE_DFF0: O -> 0 + + aic79xx.seq: + Remove a redundant test for SELDO. + + Workaround missing NONPACKREQ cases by looking + for ATNO and a message phase. + + Move the clearing of SELDO to outside of our + select_out handler's critical section. This + ensures that we don't clear this status while + stepping through a critical section. + + Remove a jmp to await_busfree by moving the + await busfree handler. + + Clear the LONGJMP_ADDR prior to entering the + NONPACK handler. + + aic79xx_inline.h: + Revamp mode pointer routines to allow automatic + restoration of the sequencer's mode pointer when + the sequencer is unpaused. + + Add debug logging for all mode pointer accesses. + aic79xx_pci.c: + Correct the logging of PCI target errors. + + aic79xx_osm.c: + Add DDB hooks for looking at AHD registers. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#54 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#32 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#29 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#32 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#22 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#25 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#8 edit + +Change 986 by gibbs@aslan on 2002/05/01 20:51:55 + + aic7xxx.c: + Force renegotiation if we have an unexpected + busfree with a target just in case the busfree + is due to a negotiation mismatch. + + If the target goes on to a message that should + be handled by the sequencer during a host message + loop, terminate our message loop. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#60 edit + +Change 980 by gibbs@overdrive on 2002/04/25 12:54:54 + + aic79xx_osm.c: + If a device does not support information units as + per its inquiry data, don't attempt to set IUs or + IU related bits in our PPR requests. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#15 edit + +Change 979 by gibbs@aslan on 2002/04/25 11:32:11 + + aic79xx.c: + Force renegotiation on a non-packetized busfree. + + Commonize some devinfo setup in the non-packetized + busfree handler. + + Modify ahd_fetch_devinfo to pull IOWNID and TOWNID + from mode 3. These registers are not valid in + modes 0 and 1. + + Add support for terminating an initiator message + loop early. This is used to return to sequencer + based processing for those messages that the + sequencer usually handles. + + When parsing configuration parameters, manually + disable IU negotiation if the disconnect privledge + is disabled. + + Print out IOWNID, TOWNID and SCSISEQ1 in + ahd_dump_card_state. + + aic79xx_osm.c: + Disable IU_REQs if disconnects are disabled. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#53 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#7 edit + +Change 977 by gibbs@aslan on 2002/04/24 14:54:33 + + aicasm/aicasm.c: + Style nit. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#15 edit + +Change 976 by gibbs@aslan on 2002/04/24 12:43:24 + + aic79xx_inline.h: + Don't attempt to run the TQINFIFO if we are + out of ATIOs with which to service it. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#21 edit + +Change 975 by gibbs@aslan on 2002/04/24 12:42:39 + + ahc_eisa.c: + ahc_pci.c: + Remove DEVINTERFACE stuff that crept in from + my private trees. + + aic7xxx_inline.h: + Correct a big endian issue with large (> 12 byte) + cdb support. + + aic7xxx_osm.c: + Correct another big endian bug having to do with + sense data copying. + + And another big endian bug in the initialization + of SCBs that do not transfer data. + + aic7xxx_osm.h: + Enable byte swapping macros for FreeBSD. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#34 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#4 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#3 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#3 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#3 edit + +Change 974 by gibbs@aslan on 2002/04/23 11:14:43 + + aic7xxx.c: + When clearing interrupts, perform a few + ahc_flush_device_writes() calls to ensure + status bits are cleared before any dependent + interrupt status bits. + + Add a comment about proper cleanup of the tqinfifo + under target mode. Special care has to be taken + if we are a twin channel controller. + + Clean up the bus reset logic as it pertains to + target mode. We still need a timer to wait for + the bus reset to fall so as to be completely immune + from "bus reset storms". + + Add a printf indicating that all ATIO resources + have been exhausted if this condition occurs and + we are running in bootverbose mode. + + aic7xxx.seq: + Properly set the synchronous transfer settings upon + resumption of a transaction with the disconnect privledge + disabled in target mode. These connections were always + run in async mode irrespective of the negotiated transfer + rate. + + aic7xxx_inline.h: + Only attempt to run the TQINFIFO if we have ATIOs available + to service any entries that are found. + + aic7xxx_osm.c: + Put target mode diagnostics for transactions without the + disconnect privledge under bootverbose. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#59 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#40 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#33 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#2 edit + +Change 969 by gibbs@overdrive on 2002/04/22 16:46:42 + + aic7xxx_osm.h: + Bump Linux driver to 6.2.7 for chip reset delay. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#79 edit + +Change 967 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/22 11:50:17 + + Note Alpha 7 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#18 edit + +Change 966 by gibbs@overdrive on 2002/04/22 11:46:47 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate firmware for Linux. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#5 edit + +Change 965 by gibbs@aslan on 2002/04/22 11:45:24 + + aic79xx.c: + Simplify LQO busfree handling. We now rely on + critical sections in the sequencer to make sure + that the sequencer is outside of the SELDO handler. + This allows us to clean up after the busfree with + one interrupt instead of two. + + Don't muck with the ENBUSFREE bit. The set of the + BUSFREE interrupt is a pulse, so simply clearing + the BUSFREE status is enough to kill the interrupt. + This allows busfree protection for any packetized + connections that might be in progress during the + BUSFREE handler. + + aic79xx.h: + Fix duplicate entries in AHD_BUG definitions. + + aic79xx.reg: + Kill the LQOBUSFREE_TRAP sequencer interrupt. + It is no longer needed. + + aic79xx.seq: + Add critical sections to protect against jumping + to the SELDO handler at the same time the kernel + clears SELDO. + + If an LQOBUSFREE is detected in our SELDO handler, + jmp back to the idle loop so that we exit the + critical section and the kernel can handle the + error. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#52 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#31 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#28 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#31 edit + +Change 964 by gibbs@overdrive on 2002/04/22 00:00:09 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate firmware for Linux. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#7 edit + +Change 963 by gibbs@aslan on 2002/04/21 23:58:57 + + aic79xx.seq: + Or in HDMAEN along with PRELOADEN just in + case HDMAENACK is not true at the time we + load a segment. This avoids accidentally + shutting off host transfers. This seems + to avoid the IBM drive issue and doesn't + require extra instructions or busy loops. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#30 edit + +Change 962 by gibbs@overdrive on 2002/04/21 23:24:21 + + aic79xx.c: + occured -> occurred. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#51 edit + +Change 961 by gibbs@overdrive on 2002/04/21 22:19:31 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate to latest. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#6 edit + +Change 960 by gibbs@aslan on 2002/04/21 19:49:06 + + aic79xx_pci.c: + Update PCI bus modes to better reflect reality. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#24 edit + +Change 959 by gibbs@overdrive on 2002/04/21 18:44:49 + + aic79xx.seq: + Do not clear ENSELO if there is a pending SELDO + already. We have not yet seen the SELDO, and + we rely on ENSELO set/clear sematics to distinguish + between packetized and non-packetized selections. + + or in IRET rather then use mvi in case some of + the bits in SEQINTCTL matter during interrupt + return. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#29 edit + +Change 958 by gibbs@overdrive on 2002/04/21 17:26:16 + + scsi_iu.h: + Correct off by 1 error. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#2 edit + +Change 957 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/21 00:23:33 + + Indicate Alpha 6 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#17 edit + +Change 956 by gibbs@overdrive on 2002/04/20 23:36:53 + + aic79xx_inline.h: + In ahd_lookup_scb(), guard against tag values + larger than AHD_SCB_MAX. Our array of indexes + in only that large. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#20 edit + +Change 955 by gibbs@overdrive on 2002/04/20 23:28:30 + + aic79xx.c: + Fix logic bug in ahd_abort_scbs(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#50 edit + +Change 954 by gibbs@overdrive on 2002/04/20 23:27:01 + + aic79xx.c: + Add missing '}'. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#49 edit + +Change 953 by gibbs@overdrive on 2002/04/20 23:25:00 + + aic79xx.c: + Limit abort processing of the busy targets table + to LUNS that are addressable when not packetized. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#48 edit + +Change 951 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/20 21:16:27 + + Add definition for PCIM_SERRESPEN + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#16 edit + +Change 950 by gibbs@overdrive on 2002/04/20 21:06:07 + + aic79xx_osm.c: + Remove call to ahd_search_disc_list() which is no + longer required. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#14 edit + +Change 949 by gibbs@overdrive on 2002/04/20 21:04:55 + + aic79xx_reg.h: + aic79xx_seq.h: + Regenerate firmware for Linux releases. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#5 edit + +Change 948 by gibbs@aslan on 2002/04/20 21:03:26 + + aic79xx.c: + Remove disconnected list handling code as this + product does not use this algorithm. + + Add a routine to determine if we are currently + in a connection that has a packetized agreement. + + Add a routine to switch to the currently active + FIFO's mode. + + Modify unexpected busfree handling for outgoing + packets. LQOBUSFREE is now a pollable status + rather than an interrupt. When the unexpected + busfree interrupt occurs, we simply clear it + if LQOBUSFREE is set. The sequencer will + eventually handle the SELDO and issue a sequencer + interrupt to the host. The host then cleans up + the execution queue and restarts the sequencer. + This avoids the problem of determining just where + the sequencer is executing at the time of the + BUSFREE since the sequencer can drift into the + SELDO handler while the BUSFREE interrupt is working + to pause it. + + Finish the port of the busy target table routines. + This are used during error recovery. + + Start documenting our strategies for handling + CRC errors. The code for this is only partially + completed. + + Tighten up the host message loop. We now have + the sequencer perform the actual reads and writes + to drive our ACK, to reduce the possibility of the + sequencer missing a short lived phase. + + Print out the HADDR and HCNT for both FIFOs + in ahd_dump_card_state(). + + aic79xx.h: + Add better documentation for the TCL format. + + Add a macro for building a TCL from target, + channel and lun, rather than SCSIID and lun. + + Add a bug entry for the issue on the A about + the packetized status bit being flakey. + + Add an SCB flag for recording transmission + errors. This flag should save us if the + target does not properly return status + in response to our initiator detected + error message. + + aic79xx.reg: + Add a new sequencer interrupt for the busfree trap. + + Add bit definition for LQIPHASE_OUTPKT. + + Target message loop definitions. + + aic79xx.seq: + Use ENSELO auto-clearing as the key to determining + if the connection is packetized or not. + + Add support for handling unexpected busfree + events in outgoing command packets. + + If we have already allocated a FIFO when entering + the command phase, this must be a retry. Free + the FIFO and reallocate it to make sure no + state from the previous transfer prevents the + retry from occurring properly. + + Host message loop changes. + + Add a possible workaround for hardware failing + to record the write to HDMAEN. We simply loop + setting this bit until the hardware finally + acknowledges that it is set. The seems to + only be required on SCSI writes to IBM Daytona + drives. More investigation is needed. + + aic79xx_osm.c: + Update for changes in host message loop + handling. + + Remove call to ahd_search_disc_list() that + is nolonger required. + + aic79xx_pci.c: + Add in new bug definitions. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#47 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#30 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#27 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#28 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#23 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#6 edit + +Change 935 by gibbs@aslan on 2002/04/17 10:28:58 + + aic79xx.c: + Perform a 1000us delay after asserting CHIPRST + and prior to touching an card registers. The + delay is not exact due to PCI write buffering + semantics, but it should still be sufficient to + avoid touching chip registers prior to the chip + becoming ready for such accesses. + + Modify ahd_chip_init() to leave the chip in a + paused state in AHD_MODE_SCSI. + + Modify ahd_loadseq() to leave the sequencer paused. + Code that follows such a call must call ahd_restart(). + + Perform a chip reset on every outgoing bus reset + on rev A hardware. + + aic79xx.h: + Add AHD_SCSIRST_BUG. + + aic79xx_inline.h: + Don't reset the channel just prior to panicing due + to a mode assertion. This could cause an infinite + recursion loop if the mode assertion is in + ahd_reset_channel or something it calls. + + aic79xx_pci.c: + Add in scsi bus reset requires chiprst bug to ahd->bugs. + + aic7xxx.c: + Perform a 1000us delay after asserting CHIPRST + and prior to touching an card registers. The + delay is not exact due to PCI write buffering + semantics, but it should still be sufficient to + avoid touching chip registers prior to the chip + becoming ready for such accesses. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#46 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#29 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#19 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#58 edit + +Change 931 by gibbs@aslan on 2002/04/16 19:19:23 + + aic79xx.c: + Break out post CHIPRST initialization from ahc_init() + so that we can reset the chip for workarounds. + + aic79xx.h: + AHD_PCIX_RST_BUG -> AHD_PCIX_CHIPRST_BUG. + + aic79xx.reg: + Move CMDSIZE_TABLE to the end of our current scratch + ram definitions and initialize it in ahd_chip_init(). + + aic79xx_pci.c: + Pull some PCI initialization code that needs to be + performed after every CHIPRST into aic79xx.c:ahd_chip_init(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#45 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#28 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#26 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#21 edit + +Change 930 by gibbs@overdrive on 2002/04/15 19:22:04 + + aic79xx_osm.h: + Turn on all debugging code. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#15 edit + +Change 929 by scottl@scottl-hobbiton-linux on 2002/04/15 15:45:29 + + Bump the driver version to ALPHA 5 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#14 edit + +Change 912 by gibbs@aslan on 2002/04/15 13:30:23 + + aic79xx.c: + Style fix. + + Move chip bug bitmap setup into the "chip personality" + handlers. + + Include a bus description in ahd_controller_info(). + + aic79xx.h: + Add a mask for bug workarounds that can be disabled + if we are not in PCI-X mode. + + Add bus_description to our softc. + + aic79xx_pci.c: + Initialize ahd->bus_description. + + Disable PCI-X specitific workarounds when operating + in PCI mode. + + Remove a few workarounds if we are an A4 chip. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#44 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#27 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#20 edit + +Change 905 by gibbs@overdrive on 2002/04/11 22:00:57 + + aic7xxx_osm.h: + Bump to version 6.2.6. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#78 edit + +Change 902 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/10 23:30:00 + + aic79xx.c: + Dump our card state should we encounter an unhandled + SCSIINT. Make the panic message for this case more + explicit too. + + Add a diagnostic for a new PPR Negotiation that should + end in a Busfree. This is the case of a pre-existing + IU_REQ agreement at the time of a Negotiation. + + Dump the card state when we encounter an unexpected busfree. + + Always refresh the neg-table when calling ahd_set_syncrate() + to handle the case of the sequencer setting the ENATNO bit + for a MK_MESSAGE request. We will always renegotiate in that + case if this is a packetized request. + + Correct the logic for setting MSG_FLAG_EXPECT_PPR_BUSFREE. + This should be set in the case of a pre-existing IU_REQ + agreement as well as if the IU_REQ agreement has changed. + + Kill a redundant call to ahd_update_neg_table. + + When dumping card state, also dump platform card state. + + aic79xx_osm.c: + user uint16_t rather than uint8_t for the array of user + settable tag limits. We will eventually allow 512 as + the max. + + Properly propogate sense data in status packets back + to the user. + + Dump card state in the abort and target reset handlers. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#43 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#13 edit + +Change 899 by scottl@scottl-hobbiton-linux on 2002/04/09 16:25:34 + + Remove seeprom_erase + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#14 integrate + +Change 895 by gibbs@overdrive on 2002/04/09 15:17:06 + + aic79xx_host.h: + aic79xx_osm.c: + aic7xxx_host.h: + aic7xxx_osm.c: + Move max_sectors initialization back into osm.c so + that it can be conditionalized on Linux kernel verison. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#91 edit + +Change 894 by scottl@scottl-hobbiton-linux on 2002/04/09 15:16:00 + + Add support for reading and writing the SEEPROM through the + /proc interface. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#40 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#13 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#9 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#37 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#15 integrate + +Change 891 by gibbs@overdrive on 2002/04/09 13:35:39 + + aic79xx_seq.h: + aic79xx_reg.h: + aic7xxx_seq.h: + aic7xxx_reg.h: + Start generating firmware at the toplevel only. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#4 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#4 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#4 edit + +Change 886 by gibbs@overdrive on 2002/04/07 23:42:22 + + aic79xx.c: + Kill debugger calls that are unsupported by Linux. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#42 edit + +Change 884 by gibbs@overdrive on 2002/04/07 21:46:23 + + aicasm/Makefile: + Reverse integration. + Kill .NOTPARALLEL. Use flex's -o. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#12 integrate + +Change 883 by gibbs@aslan on 2002/04/07 21:40:53 + + aic79xx.c: + When handling the "expected" unexpected busfree + after a negotiation, freeze the scb and the device + queue so that ordering is preserved. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#41 edit + +Change 882 by gibbs@aslan on 2002/04/07 21:21:53 + + aic79xx.c: + aic79xx.h: + aic79xx.seq: + Add a workaround for the outstanding split bug. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#40 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#26 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#27 edit + +Change 881 by gibbs@overdrive on 2002/04/07 21:10:53 + + aic79xx.c: + aic7xxx.c: + Kill return argument. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#39 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#57 edit + +Change 880 by gibbs@overdrive on 2002/04/07 21:09:54 + + aic79xx.h: + aic7xxx.h: + Kill return argument. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#25 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#39 edit + +Change 879 by gibbs@overdrive on 2002/04/07 21:06:29 + + aic79xx.c: + aic79xx.h: + aic7xxx.c: + aic7xxx.h: + Add a routine to verify that a softc is still + on our list and configured. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#38 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#24 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#56 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#38 edit + +Change 878 by gibbs@overdrive on 2002/04/07 21:04:35 + + aic79xx_host.h: + aic7xxx_host.h: + Add a missing comma. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#8 edit + +Change 875 by gibbs@overdrive on 2002/04/07 18:16:42 + + aic79xx_host.h: + aic7xxx_host.h: + aic79xx_osm.c + aic7xxx_osm.c + Set "max_sectors" in our host template so that the Linux + SCSI layer doesn't foolishly limit our I/O size. + + Set a few additional static fields into the template + initialization macro. + + aic7xxx_osm_pci.c: + aic79xx_osm_pci.c: + Use ah[dc]_find_softc rather than do a brute force lookup + in multiple places. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#90 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#31 edit + +Change 873 by gibbs@aslan on 2002/04/05 12:29:11 + + aic79xx.c: + Handle a few more sequencer interrupts. + + Monitor sstat3 during SCSIINT handling. + + Remove a duplicate comment. + + Enable checking of negotiation table and output + sync FIFO parity errors. + + When traversing the execution queue, only complain + of list corruption after itterating over max SCB + entries. Since elements can be queued outside of + the per-target lists, the num target limit coult + unintentionally fire. + + Correct a bug in the stitching of the TID lists in + the execution queue. We could lose a whole TID + list in certain scenarios. + + When handling status errors, save and restore the + current mode as well as clear any critical sections + in the firmware. We might otherwise corrupt sequencer + state. + + Add some more information to the ahd_dump_card_state() + output. + + Add a routine to dump out the state of all SCBs. This + might be useful from the debugger. + + aic79xx.h: + Prototype ahd_dump_scbs(). + + aic79xx.seq: + Stop using MK_MESSAGE as a flag for "dead" SCBs. + We should come up with another mechanism, but this + might confuse the cleanup of the execution queue + for SCBs that selected out with atn asserted. + + Use HDMAEN as a definitive test to see if a + saveptr interrupt is for a snapshot or not. + + aic79xx_pci.c: + Add a comma to the table of pci_status_strigs, so we + don't attempt to printf garbage. Oops. + + Clear latched pci status at the end of our PCI error + handler so that the pci error interrupt is de-asserted. + More logic is needed here to handle PCI-X errors. + + aic7xxx.c: + If we have an overrun on an auto-request sense, report + autosense fail, not data-run-error. + + Use AHC_NUM_TARGETS rather than a hard coded 16. + + Fix a typo. + + aic7xxx.reg: + Add a comment to the DIRECTION bit so I can stop + looking it up its polarity in the data book all the time. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#37 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#23 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#25 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#26 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#19 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#55 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#27 edit + +Change 840 by gibbs@overdrive on 2002/03/26 23:33:12 + + p4 integrate -r -b redhat-aic7xxx-2.4.7_10_i386. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#26 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#39 integrate +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#36 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#14 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#9 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#14 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#8 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#2 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#2 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#10 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#13 integrate +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#10 integrate + +Change 839 by gibbs@overdrive on 2002/03/26 23:32:40 + + Integrate -r -b redhat-aic7xxx-2.4.7_10_i386 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#89 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#14 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#3 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#3 branch + +Change 813 by gibbs@overdrive on 2002/03/13 20:18:34 + + aic79xx_osm.h: + Bump version number to 0.0.4 for Alpha 4 release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#13 edit + +Change 800 by gibbs@overdrive on 2002/03/13 14:56:13 + + aic79xx.c: + Remove TRACEPOINT6 code which is no longer used. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#36 edit + +Change 795 by gibbs@overdrive on 2002/03/13 14:39:50 + + aic79xx_osm.h: + Add an implementation for scsi_4btoul(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#12 edit + +Change 791 by gibbs@aslan on 2002/03/13 14:02:50 + + aic79xx.c: + Reset the bus if we encounter an overrun on a + status packet. + + Implement the AHD_CLRLQO_ATUTOCLR_BUG workaround. + We just need to manually clear the CLRLQO registers + when we use them. + + Roll LQISTAT1 handling into the + ahd_handle_transmission_errror(), handler. + + Don't qualify the BUSFREE status with ENBUSFREE. The + chip may well have moved on to an handled another + transaction on the bus, so we simply cannot rely on + ENBUSFREE giving us an acuate sense of whether this + is a true BUSFREE interrupt. Right now we defer + looking at BUSFREE interrupts until last in the hope + that we'll ignore spurious values of this bit by handling + the conditions we are sure of first. + + In handling busfree conditions allow the handler for that + condition to either unpause the sequencer or to force a + sequencer reset. + + Don't rely on the PACKETIZED status bit. It corresponds + to the *last* connection on the bus, not the current one. + Instead rely on LQISTAT1 giving us acurate information + about transmission errors that correspond to packetized + transfers. + + Handle unexpected busfrees that indicate the target + saw a bad CRC in one of our outgoing LQs. + + Add optional debugging information for kernel handled + message phases. + + Fix a spelling error. + + Add loging for QAS messages that occur when they shouldn't. + We will reject the message which should force a busfree. + + Add more bug entries. + + When cleaning up entries from the waiting for selection + queue, handle MK_MESSAGE SCBs specially as they are not + now placed into the per-target-id queues. + + Add more logging for sense packets. + + Link completed SCBs using a different set of link + pointers. This allows us to put the SCBs on the + complete queue without fear of corrupting the waiting + for selection queue if we have yet to see a pending + SELDO. + + Log the contents of the SCSIPHASE register in + ahd_dump_card_state(). + + aic79xx.h: + Add more bug entries. + + Add a debugging flag for printing information during + kernel handled message phases. + + aic79xx.reg: + LQOBUSFREE1 -> LQOBUSFREE + LQOPHACHG1 -> LQOPHACHGINPKT + + CLRLQOBUSFREE1 -> CLRLQOBUSFREE + CLRLQOPHACH1 -> CLRLQOPHCHGINPKT + + ENLQOBUSFREE1 -> ENLQOBUSFREE + ENLQOPHACHG1 -> ENLQOPHACHGINPKT + + LQOPHACHG0 -> LQOPHACHGOUTPKT + + Add SCB_NEXT_COMPLETE link in the CDB pad + area. + + aic79xx.seq: + Queue incoming MK_MESSAGE SCBs separately so as + to ensure we see the MK_MESSAGE bit on the outgoing + selection that will send this SCB. + + Convert all complete queue operations to use the + SCB_NEXT_COMPLETE link. + + Start adding more critical section wrappers. This + work still needs to be augmented and reviewed. + + When selecting out with a SCB that has MK_MESSAGE + set, don't bother clearing NEGPPROPTS. We now + look for the MK_MESSAGE flag in our SELDO handler + and can thus determine that this is actually a + "nonpackreq" selection. + + Add in the workaround for AHD_AUTOFLUSH_BUG. + + Correctly set the transfer size for status packets + so we don't think we've had an overrun. + + Enhance, I hope, the workaround for the PCIX arbiter + hang. We also now install the hang detection for + legacy. + + aic79xx_pci.c: + Take a first shot at handling PCI/PCI-X errors. More + work is required here. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#35 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#22 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#24 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#25 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#18 edit + +Change 779 by gibbs@overdrive on 2002/03/11 17:55:24 + + aic79xx_osm.c: + Disable ABORT and BDR attempts until error recovery + is better fleshed out. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#10 edit + +Change 778 by gibbs@overdrive on 2002/03/11 17:55:02 + + aic79xx_osm.h: + Remove EISA/VL defines that don't apply to the + hardware supported by this driver. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#11 edit + +Change 767 by gibbs@aslan on 2002/03/06 15:10:06 + + aic79xx_pci.c: + Add a #define for the A4 revision number. + + Add a placeholder for the B0 revision number. + + Disable pending PCI REQ assertion on anything + younger than the B0. It doesn't work if both + channels are active. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#17 edit + +Change 765 by gibbs@overdrive on 2002/03/04 21:59:30 + + aic79xx_osm.h: + Bump version number to 0.0.3. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#10 edit + +Change 764 by gibbs@overdrive on 2002/03/04 21:59:14 + + Handle integrate -r from redhat-aic79xx-2.4.7_10_i386 + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#3 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#5 integrate +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#3 integrate + +Change 761 by gibbs@overdrive on 2002/03/04 21:49:07 + + aic79xx.c: + Remove critical section clearing printfs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#34 edit + +Change 759 by gibbs@moria on 2002/03/04 21:36:11 + + aic79xx.c: + In ahd_devlimited_syncrate(), treat the precomp enable + bit specially. This is bit should be acted on regardless + of our goal for having the target precomp for us. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#33 edit + +Change 755 by gibbs@aslan on 2002/03/04 12:59:48 + + aic79xx_pci.c: + Only attach to A3 or newer H2A2 parts. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#16 edit + +Change 754 by gibbs@aslan on 2002/03/04 10:43:45 + + aic79xx.c: + Convert ahd_assert_atn to an inline. + + Add a comment indicating that blindly clearing out the + DMA channels in ahd_restart() is probably a bad thing. + Perhaps the best place to do this is in ahd_abort_scbs() + which should be able to match the SCB owning the FIFO + with the SCB pattern to kill off, but that is not completely + clear yet. + + Add the beginnings of an "illegal non-packetized phase" + handler. This interrupt will be invoked should a target, + with whom we've negotiated packetized, take us to a non-pkt + and non-message phase. The only situation we currently + handle is the case of a target taking us to the command + phase on the first REQ of what should be a packetized + connection. Our response to that condition is: + o Downgrade our current negotiation to async/narrow. + o Embed a TUR into the SCB to replace whatever, + possibly media altering, command was originally + in the SCB. + o Clear any tag information in the SCB and set + MK_MESSAGE. + o Set MSG_OUT to HOST_MSG, SAVED_SCSIID to the + scb's SCSIID, and SAVED_LUN to 0 (no identify + message, so target believes lun is 0). + o Clear the packetized flag in the SCB and set + SCB_ABORT and SCB_CMDPHASE_ABORT. + o assert ATN. + o Prepare the transaction to complete with + CAM_REQUEUE_REQ. + o When the Abort completes, we only abort the + SCB that encountered the error. This behavior + and the actual error code we return should be + reviewed. + + Convert some manual traversals of the phase table to calls + to ahd_lookup_phase_entry(). + + Port the MKMSG_FAILED sequencer interrupt handler. + + If busfreetime is non-zero, but we were performing nonpackreq + recovery, use the ahd_handle-nonpkt_busfree() handler. + + Handle the case of a new PPR negotiation to a target that + we have already negotiated packetized to. We should get + a busfree in this case. The remainder of the handling of + this situation is in the sequencer. + + Correct a bug in the critical section stepping code. We + were in the wrong register window when trying to clear + SIMODE0. + + If we are currently packetized with a target, the only + valid messages we can send at the beginning of the connection + are PPR or TUR. Therefore, supress the identify messages. + + Create a msg_flags field in ahd_softc. This replaces + msg_expect_ppr_busfree since we need to also record + whether the state of IU_REQ changed. + + Fix a grammer bug. + + Clear all message flags in the SCB during a request sense + that only intends to renegotiate with the device. + + Kill a debugging printf. + + Display the contents of SIMODE1, OPTIONMODE and MAXCMDCNT + during ahd_dump_card_state(). + + aic79xx.h: + Make AHD_SENSE_BUFSIZE a sequencer visible value. + + Redefine our Hardware SCB format so we can embed a + sense address in the case of cdbs <= 12 bytes or using + a pointer. + + Add the SCB_CMDPHASE_ABORT flag. + + Add ahd_msg_flags. + + aic79xx.reg: + Document the DIRECTION bit in DFCNTRL. + + Redefine our Hardware SCB format so we can embed a + sense address in the case of cdbs <= 12 bytes or using + a pointer. + + Make AHD_SENSE_BUFSIZE a sequencer visible value. + aic79xx.seq: + When we are about to select a device and the first SCB + has MK_MESSAGE set, make sure to enable ENAUTOATNO. + + Treat LQOPHACHG1 as an unexpected_nonpkt_phase. + + Make the PCI-X workaround for the hung arbiter even + more selective in the legacy case. We only need to + check for the hang condition if we are disconnecting + in the middle of a transfer. + + Enhance a comment about BITBUCKET handling in the + non-pack case. + + Correct a lable jump that should have been changed in + the last commit to this file. The previous lable has + been removed. + + Add support for handling a status packet without host + intervention if the sense address is embedded in the + SCB. + + aic79xx_inline.h: + Embed the sense address in the SCB if there is room. + + aic79xx_pci.c: + Be more careful about endianess when printing out + serial eeprom contents. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#32 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#21 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#23 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#24 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#18 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#15 edit + +Change 697 by gibbs@overdrive on 2002/02/26 17:49:44 + + aic79xx.c: + aic79xx.h: + aic79xx.reg: + aic79xx.seq: + aic79xx_pci.c: + Integrate changes from redhat-aic7xxx-2.4.7_10_i386 + back into the core files. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#31 integrate +... //depot/aic7xxx/aic7xxx/aic79xx.h#20 integrate +... //depot/aic7xxx/aic7xxx/aic79xx.reg#22 integrate +... //depot/aic7xxx/aic7xxx/aic79xx.seq#23 integrate +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#14 integrate + +Change 673 by gibbs@overdrive on 2002/02/11 16:36:16 + + aic79xx_osm.h: + Bump driver version to 0.0.2. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#9 edit + +Change 671 by gibbs@overdrive on 2002/02/11 16:28:09 + + aic7xxx_pci.c: + Pretend that there are no cables if we have + an illegal cable configuration. This may fix + problems on certain HP Kayak systems. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#35 edit + +Change 668 by gibbs@overdrive on 2002/02/11 15:13:10 + + aic79xx.reg: + aic79xx.seq: + Convert to text+ko + + aic79xx_pci.c: + Avoid endian issues when dumping the seeprom. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.reg#21 integrate +... //depot/aic7xxx/aic7xxx/aic79xx.seq#22 integrate +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#13 edit + +Change 667 by gibbs@aslan on 2002/02/11 15:09:27 + + aic79xx.c: + Add additional bug entries for Rev A errata. + + Don't attempt to perform current sensing on a + board unless we know that it is supported. Doing + current sensing when it is not support messes up + our external termination. + + Leave the force U160 stuff in place, but allow + U320 transfers now. + + Don't attempt QAS or read streaming on A2 hardware. + + aic79xx.h: + Add more bug entries. + + aic79xx.seq: + Add comment about why we have to check SEDO when + ENSELO is clear but prior to starting a new selection. + + Add critical sections around some of the places they + are needed. + + Add a first cut workaround for one of the PCI-X bugs. + This particular bug is fixed in A3. + + Conditionalize the last bit of the CURRSCB workaround. + + Set the SCB_DMA flag when we initiate an SCB dma. This + is the beginning of work to handle cancled DMAs from + the qinfifo. + + aic79xx_pci.c: + Only do current sensing if the card supports it. + + Truely initialize termctl if auto-term sensing fails. + + Set the low primary termination prior to setting any + external termination. This mirrors what CHIM does. + + Add a mode assert to ahd_write_flexport. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#30 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#19 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#21 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#12 edit + +Change 663 by gibbs@overdrive on 2002/02/11 13:13:52 + + aic7xxx_osm.h: + Bump Linux aic7xxx driver version number to 6.2.5. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#77 edit + +Change 661 by gibbs@overdrive on 2002/02/11 13:11:36 + + aicasm/Makfile: + Bring .NOTPARALLEL change into the top level. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#11 integrate + +Change 657 by scottl@scottl-linux on 2002/02/06 19:17:16 + + Serialize Makefiles. Use CONFIG_AIC79XX_BUILD_FIRMWARE flag. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#2 edit +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/Makefile#2 edit + +Change 650 by gibbs@overdrive on 2002/01/28 17:35:10 + + aic79xx_osm.c: + Limit tag depth to 16 under Linux to avoid QUEUE_FULL + issues with Maxtor drives. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#9 edit + +Change 648 by gibbs@overdrive on 2002/01/28 17:29:46 + + aic79xx.c: + Correct typo. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#29 edit + +Change 647 by gibbs@overdrive on 2002/01/28 17:22:18 + + aic79xx.c: + Move more diagnostic printfs under AHD_DEBUG. + + Force 160 as the maximum sync speed until 320 + issues are ironed out. + + aic79xx_pci.c: + Kill some diagnostic printfs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#28 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#11 edit + +Change 646 by gibbs@overdrive on 2002/01/28 17:18:52 + + aic79xx_osm.h: + Bump Linux version number to for 0.0.1 release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#8 edit + +Change 644 by gibbs@overdrive on 2002/01/28 16:43:03 + + aic79xx_osm.c: + Remove reference to ahc->seltime_b. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#8 edit + +Change 643 by gibbs@aslan on 2002/01/28 15:18:56 + + aic79xx.c: + aic79xx.h: + aic79xx.reg: + aic79xx.seq: + aic79xx_inline.h: + aic79xx_pci.c: + First pass at NONPACKREQ and CRC error handling. + + Turn on digital filtering and some additional IOCELL + workarounds. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#27 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#18 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#20 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#20 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#17 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#10 edit + +Change 640 by gibbs@aslan on 2002/01/27 14:15:43 + + aic79xx.c: + aic79xx.h: + aic79xx.reg: + Correct the selection timeout period on Rev A + parts where it is twice as long as the set value. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#26 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#17 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#19 edit + +Change 639 by gibbs@aslan on 2002/01/26 19:39:29 + + aic79xx.c: + Remove debugging printfs and place others inside + AHD_DEBUG statements. + aic79xx.h: + aic79xx_pci.c: + Complete support for termination current sensing. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#25 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#16 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#9 edit + +Change 637 by gibbs@overdrive on 2002/01/25 14:07:51 + + Firmware is generated in the leaf branch nodes. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#3 delete + +Change 626 by gibbs@overdrive on 2002/01/25 12:55:44 + + Remove extra blank line. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#76 edit + +Change 623 by gibbs@overdrive on 2002/01/25 12:48:59 + + Add text+ko and finish cleanup of no_probe. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#2 edit + +Change 621 by gibbs@overdrive on 2002/01/25 12:39:17 + + aic79xx_osm.h: + aic7xxx_osm.h: + linux/malloc.h has been deprecated in 2.4.15. Use + linux/slab.h instead which has been available since 2.4.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#75 edit + +Change 615 by gibbs@overdrive on 2002/01/24 17:27:58 + + aic79xx_osm.c: + Lose references to EISA and VLB inherited from + aic7xxx driver. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#6 edit + +Change 608 by gibbs@overdrive on 2002/01/24 13:32:31 + + To keep IDs coherent, we'll generate these in each branch we + ship to customers. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#2 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#2 delete + +Change 603 by gibbs@overdrive on 2002/01/24 13:00:46 + + Add assembled aic79xx firmware to revision control. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#1 add + +Change 601 by gibbs@overdrive on 2002/01/24 12:57:18 + + Add assembled firmware to revision control. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#1 add + +Change 587 by gibbs@overdrive on 2002/01/23 14:36:02 + + aic7xxx_osm.c: + Integrate PROBE_VL config changes back into Linux + driver mainline. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#88 integrate + +Change 580 by gibbs@overdrive on 2002/01/22 22:13:15 + + Integrate from linux-aic7xxx-2.4.0 -> linux-aic79xx-2.4.0 + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd640.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7770_osm.c#2 integrate +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.c#2 integrate + +Change 578 by gibbs@overdrive on 2002/01/22 21:48:24 + + aic7xxx_osm.c: + Protect against config not defining CONFIG_AIC7XXX_PROBE_EISA_VL + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#87 edit + +Change 576 by gibbs@overdrive on 2002/01/22 21:42:02 + + aic7770_osm.c: + Don't refer to aic7xxx_no_probe. The check for + whether to perform EISA/VL probes was made prior + to the call to the EISA/VL probe. + + aic7xxx_osm.c: + Add a configuration option for EISA/VL probing. + It will default to off to avoid clobbering PCI + devices that frequest those I/O ranges. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#86 edit + +Change 575 by gibbs@overdrive on 2002/01/22 21:34:25 + + aic7xxx_osm.c: + Default to not scanning for EISA/VL adapters. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#85 edit + +Change 569 by gibbs@aslan on 2002/01/22 13:56:22 + + aic79xx.c: + Clean up warnings related to currently disabled code. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#24 edit + +Change 568 by gibbs@overdrive on 2002/01/22 13:49:27 + + aic79xx_osm.h: + Include scsi_iu.h. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#5 edit + +Change 567 by gibbs@aslan on 2002/01/22 13:46:00 + + aic79xx.c: + Remove call to Debugger() which is not supported + under Linux. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#23 edit + +Change 566 by gibbs@overdrive on 2002/01/22 13:43:07 + + Initial aic79xx port to 2.4.0. + +Affected files ... + +... //depot/linux-aic79xx-2.4.0/COPYING#1 branch +... //depot/linux-aic79xx-2.4.0/CREDITS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/BUG-HUNTING#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/Changes#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/CodingStyle#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/Configure.help#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DMA-mapping.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/kernel-api.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/kernel-hacking.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/kernel-locking.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/mcabook.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/mousedrivers.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parport-multi.fig#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parport-share.fig#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parport-structure.fig#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parportbook.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/sis900.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/via-audio.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/videobook.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/wanbook.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/z8530book.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/IO-mapping.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/IRQ-affinity.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/LVM-HOWTO#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/README.DAC960#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/README.moxa#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/SubmittingDrivers#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/SubmittingPatches#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/VGA-softcursor.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/Netwinder#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Assabet#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Brutus#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/CERF#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/GraphicsClient#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Itsy#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/LART#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/PLEB#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Pangolin#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Tifon#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Victor#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/empeg#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/nanoEngine#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/serial_UART#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/Setup#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/empeg/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/empeg/ir.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/empeg/mkdevs#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/NOTES#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/README.FPE#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/TODO#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/binfmt_misc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cachetlb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cciss.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/aztcd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/cdrom-standard.tex#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/cdu31a#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/cm206#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/gscd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/ide-cd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/isp16#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/mcd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/mcdx#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/optcd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/sbpcd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/sjcd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/sonycd535#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/computone.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/cpqarray.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/devices.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/digiboard.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/digiepca.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/dnotify.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/exception.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/aty128fb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/clgenfb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/framebuffer.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/internals.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/matroxfb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/modedb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/sa1100fb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/tgafb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/fb/vesafb.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/Locking#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/adfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/affs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/bfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/coda.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/cramfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/ToDo#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/boot-options#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/rc.devfs#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ext2.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/fat_cvf.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/hpfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/isofs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ncpfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ntfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/proc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/romfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/smbfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/sysv-fs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/udf.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ufs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/umsdos.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/vfat.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/vfs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/floppy.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/ftape.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/hayes-esp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/highuid.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/dev-interface#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/functionality#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/i2c-protocol#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/proc-interface#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/smbus-protocol#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/summary#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/ten-bit-addresses#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i2c/writing-clients#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i386/IO-APIC.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i386/boot.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/i386/zero-page.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/ia64/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/ia64/efirtc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/ide.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/initrd.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/ioctl-number.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isapnp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/CREDITS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/HiSax.cert#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/INTERFACE#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/INTERFACE.fax#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.FAQ#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.HiSax#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.act2000#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.audio#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.avmb1#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.concap#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.diversion#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.eicon#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.fax#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.hfc-pci#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.hysdn#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.icn#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.pcbit#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.sc#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.syncppp#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.x25#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/isdn/syncPPP.FAQ#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/java.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/joystick-api.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/joystick-parport.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/joystick.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/bug-list.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/commands.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/config-language.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/makefiles.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kernel-doc-nano-HOWTO.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kernel-docs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kernel-parameters.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/kmod.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/locks.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/logo.gif#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/logo.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/m68k/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/m68k/README.buddha#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/m68k/kernel-options.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/magic-number.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/mandatory.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/mca.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/md.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/memory.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/mkdev.cciss#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/mkdev.ida#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/modules.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/moxa-smartio#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/mtrr.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/nbd.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/3c505.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/6pack.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/8139too.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/Configurable#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/DLINK.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/PLIP.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/README.sb1000#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/alias.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/arcnet-hardware.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/arcnet.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/atm.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ax25.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/baycom.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/bridge.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/comx.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/cops.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/cs89x0.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/de4x5.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/decnet.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/depca.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/dgrs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/dmfe.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/eql.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ethertap.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ewrk3.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/filter.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/fore200e.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/framerelay.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ip-sysctl.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ip_dynaddr.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ipddp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/iphase.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/irda.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/lapb-module.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ltpc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/multicast.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ncsa-telnet#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/net-modules.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/netdevices.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/olympic.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/policy-routing.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/pt.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/ray_cs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/routing.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/shaper.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/sis900.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/sk98lin.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/skfp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/smc9.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/smctr.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/soundmodem.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/tcp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/tlan.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/tms380tr.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/tulip.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/tuntap.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/vortex.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/wan-router.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/wanpipe.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/wavelan.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/x25-iface.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/x25.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/networking/z8530drv.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/nfsroot.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/nmi_watchdog.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/oops-tracing.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/paride.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parisc/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parisc/IODC.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parisc/debugging#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parisc/mm#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parisc/registers#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parport-lowlevel.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/parport.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/pci.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/pcwd-watchdog.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/pm.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/00-INDEX#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/SBC8260_memory_mapping.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/ppc_htab.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/smp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/sound.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/zImage_layout.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/ramdisk.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/riscom8.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/rtc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/s390/DASD#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/s390/cds.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/scsi-generic.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/scsi.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/serial-console.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sgi-visws.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/smart-config.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/smp.tex#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/smp.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/AD1816#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/ALS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/AWE32#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/AudioExcelDSP16#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/CMI8330#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/CMI8338#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/CS4232#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/ChangeLog.awe#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/ChangeLog.multisound#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/ESS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/ESS1868#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/INSTALL.awe#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/Introduction#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/MAD16#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/Maestro#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/MultiSound#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/NEWS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/NM256#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/OPL3#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/OPL3-SA#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/OPL3-SA2#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/Opti#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/PAS16#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/PCM1-pro#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/PSS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/PSS-updates#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.OSS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.awe#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.modules#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.ymfsb#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/SoundPro#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/Soundblaster#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/Tropez+#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/VIA-chipset#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/VIBRA16#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/Wavefront#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/es1370#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/es1371#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/mwave#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/solo1#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/sonicvibes#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/ultrasound#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/via82cxxx.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sound/vwsnd#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sparc/sbus_drivers.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/specialix.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/spinlocks.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/stallion.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/svga.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sx.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/fs.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/kernel.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/sunrpc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/vm.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/sysrq.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/telephony/ixj.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/unicode.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/CREDITS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/URB.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/acm.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/bluetooth.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/dc2xx.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/error-codes.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/hotplug.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/ibmcam.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/input.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/ohci.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/ov511.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/proc_usb_info.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/rio.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/scanner-hp-sane.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/scanner.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/uhci.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/usb-help.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/usb/usb-serial.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/API.html#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/CQcam.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/README.buz#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/README.cpia#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/CARDLIST#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/CONTRIBUTORS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/ICs#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Insmod-options#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/MAKEDEV#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Modules.conf#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/PROBLEMS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/README#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/README.WINVIEW#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Sound-FAQ#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Specs#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/THANKS#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/radiotrack.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/zr36120.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/vm/balance#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/vm/locking#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/vm/numa#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/watchdog.txt#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/xterm-linux.xpm#1 branch +... //depot/linux-aic79xx-2.4.0/Documentation/zorro.txt#1 branch +... //depot/linux-aic79xx-2.4.0/MAINTAINERS#1 branch +... //depot/linux-aic79xx-2.4.0/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/README#1 branch +... //depot/linux-aic79xx-2.4.0/REPORTING-BUGS#1 branch +... //depot/linux-aic79xx-2.4.0/Rules.make#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/bootloader.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/bootp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/tools/mkbb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/tools/objstrip.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/alpha_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/check_asm.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_apecs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_cia.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_irongate.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_lca.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_mcpcia.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_polaris.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_t2.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_titan.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_tsunami.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_wildfire.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/es1888.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_alpha.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_i8259.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_impl.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_pyxis.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_srm.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/machvec_impl.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/ns87312.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/osf_sys.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/pci_impl.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/pci_iommu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/proto.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/smc37c669.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/smc37c93x.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_alcor.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_cabriolet.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_dp264.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_eb64p.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_eiger.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_jensen.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_miata.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_mikasa.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_nautilus.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_noritake.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_rawhide.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_ruffian.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_rx164.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_sable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_sio.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_sx164.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_takara.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_titan.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_wildfire.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/callback_srm.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/clear_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/copy_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/csum_ipv6_magic.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/csum_partial_copy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/divide.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-clear_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-copy_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-csum_ipv6_magic.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-divide.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-memchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-strncpy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-stxcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-stxncpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strcat.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strlen.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strncat.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strrchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/fpreg.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memcpy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memmove.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/srm_printk.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/srm_puts.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stackcheck.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stackkill.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stacktrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strcasecmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strcat.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strlen.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strncat.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strncpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strncpy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strrchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stxcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stxncpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/math.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/qrnnd.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/sfp-util.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/alpha/vmlinux.lds.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/bootp/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/bootp/bootp.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/bootp/init.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/Makefile.debug#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-ftvpci.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-l7200.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-netwinder.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-sa1100.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/hw-bse.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/ll_char_wr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/setup-sa1100.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/vmlinux.lds.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/boot/install.sh#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/a5k#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/assabet#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/brutus#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/cerf#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/clps7500#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/ebsa110#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/empeg#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/footbridge#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/graphicsclient#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/integrator#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/lart#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/lusl7200#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/neponset#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/pangolin#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/rpc#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/shark#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/sherman#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/victor#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/arch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/armksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/arthur.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/bios32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/calls.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/debug-armo.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/debug-armv.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dec21285.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-arc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-footbridge.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-rpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ecard.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/entry-armo.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/entry-armv.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/entry-common.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/fiq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ftv-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/head-armo.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/head-armv.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/leds-ebsa110.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/leds-ftvpci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/oldlatches.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/plx90x0.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/sys_arm.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/time-acorn.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/via82c505.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/backtrace.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/changebit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/clearbit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/copy_page.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumipv6.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumpartial.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumpartialcopy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumpartialcopyuser.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/delay.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/ecard.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/extractconstants.pl#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/findbit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/floppydma.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/getconsdata.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-acorn.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-pcio.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsb.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsl.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsw-armv3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsw-armv4.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-shark.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesb.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesl.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesw-armv3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesw-armv4.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memzero.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/setbit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strncpy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strnlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strrchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/testchangebit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/testclearbit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/testsetbit.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/uaccess-armo.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/lib/uaccess.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/arch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/cats-hw.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/cats-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/ebsa285-leds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/ebsa285-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/netwinder-hw.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/netwinder-leds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/netwinder-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/personal-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/arch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/hw.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/leds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/arch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/mm.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/consistent.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/fault-armo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/fault-armv.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/fault-common.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/ioremap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-armo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-armv.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-clps7500.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-ebsa110.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-footbridge.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-l7200.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-nexuspci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-rpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-sa1100.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-tbox.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm2,3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm6,7.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm720.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm920.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-sa110.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/mm/small_page.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/ARM-gcc.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/config.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/double_cpdo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/entry26.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/extended_cpdo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11.inl#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11_cpdo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11_cpdt.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11_cprt.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpmodule.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpmodule.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpmodule.inl#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpopcode.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpopcode.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpsr.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/milieu.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/single_cpdo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat-macros#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat-specialize#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/tools/gen-mach-types#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/tools/mach-types#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/vmlinux-armo.lds.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/arm/vmlinux-armv.lds.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/bootsect.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/compressed/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/compressed/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/compressed/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/install.sh#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/setup.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/tools/build.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/boot/video.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/apic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/apm.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/bluesmoke.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/cpuid.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/dmi_scan.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/i386_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/i387.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/i8259.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/io_apic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/ioport.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/ldt.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/mca.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/microcode.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/mpparse.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/msr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/mtrr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-i386.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-i386.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-pc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-visws.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/smpboot.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/sys_i386.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/trampoline.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/visws_apic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/vm86.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/checksum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/dec_and_lock.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/delay.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/getuser.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/iodebug.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/memcpy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/mmx.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/old-checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/putuser.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/lib/usercopy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/README#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/control_w.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/div_Xsig.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/div_small.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/errors.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/exception.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_arith.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_asm.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_aux.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_emu.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_entry.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_etc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_proto.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_system.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_tags.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_trig.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/get_address.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/load_store.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/mul_Xsig.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_2xm1.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_atan.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_l2.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_sin.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_tan.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/polynom_Xsig.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_add_sub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_compare.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_constant.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_constant.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_convert.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_divide.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_ld_str.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_mul.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_norm.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_round.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_add.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_div.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_mul.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_sub.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/round_Xsig.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/shr_Xsig.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/status_w.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/version.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/wm_shrx.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/wm_sqrt.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/mm/ioremap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/i386/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/boot/bootloader.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/boot/bootloader.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/dig/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/dig/machvec.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/dig/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_machvec.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_ssc.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/binfmt_elf32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_support.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/sys_ia32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/acpi.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/brl_emu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/efi.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/efi_stub.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/entry.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/fw-emu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/gate.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/ia64_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/iosapic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/irq_ia64.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/irq_sapic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/ivt.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/machvec.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/mca.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/mca_asm.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/minstate.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/pal.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/palinfo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/perfmon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/sal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/smpboot.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/sys_ia64.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unaligned.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unwind.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unwind_decoder.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unwind_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/clear_page.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/clear_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/copy_page.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/copy_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/csum_partial_copy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/do_csum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/flush.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/idiv32.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/idiv64.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strlen.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strncpy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strnlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/swiotlb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/tlb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/README#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fpmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fpmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fprom.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fpromasm.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fw-emu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/runsim#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/alenlist.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/cdl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/devsupport.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/eeprom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hcl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hcl_util.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hubdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hubspc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/invent.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ip37.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/klconflib.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/klgraph.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/klgraph_hack.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/l1.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/l1_command.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/labelcl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/mem_refcnt.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ml_SN_init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ml_SN_intr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ml_iograph.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/module.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pci_bus_cvlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pci_dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pcibr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pciio.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/sgi_if.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/sgi_io_init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/sgi_io_sim.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/stubs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/xbow.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/xswitch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/xtalk.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/discontig.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/iomv.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/llsc4.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/llsc4.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/machvec.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/mm.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/sn1_asm.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/synergy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/tools/make_textsym#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/tools/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/tools/print_offsets.awk#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/tools/print_offsets.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ia64/vmlinux.lds.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/amiga_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/amiints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/amisound.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/chipram.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/cia.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/pcmcia.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/dn_debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/dn_ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/ataints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atakeyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atari_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atasound.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atasound.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/hades-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/joystick.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/stdma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/stram.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/bvmeints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/README#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/bindec.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/binstr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/bugfix.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/decbin.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/do_func.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/fpsp.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/gen_except.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/get_op.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/kernel_ex.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/res_func.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/round.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sacos.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sasin.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/satan.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/satanh.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/scale.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/scosh.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/setox.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sgetem.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sint.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/skeleton.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/slog2.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/slogn.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/smovecr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/srem_mod.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/ssin.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/ssinh.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/stan.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/stanh.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sto_res.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/stwotox.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/tbldo.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/util.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_bsun.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_fline.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_operr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_ovfl.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_snan.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_store.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_unfl.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_unimp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_unsupp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/README.hp300#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/hil.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/hp300map.map#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/ints.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/reboot.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/CHANGES#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/MISC#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/README#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/TEST.DOC#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fplsp.doc#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fplsp.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fpsp.doc#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fpsp.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fskeleton.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/ftest.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/ilsp.doc#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/ilsp.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/iskeleton.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/isp.doc#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/isp.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/itest.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/os.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/pfpsp.sa#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/README-SRC#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/fplsp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/fpsp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/ftest.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/ilsp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/isp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/itest.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/pfpsp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/bios32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/m68k_defs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/m68k_defs.head#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/m68k_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/sun3-head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/sys_m68k.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/ashldi3.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/ashrdi3.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/lshrdi3.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/memcmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/memcpy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/memset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/muldi3.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/semaphore.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/baboon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/bootparse.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/iop.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/mac_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/mac_penguin.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/macboing.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/macints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/oss.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/psc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/via.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_arith.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_arith.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_cond.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_decode.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_emu.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_log.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_move.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_movem.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_scan.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_trig.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_trig.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_util.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/multi_arith.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/hwtest.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/kmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/motorola.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/sun3mmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme147/147ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme147/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme147/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/16xints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/mvme16x_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/README#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/q40ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/dvma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/idprom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/intersil.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/leds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/mmu_emu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/printf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/sbus.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/sun3_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/sun3ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/dvma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/sbus.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/tools/amiga/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/tools/amiga/dmesg.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/vmlinux-sun3.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/m68k/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/.gdbinit#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/algor/README#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/cmdline.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/env.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/identify.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/printf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/salone.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/arc/tree.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/baget.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/bagetIRQ.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/balo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/balo_supp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/ld.script.balo#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/print.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/prom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/prom/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/vacserial.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/baget/wbflush.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/boot/addinitrd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/boot/ecoff.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/boot/elf2ecoff.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/boot/mkboot.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/cobaltscc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/diagdefs.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/hw-access.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/int-handler.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/via.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/z8530.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/int-handler.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/nile4.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/pci-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/prom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/boot/decstation.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/boot/ld.ecoff#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/int-handler.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/cmdline.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/dectypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/identify.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/locore.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/prom.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/promcon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/rtc-dec.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/serial.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/dec/wbflush.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-cobalt#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-decstation#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-ip22#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-orion#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-rm200#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/floppy-jazz.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/int-handler.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/jazzdma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/kbd-jazz.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/rtc-jazz.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/branch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/fpe.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/gdb-low.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/gdb-stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/ioport.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/ipc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irix5sys.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixelf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixinv.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixsig.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/mips_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r2300_fpu.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r2300_misc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r2300_switch.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r4k_fpu.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r4k_misc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r4k_switch.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r6000_fpu.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/scall_o32.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/softfp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/syscall.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/syscalls.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/sysirix.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/sysmips.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/unaligned.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/vm86.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ld.script.big#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/ld.script.little#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/csum_partial.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/csum_partial_copy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/dump_tlb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/floppy-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/floppy-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/ide-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/ide-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/kbd-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/kbd-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/r3k_dump_tlb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/rtc-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/rtc-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/strncpy_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/strnlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/tinycon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/lib/watch.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/andes.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/loadmmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/r2300.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/r4xx0.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/mm/umap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/int-handler.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/ld.script.orion#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/no_initrd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/piggyback.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/promcon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/orion/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indyIRQ.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_hpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_int.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_mc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_sc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/promcon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/system.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/int-handler.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/pcimt_scache.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/sni/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/tools/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips/tools/offset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/cmdline.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/env.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/identify.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/printf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/salone.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/tree.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/defconfig-ip22#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/defconfig-ip27#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/binfmt_elf32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/branch.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/ioctl32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/linux32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/mips64_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_cache.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_fpu.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_genex.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_switch.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_tlb.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_tlb_debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_tlb_glue.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/scall_64.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/scall_o32.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/signal32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/softfp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/syscall.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/unaligned.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/ld.script.elf32.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/ld.script.elf64#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/csum_partial.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/csum_partial_copy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/dump_tlb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/floppy-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/floppy-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/ide-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/ide-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/kbd-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/kbd-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/rtc-no.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/rtc-std.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/strncpy_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/strnlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/watch.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/andes.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/loadmmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/r4xx0.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/umap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-berr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-hpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-int.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-irq.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-mc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-sc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/system.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/TODO#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-berr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-irq-glue.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-klconfig.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-klnuma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-nmi.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-pci-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-reset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/tools/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/mips64/tools/offset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/entry_hpux.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/fs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/gate.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/sys_hpux.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/wrappers.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/cache.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/ccio-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/ccio-rm-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/drivers.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/hardware.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/hpmc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/inventory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/iosapic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/iosapic_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/keyboard.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/lasimap.map#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/lba_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/led.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pa7300lc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/parisc_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pci-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pdc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pdc_cons.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/real1.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/real2.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/sba_iommu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/sys_parisc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/syscall.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/bitops.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/lusercopy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/kmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/pa11.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/pa20.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/tools/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/tools/offset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/parisc/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/commproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/enet.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/fcc_enet.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/uart.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/commproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/commproc.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/enet.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/fec.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/uart.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/amiga_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/amiints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/amisound.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/bootinfo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/chipram.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/cia.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/ints.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/pcmcia.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/iso_font.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/kbd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/mkprep.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/ns16550.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/ns16550.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/of1275.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/of1275.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/offset#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/size#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/vreset.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/addnote.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/crt0.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/misc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/mknote.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/no_initrd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/piggyback.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/start.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/chrpmain.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/coffcrt0.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/coffmain.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/crt0.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/dummy.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/hack-coff.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/ld.script#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/misc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/mknote.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/no_initrd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/nonstdio.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/piggyback.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/rs6000.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/start.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/string.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/zlib.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/zlib.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/apus_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/bseip_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/common_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/est8260_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/gemini_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/mbx_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/oak_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/rpxcllf_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/rpxlite_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/walnut_defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/align.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/apus_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/bitops.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/checks.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/chrp_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/chrp_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/chrp_time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/feature.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/find_name.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/galaxy_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/gemini_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/gemini_prom.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/gemini_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/hashtable.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/head_4xx.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/head_8xx.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/i8259.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/i8259.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/idle.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/indirect_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/local_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/m8260_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/m8xx_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/misc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/mk_defs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/mol.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/oak_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/oak_setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/open_pic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/open_pic.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pci-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_backlight.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_nvram.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_pic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_pic.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc-stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc4xx_pic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc4xx_pic.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8260_pic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8260_pic.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8xx_pic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8xx_pic.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_asm.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_asm.tmpl#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_defs.head#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_htab.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_nvram.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/qspan_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/residual.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/sleep.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/softemu8xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/syscalls.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/walnut_setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/walnut_setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/xics.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/xics.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/checksum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/locks.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/strcase.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/string.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/double.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fabs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fadd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fadds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fcmpo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fcmpu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fctiw.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fctiwz.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fdiv.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fdivs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmadd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmadds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmsub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmsubs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmul.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmuls.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnabs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fneg.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmadd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmadds.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmsub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmsubs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fres.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/frsp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/frsqrte.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsel.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsqrt.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsqrts.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsubs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/lfd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/lfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/math.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mcrfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mffs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsb0.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsb1.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsfi.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-1.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-2.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-4.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-common.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/sfp-machine.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/single.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/soft-fp.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/stfd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/stfiwx.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/stfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/types.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/udivmodti4.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/embed_config.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/gzimage.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/head_8260.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/iic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/m8260_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/m8xx_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/offset#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/qspan_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/rdimage.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/size#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/4xx_tlb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/4xx_tlb.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/mem_pieces.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/mem_pieces.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/crt0.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/elf.pl#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/irSect.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/irSect.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/ld.script#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/misc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/mkevimg#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/mkirimg#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/adb.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ansidecl.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/nonstdio.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ppc-dis.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ppc-opc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ppc.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/privinst.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/setjmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/start.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/start_8xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/subr_prf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/xmon.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/boot/ipldump.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/boot/ipleckd.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/boot/iplfba.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/bitmap.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/cpcmd.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/cpcmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/ebcdic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/floatlib.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/gdb-stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/ieee.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/irqextras390.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/lowcore.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/mathemu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/reipl.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390dyn.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390fpu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390mach.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/sys_s390.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/lib/checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/lib/delay.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/lib/strcmp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/lib/strncpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/mm/ioremap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/dasdfmt/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/dasdfmt/dasdfmt.8#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/dasdfmt/dasdfmt.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/cfg.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/cfg.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/silo.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/silo.conf#1 branch +... //depot/linux-aic79xx-2.4.0/arch/s390/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/install.sh#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/cf-enabler.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/fpu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_hd64461.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_se.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_unknown.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/irq_imask.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/irq_ipr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/led_se.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/mach_hp600.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/mach_se.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/mach_unknown.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/pci-sh.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_cqreek.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_hd64461.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_od.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_se.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/sh_bios.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/sh_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/sys_sh.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/checksum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/delay.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memchr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memmove.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/old-checksum.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/lib/strcasecmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/mm/cache.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/mm/ioremap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sh/vmlinux.lds.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/boot/btfixupprep.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/boot/piggyback.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/auxio.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/check_asm.sh#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/cpu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/devices.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/ebus.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/errtbls.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/etrap.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/idprom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/ioport.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/muldiv.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/pcic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/rtrap.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sclow.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sparc-stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sparc_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4c_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4d_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4d_smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4m_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4m_smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sunos_asm.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sunos_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sys_solaris.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sys_sparc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sys_sunos.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/systbls.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/tadpole.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/tick14.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/trampoline.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/unaligned.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/windows.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/wof.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/wuf.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/COPYING.LIB#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/ashldi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/ashrdi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/atomic.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/bitops.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/blockops.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/checksum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/copy_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/debuglocks.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/divdi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/locks.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/lshrdi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memcmp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memscan.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/mul.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/muldi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/rem.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/rwsem.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/sdiv.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strlen.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strncmp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strncpy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/udiv.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/udivdi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/umul.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/urem.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/ashldi3.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/math.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/sfp-util.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/btfixup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/hypersparc.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/io-unit.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/iommu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/loadmmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/nosrmmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/nosun4c.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/srmmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/sun4c.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/swift.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/tsunami.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/viking.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/bootstr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/devmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/devops.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/mp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/palloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/printf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/ranges.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/segment.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/sun4prom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/tree.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/boot/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/boot/piggyback.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/config.in#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/defconfig#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/auxio.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/binfmt_aout32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/binfmt_elf32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/central.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/check_asm.sh#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/cpu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/devices.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/dtlb_backend.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/dtlb_base.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/dtlb_prot.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ebus.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/entry.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/etrap.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/head.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/idprom.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/init_task.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ioctl32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/iommu_common.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/iommu_common.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/itlb_base.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_common.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_impl.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_iommu.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_psycho.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_sabre.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/power.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/process.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/rtrap.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sbus.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/semaphore.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/signal32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/smp.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sparc64_ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/starfire.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sunos_ioctl32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys32.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys_sparc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys_sparc32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys_sunos32.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/systbls.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/trampoline.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/traps.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ttable.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/unaligned.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/winfixup.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/PeeCeeI.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3copy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3copy_in_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3copy_to_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3memcpy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIS.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VISbzero.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScopy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScsum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScsumcopy.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScsumcopyusr.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VISmemset.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VISsave.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/atomic.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/bitops.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/blockops.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/checksum.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/debuglocks.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/dec_and_lock.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/memcmp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/memscan.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/rwlock.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strlen.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strlen_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strncmp.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strncpy_from_user.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/math-emu/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/math-emu/math.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/math-emu/sfp-util.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/extable.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/fault.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/modutil.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/ultra.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/bootstr.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/devops.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/map.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/p1275.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/printf.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/tree.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/conv.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/entry64.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/fs.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/ipc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/socket.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/socksys.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/socksys.h#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/systbl.S#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/timod.c#1 branch +... //depot/linux-aic79xx-2.4.0/arch/sparc64/vmlinux.lds#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/README#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/fd1772.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/fd1772dma.S#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/mfm.S#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/mfmhd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/defkeymap-acorn.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/i2c.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/keyb_arc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/keyb_ps2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/mouse_rpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/pcf8583.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/pcf8583.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/serial-atomwide.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/serial-card.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/serial-dualsp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether3.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/etherh.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/acornscsi-io.S#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/acornscsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/acornscsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/arxescsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/arxescsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/ecoscsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/ecoscsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/eesox.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/eesox.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/fas216.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/fas216.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/msgqueue.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/msgqueue.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/oak.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/oak.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/powertec.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/powertec.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/queue.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/queue.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/cmbatt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmalloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmclib.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmcopy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmdebug.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmdelete.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmeval.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmglobal.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cminit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmobject.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/cpu.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsfield.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsmethod.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsmthdat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsobject.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsopcode.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswexec.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswload.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswscope.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswstate.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/driver.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/driver.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/ec.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/ec.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evevent.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evmisc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evregion.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evrgnini.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evsci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evxfevnt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evxfregn.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwacpi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwcpu32.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwgpe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwregs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/accommon.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acconfig.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acdebug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acdispat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acenv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acevents.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acexcep.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acgcc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acglobal.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/achware.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acinterp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/aclinux.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/aclocal.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acmacros.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acnamesp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acobject.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acoutput.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acparser.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acpi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acpiosxf.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acpixf.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acresrc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actables.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl71.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/amlcode.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amconfig.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amcreate.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amdyadic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amfield.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amfldio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/ammisc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/ammonad.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amnames.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amprep.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amregion.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amresnte.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amresolv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amresop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amstore.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amstoren.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amstorob.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amsystem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsaccess.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsalloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nseval.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsinit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsload.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsnames.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsobject.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nssearch.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nswalk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsxfname.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsxfobj.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/os.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psargs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psopcode.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psparse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psscope.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/pstree.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/pswalk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/power.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsaddr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rscalc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rscreate.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsdump.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsirq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rslist.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsmemory.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsmisc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/sys.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/table.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbconvrt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbget.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbinstal.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbutils.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbxface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbxfroot.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/ambassador.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/ambassador.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/atmdev_init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/atmsar11.data#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/atmsar11.regions#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/atmsar11.start#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/atmtcp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/eni.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/eni.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/firestream.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/firestream.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e_firmware_copyright#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e_mkfirm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/horizon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/horizon.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/idt77105.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/idt77105.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/iphase.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/iphase.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/midway.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstar.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstar.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstarmac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstarmac.copyright#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstarmac.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/pca200e.data#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/pca200e_ecd.data#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/sba200e_ecd.data#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/suni.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/suni.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/tonga.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/uPD98401.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/uPD98402.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/uPD98402.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/zatm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/zatm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/atm/zeprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/DAC960.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/DAC960.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/acsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/acsi_slm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/amiflop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/ataflop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/blkpg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/cciss.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/cciss.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/cciss_cmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/cpqarray.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/cpqarray.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/elevator.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/floppy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/genhd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/ida_cmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/ida_ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/ll_rw_blk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/loop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/nbd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/aten.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/bpck.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/comm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/dstr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/epat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/epia.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/fit2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/fit3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/friq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/frpw.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/jumbo#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/kbic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/ktti.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/mkd#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/on20.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/on26.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/paride.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/paride.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pcd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pseudo.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/paride/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/ps2esdi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/rd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/smart1,2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/swim3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/swim_iop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/xd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/xd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/block/z2ram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/aztcd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/aztcd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cdrom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cdu31a.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cdu31a.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cm206.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cm206.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/gscd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/gscd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/isp16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/isp16.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcdx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcdx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/optcd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/optcd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd4.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sjcd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sjcd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sonycd535.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sonycd535.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/README.computone#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/README.cycladesZ#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/README.cyclomY#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/README.epca#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/README.scc#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/acquirewdt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/adbmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/agp/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/agp/agp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/agp/agpgart_be.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/agp/agpgart_fe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/amigamouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/amikeyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/amiserial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/applicom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/applicom.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/atarimouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/atixlmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/busmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/busmouse.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/cd1865.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/conmakehash.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/console.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/console_macros.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/consolemap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/cp437.uni#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/cyclades.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/defkeymap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/defkeymap.map#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/digi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/digi1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/digiFep1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/digiPCI.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/digi_bios.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/digi_fep.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/dn_keyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/README.drm#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/agpsupport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/auth.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/bufs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/context.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ctxbitmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/drawable.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/drm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/drmP.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ffb_context.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ffb_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ffb_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/fops.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/gamma_dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/gamma_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/gamma_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_bufs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_context.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_drm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/lists.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/lock.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_bufs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_context.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_drm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_state.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_bufs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_cce.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_context.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_drm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_state.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/tdfx_context.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/tdfx_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/tdfx_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/drm/vm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ds1620.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/dsp56k.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/dtlk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/dz.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/dz.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/efirtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/epca.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/epca.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/epcaconfig.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/fep.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/README.PCI#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/RELEASE-NOTES#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/lzrw3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/lzrw3.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/zftape-compress.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/zftape-compress.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fc-10.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fc-10.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-io.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-io.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-isr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-isr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-bsm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-bsm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-buffer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-buffer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-calibr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-calibr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ecc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ecc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-format.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-format.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-init.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-io.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-io.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-proc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-read.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-read.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-rw.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-rw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-tracing.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-tracing.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-write.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-write.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape_syms.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-buffers.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-buffers.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-ctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-ctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-eof.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-eof.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-init.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-read.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-read.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-rw.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-rw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-vtbl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-vtbl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-write.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-write.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape_syms.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/generic_serial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/h8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/h8.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/hp600_keyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/i810-tco.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/i810-tco.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/i810_rng.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/fip_firm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2cmd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2cmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2ellis.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2ellis.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2lib.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2lib.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2os.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2pack.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2mkdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2stat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2trace.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2trace.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2types.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ip2main.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/isicom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/istallion.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/a3d.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/adi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/amijoy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/analog.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/cobra.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/db9.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/gamecon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/gameport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/gf2k.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/grip.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/iforce.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/interact.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/lightning.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/magellan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/ns558.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/pcigame.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/serio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/serport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/sidewinder.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/spaceball.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/spaceorb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/tmdc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/turbografx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/warrior.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/keyboard.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/logibusmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/lp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/mem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/mixcomwd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/moxa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/msbusmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/mxser.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/n_hdlc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/n_r3964.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/n_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/nvram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/nwbutton.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/nwbutton.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/nwflash.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pc110pad.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pc110pad.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pc_keyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/serial_cb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/serial_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcwd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcxx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pcxx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/ppdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/pty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/q40_keyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/qpmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/random.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/raw.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/board.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/bootpkt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/brates.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cdproto.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/chan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cirrus.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cmdblk.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cmdpkt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/control.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/daemon.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/data.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/defaults.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/eisa.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/enable.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/error.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/errors.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/formpkt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/func.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/host.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/hosthw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/link.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/linux_compat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/list.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/lrt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/ltt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/lttwake.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/map.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/mca.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/mesg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/parmmap.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/phb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/pkt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/port.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/proto.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/protsts.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/qbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rio_linux.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rio_linux.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioboot.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riocmd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioctrl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riodrvr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioinit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riointr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riolocks.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioparam.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riopcicopy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioroute.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riospace.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotable.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotime.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riowinif.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riscos.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rom.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/route.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rtahw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rup.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rupstat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/sam.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/selftest.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/space.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/sysmap.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/timeouts.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/top.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/typdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rio/unixrup.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/riscom8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/riscom8.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/riscom8_reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rocket.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rocket_int.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rsf16fmi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sbc60xxwdt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/scan_keyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/scan_keyb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/scc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/selection.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/serial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/serial167.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/serial_21285.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/serial_amba.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sh-sci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sh-sci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/softdog.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/specialix.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/specialix_io8.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/stallion.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sxboards.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sxwindow.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/synclink.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/sysrq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/toshiba.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/tpqic02.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/tty_io.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/tty_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/vc_screen.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/vino.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/vme_scc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/vt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/wd501p.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/wdt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/wdt285.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/wdt977.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/char/wdt_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/dio/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/dio/dio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc-al.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/fcp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/fcp_impl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/soc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/soc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/socal.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/fc4/socal.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-algo-bit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-algo-pcf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-elektor.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-elv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-pcf8584.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-philips-par.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-velleman.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/README#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/README.ioctl#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_block.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_config.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_lan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_lan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_scsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/aec62xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ali14xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/alim15x3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/amd7409.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/buddha.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd640.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd64x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/cs5530.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/cy82c693.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/dtc2278.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/falconide.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/gayle.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/hd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/hpt34x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/hpt366.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ht6560b.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/icside.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-cd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-cd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-disk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-features.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-floppy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-geometry.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-pmac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-pnp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-probe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-tape.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ide_modes.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/macide.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/ns87415.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/opti621.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/osb4.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/pdc202xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/pdc4030.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/pdc4030.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/piix.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/q40ide.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/qd6580.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/rapide.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/rz1000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/sis5513.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/sl82c105.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/slc90e66.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/trm290.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/umc8672.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ide/via82cxxx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/aic5800.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/aic5800.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/csr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/csr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/guid.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/guid.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/highlevel.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/highlevel.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/hosts.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/hosts.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_core.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_transactions.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_transactions.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ohci1394.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ohci1394.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/pcilynx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/pcilynx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/raw1394.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/raw1394.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/video1394.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/video1394.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/evdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/input.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/joydev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/keybdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/input/mousedev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/act2000.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/act2000_isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/act2000_isa.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/capi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/capi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/module.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/avm_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/avmcard.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1pcmcia.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/c4.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capicmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capidev.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capidrv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capidrv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capifs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capifs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capilli.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capiutil.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capiutil.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/kcapi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/t1isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/t1pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/divert_init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/divert_procfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/isdn_divert.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/isdn_divert.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/Divas_mod.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/adapter.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/bri.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/common.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/constant.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/divalog.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/divas.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/dsp_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/dspdids.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_dsp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_idi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_idi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_io.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_isa.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_mod.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/fcheck.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/fourbri.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/fpga.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/idi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/idi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/kprintf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/lincfg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/linchr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/linio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/linsys.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/log.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/md5sums.asc#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pc_maint.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pr_pc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pri.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/sys.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/uxio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/xlog.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/amd7930.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/arcofi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/arcofi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/asuscom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/avm_a1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/avm_a1p.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/avm_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/bkm_a4t.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/bkm_a8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/bkm_ax.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/callc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/cert.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/config.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/diva.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/elsa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/elsa_ser.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/fsm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/gazel.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bds0.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bds0.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bs0.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bs0.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_sx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_sx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfcscard.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hisax.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hscx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hscx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hscx_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/icc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/icc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/ipac.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isac.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isar.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isar.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl3.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isurf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/ix1_micro.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/jade.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/jade.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/jade_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3_1tr6.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3_1tr6.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3dss1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3dss1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3ni1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3ni1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/lmgr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/md5sums.asc#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/mic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/netjet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/netjet.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/niccy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/nj_s.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/nj_u.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/q931.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/rawhdlc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/rawhdlc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/s0box.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/saphir.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/sedlbauer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/sportster.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/tei.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/teleint.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/teles0.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/teles3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/telespci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/w6692.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/w6692.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/boardergo.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/boardergo.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hycapi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_boot.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_net.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_pof.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_procconf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_procfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_proclog.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_sched.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/ince1pc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/icn/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/icn/icn.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/icn/icn.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_audio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_bsdcomp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_cards.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_cards.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_common.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_common.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_concap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_concap.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_net.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_net.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ppp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_tty.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ttyfax.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ttyfax.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_v110.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_v110.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_x25iface.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_x25iface.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdnloop/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdnloop/isdnloop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdnloop/isdnloop.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/callbacks.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/callbacks.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/capi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/capi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/edss1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/edss1.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/layer2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/layer2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/module.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/pcbit.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/card.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/command.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/event.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/includes.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/interrupt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/message.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/message.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/packet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/scioc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/shmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/adb-iop.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/adb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/adbhid.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mac_hid.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mac_keyb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/macio-adb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mackeymap.map#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/macserial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/macserial.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mediabay.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/nvram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-cuda.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-macii.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-maciisi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-pmu.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-pmu68k.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/linear.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/lvm-snap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/lvm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/md.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/raid0.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/raid1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/raid5.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/md/xor.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-aimslab.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-aztech.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-cadet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-gemtek.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-maestro.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-miropcm20.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-rtrack2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-sf16fmi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-terratec.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-trust.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-typhoon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-zoltrix.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/audiochip.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bt848.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv-cards.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv-driver.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv-if.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttvp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/buz.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/buz.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bw-qcam.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/bw-qcam.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/c-qcam.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia_pp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia_usb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/cs8420.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/i2c-old.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/i2c-parport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/ibmmpeg2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/id.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/msp3400.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/planb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/planb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/pms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa5249.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7110.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7111.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7121.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7146.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7146reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7185.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7196.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/stradis.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tda7432.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tda9875.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tuner-3036.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tuner.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tuner.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tvaudio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tvaudio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/tvmixer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/videodev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/vino.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36057.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36060.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120_i2c.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120_mem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120_mem.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/misc/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/misc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/cfi_cmdset_0001.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/cfi_cmdset_0002.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/cfi_probe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/doc1000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/doc2000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/doc2001.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/docecc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/docprobe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/ftl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/jedec.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/map_ram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/map_rom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mapped.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mixmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdblock.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdchar.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdcore.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdpart.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/nftl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/nftlmount.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/nora.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/octagon-5066.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/physmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/pmc551.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/pnc2000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/rpxlite.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/slram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/mtd/vmax301.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c501.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c503.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c503.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c505.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c505.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c507.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c509.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c515.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c523.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c523.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c527.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c527.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/3c59x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/7990.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/7990.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/8139too.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/82596.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/8390.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/8390.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/LICENSE.SRC#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/Space.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/a2065.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/a2065.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ac3200.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/acenic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/acenic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/acenic_firmware.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_card.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_rid.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/am79c961a.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/am79c961a.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/apne.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops_ffdrv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops_ltdrv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ipddp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ipddp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ltpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ltpc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/arc-rawmode.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/arc-rimi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/arcnet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com20020-isa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com20020-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com20020.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com90io.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com90xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/rfc1051.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/rfc1201.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ariadne.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ariadne.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ariadne2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arlan-proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arlan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/arlan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/at1700.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/atari_bionet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/atari_pamsnet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/atarilance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/atp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/atp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/auto_irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/bagetlance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/bmac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/bmac.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/bonding.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/bsd_comp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/cs89x0.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/cs89x0.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/daynaport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/de4x5.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/de4x5.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/de600.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/de620.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/de620.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/declance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/defxx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/defxx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/depca.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/depca.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_asstruct.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_bcomm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_es4h.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_ether.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_firmware.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_i82596.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_plx9060.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dmfe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/dummy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/e2100.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/eepro.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/eepro100.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/eexpress.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/eexpress.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/epic100.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/eql.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/es3210.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/eth16i.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ethertap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ewrk3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ewrk3.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526_ip.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526_novram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526_scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/tach.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fc/tach_structs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/fmv18x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/gmac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/gmac.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamachi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/6pack.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_epp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_par.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_ser_fdx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_ser_hdx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/bpqether.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/dmascc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/hdlcdrv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/mkiss.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/mkiss.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/scc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/gentbl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk1200.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk2666.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_fsk9600.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_hapn4800.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_psk4800.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_sbc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_wss.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/smdma.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/yam.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/yam1200.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/yam9600.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/z8530.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hp-plus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hp100.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hp100.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hplance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hplance.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hydra.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/hydra.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/i82586.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ibmlana.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ibmlana.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ioc3-eth.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/actisys.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/esi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/girbil.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/irport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/irtty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/litelink.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/nsc-ircc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/old_belkin.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/smc-ircc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/tekram.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/toshoboe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/irda/w83977af_ir.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/isa-skeleton.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/jazzsonic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/lance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/lasi_82596.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/lne390.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/loopback.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/mac89x0.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/mace.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/mace.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/macmace.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/macsonic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/mvme147.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/myri_code.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/myri_sbus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/myri_sbus.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/natsemi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ncr885_debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ncr885e.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ncr885e.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ne.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ne2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ne2k-pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ne3210.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/net_init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ni5010.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ni5010.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ni52.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ni52.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ni65.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ni65.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/oaknet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/3c574_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/3c589_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/aironet4500_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/com20020_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/fmvj18x_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/i82593.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ibmtr_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/netwave_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/nmclan_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ositech.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/pcnet_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ray_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ray_cs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/rayctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/smc91c92_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/wavelan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/wavelan_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/wavelan_cs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/xirc2ps_cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/xircom_tulip_cb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pcnet32.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/plip.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_async.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_deflate.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_synctty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pppoe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/pppox.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ptifddi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ptifddi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/ptifddi_asm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rcif.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rclanmtl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rclanmtl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rcpci45.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rrunner.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rrunner.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/rtl8129.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sb1000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/seeq8005.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/seeq8005.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/setup.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sgiseeq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sgiseeq.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/shaper.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sis900.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sis900.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/lm80.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skaddr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skcsum.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skdebug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skdrv1st.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skdrv2nd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skerror.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgedrv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgehw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgehwt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgei2c.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgeinit.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgepnm2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgepnmi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgesirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/ski2c.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skqueue.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skrlmt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/sktimer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/sktypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skvpd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/xmac_ii.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skaddr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skcsum.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skge.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgehwt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgeinit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgepnmi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgesirq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/ski2c.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/sklm80.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skqueue.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skrlmt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/sktimer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skvpd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skxmac2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk_g16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk_g16.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk_mca.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sk_mca.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/can.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/cfm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/drvfbi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/ecm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/ess.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/fplustm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/cmtdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/fddi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/fddimib.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/fplustm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/hwmtm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/lnkstat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/mbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/osdef1st.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/sba.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/sba_def.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/skfbi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/skfbiinc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smt.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smt_p.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smtstate.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/supern_2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/targethw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/targetos.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/hwmtm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/hwt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/lnkstat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/pcmplc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/pmf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/queue.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/rmt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/skfddi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smtdef.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smtinit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smtparse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smttimer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/srf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/slhc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/slip.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/slip.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/smc-mca.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/smc-mca.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/smc-ultra.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/smc-ultra32.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/smc9194.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/smc9194.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sonic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sonic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/starfire.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/stnic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/strip.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sun3lance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunbmac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunbmac.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sundance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunhme.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunhme.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunlance.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunqe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/sunqe.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tlan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tlan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/abyss.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/abyss.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/ibmtr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/ibmtr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/lanstreamer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/lanstreamer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/madgemc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/madgemc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/olympic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/olympic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/smctr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/smctr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/smctr_firmware.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tms380tr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tms380tr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tms380tr_microcode.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tmspci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/21142.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/eeprom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/interrupt.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/media.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/pnic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/tulip.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/tulip_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/tun.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/via-rhine.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-hw-comx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-hw-locomx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-hw-mixcom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-proto-fr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-proto-lapb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-proto-ppp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comxhw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cosa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cosa.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cycx_drv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cycx_main.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cycx_x25.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/dlci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/hostess_sv11.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/hscx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lapbether.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_main.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_media.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_media.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_prot.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_proto.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_proto.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_proto_raw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_var.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_ver.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/mixcom.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sbni.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sbni.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_chdlc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_fr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_ppp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_x25.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdladrv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdlamain.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sealevel.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/syncppp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/syncppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/x25_asy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/x25_asy.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/z85230.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wan/z85230.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wavelan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wavelan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wavelan.p.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/wd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/winbond-840.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/yellowfin.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/zlib.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/zlib.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/net/znet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/nubus/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/nubus/nubus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/nubus/nubus_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/nubus/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/BUGS-parport#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/TODO-parport#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/daisy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/ieee1284.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/ieee1284_ops.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/multiface.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_amiga.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_arc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_atari.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_gsc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_mfc3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_pc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_sunbpp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/probe.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/procfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/parport/share.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/compat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/gen-devlist.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/names.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/pci.ids#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/quirks.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/setup-bus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/setup-irq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/setup-res.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pci/syscall.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/bulkmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cardbus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cb_enabler.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cirrus.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cistpl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cs_internal.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/ds.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/i82365.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/i82365.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/o2micro.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/old-yenta.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/pci_socket.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/pci_socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/ricoh.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/rsrc_mgr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/rsrc_mgr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/smc34c90.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/tcic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/tcic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/ti113x.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/topic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/vg468.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/yenta.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/yenta.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pnp/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pnp/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pnp/isapnp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pnp/isapnp_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/pnp/quirks.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_ccwstuff.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_ccwstuff.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_eckd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_erp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_erp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_mdsk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_profile.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/mdisk.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/block/mdisk.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/con3215.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_con.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_rw.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_rw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/misc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/misc/chandev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/net/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/net/ctc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/net/iucv.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/s390/net/iucv.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/amd7930.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/amd7930.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/cs4215.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/cs4231.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/cs4231.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dbri.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dbri.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dmy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dummy.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/aurora.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/aurora.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/bpp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/cd180.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/display7seg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/envctrl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/flash.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/jsflash.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/openprom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/pcikbd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/pcikbd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/rtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sab82532.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/su.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkbd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkbd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkbdmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkeymap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkeymap.map#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunmouse.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunserial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunserial.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/uctrl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc_i2c.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc_i2c.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/zs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/zs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/dvma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sbus/sbus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/3w-xxxx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/3w-xxxx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7,8xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7,8xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7,8xx.scr#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7xx.scr#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c8xx_d.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c8xx_u.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/AM53C974.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/AM53C974.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/BusLogic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/BusLogic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.ips#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.ncr53c8xx#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.serverraid#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.sym53c8xx#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/FlashPoint.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/LICENSE.FlashPoint#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR5380.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR5380.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53C9x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53C9x.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53c406a.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53c406a.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.AM53C974#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.BusLogic#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.FlashPoint#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.Mylex#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.aha152x#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.dtc3x80#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.g_NCR5380#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ibmmca#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.in2000#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ncr53c7xx#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ncr53c8xx#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.osst#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ppa#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.qlogicfas#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.qlogicisp#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.st#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.tmscsim#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/a2091.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/a2091.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/a3000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/a3000.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/advansys.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/advansys.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha152x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha152x.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1542.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1542.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1740.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1740.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7770.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7770_osm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.reg#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.seq#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_host.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_inline.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.reg#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.seq#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_host.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_inline.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_pci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/cam.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/queue.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/scsi_iu.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/scsi_message.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/README.aic7xxx#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx.reg#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx.seq#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx_reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx_seq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/scsi_message.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/sequencer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/amiga7xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/amiga7xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_NCR5380.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_dma_emul.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_scsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/atp870u.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/atp870u.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz1230.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz1230.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz2060.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz2060.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/bvme6000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/bvme6000.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/constants.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/constants.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfc.Readme#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTS.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSchip.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTScontrol.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSi2c.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSinit.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSstructs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTStrigger.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSworker.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstorm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstorm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstormII.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstormII.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dc390.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dec_esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dec_esp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dmx3191d.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dmx3191d.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dtc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/dtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma_proc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_generic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_pio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_pio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_pio_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/esp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fastlane.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fastlane.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fcal.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fcal.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fd_mcs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fd_mcs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fdomain.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/fdomain.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/g_NCR5380.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/g_NCR5380.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth_ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth_proc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gvp11.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/gvp11.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/hosts.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/hosts.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/i60uscsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/i60uscsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/i91uscsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/i91uscsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ibmmca.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ibmmca.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ide-scsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ide-scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/imm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/imm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/in2000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/in2000.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ini9100u.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ini9100u.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/inia100.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/inia100.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ips.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ips.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/jazz_esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/jazz_esp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac53c94.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac53c94.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_NCR5380.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_esp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_scsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mca_53c9x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mca_53c9x.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/megaraid.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/megaraid.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mesh.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mesh.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme147.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme147.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme16x.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme16x.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ncr53c8xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ncr53c8xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/oktagon_esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/oktagon_esp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/oktagon_io.S#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst_detect.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst_options.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pas16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pas16.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2000.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2220i.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2220i.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/aha152x_stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/fdomain_stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/qlogic_stub.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pluto.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/pluto.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ppa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ppa.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi240i.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi240i.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi_chip.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi_dale.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi_roy.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ql12160_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ql1280_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qla1280.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qla1280.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfas.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfas.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfc_asm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicisp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicisp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicisp_asm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicpti.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicpti.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicpti_asm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/script_asm.pl#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_error.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_lib.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_merge.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_module.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_obsolete.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_obsolete.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_queue.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_scan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsicam.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsiiom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/seagate.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/seagate.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sgiwd93.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sgiwd93.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710.scr#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710_d.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710_u.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr_vendor.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/st.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/st.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/st_options.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3_NCR5380.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3_scsi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3_scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3x_esp.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3x_esp.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c416.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c416.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx_comm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/t128.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/t128.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/tmscsim.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/tmscsim.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/u14-34f.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/u14-34f.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ultrastor.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/ultrastor.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd33c93.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd33c93.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd7000.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd7000.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/ds1286.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/gconsole.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/graphics.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/graphics.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/graphics_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/newport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/rrm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/sgicons.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/sgiserial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/sgiserial.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/shmiq.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/streamable.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/usema.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/usema.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/.indent.pro#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/.version#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/724hwmcode.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/CHANGELOG#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/COPYING#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/Hwmcode.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/README.FIRST#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ac97.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ac97.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ac97_codec.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/aci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1816.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1848.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1848.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1848_mixer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/adlib_card.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/aedsp16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/audio_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/awe_hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/awe_wave.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/awe_wave.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/bin2hex.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cmpci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/coproc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4232.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4232.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4281.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4281_hwdefs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs461x.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs461x_image.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/cs46xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dev_table.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dev_table.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmabuf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/awacs_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_atari.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_awacs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_paula.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_q40.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/8010.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/audio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmo.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmo.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwo.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwo.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/ecard.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/ecard.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/efxmgr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/emu_wrapper.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/emuadxmg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/hwaccess.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/hwaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/icardmid.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/icardwav.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/irqmgr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/irqmgr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/midi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/midi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/mixer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/recmgr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/recmgr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/timer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/voicemgr.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/voicemgr.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/es1370.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/es1371.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/esssolo1.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_card.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_linearvol.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_midi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_vol.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_wave.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/hex2hex.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/i810_audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ics2101.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/iwmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/mad16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/maestro.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/maestro.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/maestro_tables.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/maui.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_ctrl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_synth.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_synth.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/midibuf.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/miroaci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/mpu401.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/mpu401.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_classic.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_classic.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_pinnacle.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_pinnacle.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/nm256.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/nm256_audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/nm256_coeff.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3_hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3sa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3sa2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/os.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_card.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_midi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_mixer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_pcm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/pss.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_card.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_common.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_ess.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_ess.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_midi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_mixer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_mixer.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sequencer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sequencer_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sgalaxy.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/skeleton.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sonicvibes.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_calls.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_config.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_firmware.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_firmware.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/soundcard.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/soundvers.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sscape.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/sys_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/trident.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/trident.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/trix.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/tuning.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/uart401.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/uart6850.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ulaw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/v_midi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/v_midi.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/via82cxxx_audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/vidc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/vidc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/vidc_fill.S#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/vwsnd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/waveartist.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/waveartist.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/wavfront.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/wf_midi.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ymf_sb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ymfpci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ymfpci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/ymfpci_image.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/yss225.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/sound/yss225.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/tc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/tc/tc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/tc/tcsyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/tc/zs.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/tc/zs.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/telephony/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/telephony/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/telephony/ixj.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/telephony/ixj.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/telephony/phonedev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/acm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/audio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/audio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/bluetooth.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/dabfirmware.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/dabusb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/dabusb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/dc2xx.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/devices.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/devio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/drivers.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/dsbr100.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/hid-debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/hid.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/hid.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/hub.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/hub.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/ibmcam.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/ibmcam.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/mdc800.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/microtek.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/microtek.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/net1080.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/ov511.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/ov511.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/pegasus.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/pegasus.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/plusb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/printer.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/rio500.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/rio500_usb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/scanner.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/scanner.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/Makefile-keyspan_pda_fw#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/belkin_sa.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/belkin_sa.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/digi_acceleport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/empeg.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/ezusb_convert.pl#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/ftdi_sio.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/ftdi_sio.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_pda.S#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_pda.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_pda_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa18x_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa19_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa19w_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa26msg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa28_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa28msg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa28x_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa49msg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa49w_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/mct_u232.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/mct_u232.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/omninet.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/usb-serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/usbserial.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/visor.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/visor.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/whiteheat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/whiteheat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/whiteheat_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/dpcm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/dpcm.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/freecom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/freecom.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/initializers.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/initializers.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/protocol.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/protocol.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/scsiglue.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/scsiglue.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/sddr09.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/sddr09.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/shuttle_usbat.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/shuttle_usbat.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/transport.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/transport.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/usb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/usb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/uhci-debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/uhci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/uhci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-debug.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-ohci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-ohci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-uhci-debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-uhci.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-uhci.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usbkbd.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/usbmouse.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/uss720.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/usb/wacom.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/S3triofb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/acornfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/acornfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/amifb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/atafb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/aty.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/aty128.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/aty128fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/atyfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/bwtwofb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cgfourteenfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cgsixfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cgthreefb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/chipsfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/clgenfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/clgenfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/controlfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/controlfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/creatorfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cvisionppc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cyber2000fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cyber2000fb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cyberfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/cyberfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/dn_accel.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/dn_cfb4.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/dn_cfb8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/dnfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/dummycon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-afb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb24.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb32.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb4.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-hga.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-ilbm.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-iplan2p2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-iplan2p4.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-iplan2p8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-mac.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-mfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-sti.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-vga-planes.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-vga.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbgen.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fbmon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fm2fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_6x11.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_8x16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_8x8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_acorn_8x8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_pearl_8x8.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_sun12x22.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/font_sun8x16.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/fonts.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/g364fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/hgafb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/hitfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/hpfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/iga.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/igafb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/imsttfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/leofb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/macfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/macmodes.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/i2c-matroxfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_DAC1064.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_DAC1064.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_Ti3026.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_Ti3026.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_accel.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_accel.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_base.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_base.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_crtc2.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_crtc2.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_g450.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_g450.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_maven.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_maven.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_misc.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/mdacon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/modedb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/newport_con.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/offb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/p9100.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/p9100fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/platinumfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/platinumfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/pm2fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/pm2fb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/prom.uni#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/promcon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/q40fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/retz3fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/retz3fb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/fbdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/nv4ref.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/nvreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/riva_hw.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/riva_hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/riva/riva_tbl.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sa1100fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sbusfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sgivwfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sgivwfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/initdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_300.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_300.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_301.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_301.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_main.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/skeletonfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sti-bmode.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sti.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sticon-bmode.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sticon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sticore.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/stifb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/sun3fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/tcxfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/tdfxfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/tgafb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/tgafb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/valkyriefb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/valkyriefb.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/vesafb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/vfb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/vga16fb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/vgacon.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/video/virgefb.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/gen-devlist.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/names.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/zorro.c#1 branch +... //depot/linux-aic79xx-2.4.0/drivers/zorro/zorro.ids#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/fs/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/fs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/adfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_f.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_f.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_fplus.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_fplus.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/map.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/adfs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/Changes#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/amigaffs.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/bitmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/affs/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/attr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/autofs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/dirhash.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/root.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs/waitq.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/autofs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/expire.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/init.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/root.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/autofs4/waitq.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/bad_inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/bfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/bfs/bfs_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/bfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/bfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/bfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/binfmt_aout.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/binfmt_elf.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/binfmt_em86.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/binfmt_misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/binfmt_script.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/block_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/buffer.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/cache.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/cnode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/coda_linux.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/pioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/psdev.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/sysctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/coda/upcall.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/README#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/cramfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/adler32.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infblock.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infblock.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infcodes.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infcodes.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inffast.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inffast.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inffixed.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inflate.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inftrees.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inftrees.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infutil.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infutil.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/uncompr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/zconf.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/zlib.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/zutil.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/cramfs/uncompress.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/dcache.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devfs/base.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devfs/util.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devices.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devpts/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devpts/devpts_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devpts/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/devpts/root.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/dnotify.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/dquot.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/efs/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/exec.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/CHANGES#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/acl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/balloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/bitmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/fsync.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/ialloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ext2/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/buffer.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/cache.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/cvf.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/fatfs_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/msbuffer.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/tables.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fat/tables.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fcntl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/fifo.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/file_table.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/filesystems.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/COPYING#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/FAQ.txt#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/HFS.txt#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/INSTALL.txt#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/TODO#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/balloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/bdelete.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/bfind.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/bins_del.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/binsert.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/bitmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/bitops.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/bnode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/brec.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/btree.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/catalog.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/dir_cap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/dir_dbl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/dir_nat.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/extent.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/file_cap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/file_hdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/hfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/hfs_btree.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/mdb.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/part_tbl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/string.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/sysdep.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/trans.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hfs/version.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/alloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/anode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/buffer.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/dentry.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/dnode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/ea.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/hpfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/hpfs_fn.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/map.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/name.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/hpfs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/iobuf.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/joliet.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/rock.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/rock.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/isofs/util.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/jffs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/jffs/inode-v23.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/jffs/intrep.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/jffs/intrep.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/jffs/jffs_fm.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/jffs/jffs_fm.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/clntlock.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/clntproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/host.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/lockd_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/mon.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/svc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/svc4proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/svclock.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/svcproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/svcshare.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/svcsubs.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/xdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/lockd/xdr4.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/locks.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/bitmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/itree_common.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/itree_v1.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/itree_v2.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/minix/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/msdos/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/msdos/msdosfs_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/msdos/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/mmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncplib_kernel.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncplib_kernel.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncpsign_kernel.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncpsign_kernel.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/sock.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ncpfs/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/flushd.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/mount_clnt.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/nfs2xdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/nfs3proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/nfs3xdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/nfsroot.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/read.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/unlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfs/write.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/auth.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/export.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/lockd.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfs3proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfs3xdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfscache.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsfh.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfssvc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsxdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/stats.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nfsd/vfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_base.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_big5.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp437.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp737.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp775.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp850.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp852.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp855.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp857.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp860.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp861.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp862.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp863.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp864.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp865.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp866.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp869.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp874.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp932.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp936.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp949.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp950.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_euc-jp.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_euc-kr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_gb2312.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-1.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-14.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-15.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-2.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-3.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-4.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-5.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-6.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-7.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-8.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-9.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_koi8-r.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_sjis.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/nls/nls_utf8.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/noquot.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/attr.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/attr.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/dir.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/fs.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/inode.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/macros.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/ntfsendian.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/ntfstypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/struct.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/super.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/support.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/support.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/sysctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/sysctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/util.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ntfs/util.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/open.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/openpromfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/openpromfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/acorn.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/acorn.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/amiga.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/amiga.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/atari.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/atari.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/check.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/check.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/ibm.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/ibm.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/mac.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/mac.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/msdos.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/msdos.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/osf.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/osf.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/sgi.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/sgi.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/sun.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/sun.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/ultrix.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/partitions/ultrix.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/pipe.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/array.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/base.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/inode-alloc.txt#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/kcore.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/kmsg.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/proc_devtree.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/proc_misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/proc_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/procfs_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/proc/root.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/BUGS#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/README#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/TODO#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/bitmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/fsync.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/qnx4/truncate.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ramfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ramfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/read_write.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/readdir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/romfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/romfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/select.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/ChangeLog#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/cache.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/getopt.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/getopt.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/smb_debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/smbfs/sock.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/stat.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/CHANGES#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/INTRO#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/balloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/fsync.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/ialloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/sysv/truncate.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/balloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/crc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/directory.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/fsync.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/ialloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/lowlevel.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/partition.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/truncate.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/udf_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/udf_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/udfdecl.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/udfend.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/udftime.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/udf/unicode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/balloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/cylinder.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/file.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/ialloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/super.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/swab.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/symlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/truncate.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/util.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/ufs/util.h#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/README-WIP.txt#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/dir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/emd.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/inode.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/mangle.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/notes#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/rdir.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/umsdos/specs#1 branch +... //depot/linux-aic79xx-2.4.0/fs/vfat/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/fs/vfat/namei.c#1 branch +... //depot/linux-aic79xx-2.4.0/fs/vfat/vfatfs_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/asm_offsets.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/compiler.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/console.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_apecs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_cia.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_irongate.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_lca.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_mcpcia.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_polaris.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_t2.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_titan.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_tsunami.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_wildfire.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/fpu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/gentrap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hwrpb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/jensen.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/machvec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/md.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sfp-machine.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sysinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-alpha/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/oldlatches.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/acornfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/serial_l7200.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/acornfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/SA-1100.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/SA-1101.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/SA-1111.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/assabet.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/bitfield.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/bitsy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/cerf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/mmzone.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/serial_reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/thinclient.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/irqs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/assembler.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/cpu-multi26.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/cpu-multi32.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/cpu-single.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ecard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/fiq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/dec21285.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/ioc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/iomd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/memc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/pci_v3.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/serial_amba.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/leds.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/limits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/arch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/map.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/mmzone.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/nwflash.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/assembler.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/locks.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/assembler.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/domain.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/locks.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/uncompress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-fns.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/procinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/therm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/vt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-arm/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-generic/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-generic/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-generic/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-generic/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-generic/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/apic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/apicdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/boot.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/cobalt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/cpufeature.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/debugreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/desc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/e820.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/fixmap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/highmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/i387.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/io_apic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/kmap_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ldt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/lithium.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/locks.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/math_emu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mca_dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mmx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mpspec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/msr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/mtrr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgalloc-2level.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgalloc-3level.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgtable-2level.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgtable-3level.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/rwlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/string-486.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/vm86.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-i386/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/acpi-ext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/acpikcfg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/asmmacro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/break.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/efi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/fpswa.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/fpu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ia32.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/iosapic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_dig.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_hpsim.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_sn1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mca.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mca_asm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/offsets.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ptrace_offsets.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/rse.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/addrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/agent.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/alenlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/arc/hinv.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/arc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/arch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/cdl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/clksupport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/cmn_err.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/dmamap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/driver.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/eeprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/gda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hack.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hcl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hcl_util.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hubspc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hwcntrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/intr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/intr_public.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/invent.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/iobus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ioc3.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ioerror.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ioerror_handling.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/iograph.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/klconfig.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/kldir.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ksys/elsc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ksys/i2c.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ksys/l1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/labelcl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mem_refcnt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mmzone.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mmzone_default.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mmzone_sn1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/nic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/nodemask.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/nodepda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/bridge.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pci_bus_cvlink.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pci_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pcibr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pcibr_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pciio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pciio_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/prio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/router.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sgi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/slotnum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/addrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/arch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/bedrock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubdev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubio_next.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hublb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hublb_next.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubmd_next.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubni.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubni_next.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubpi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubpi_next.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubxb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubxb_next.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/ip27config.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/kldir.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/leds.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/promlog.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/router.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/slotnum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/sn1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/uart16550.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/war.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn_cpuid.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn_fru.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/synergy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/systeminfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/vector.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/war.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xbow.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xbow_info.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xswitch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xtalk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xtalk_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xtalkaddrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xwidget.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/unwind.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ia64/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/adb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/adb_iop.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/adb_mouse.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amigahw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amigaints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amigayle.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amipcmcia.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/apollodma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/apollohw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atafd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atafdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_SCCserial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_SLM.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_acsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_joystick.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_stdma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_stram.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atarihw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atariints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atarikb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/blinken.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bootinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bvme6000hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/cachectl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/contregs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/dsp56k.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/dvma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/entry.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/fbio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/fpu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/hwtest.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/idprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/intersil.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/kbio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_asc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_baboon.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_iop.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_mouse.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_oss.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_psc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_via.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/machdep.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/machines.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/machw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/macintosh.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/macints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/math-emu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/md.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/motorola_pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/motorola_pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/movs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mvme147hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mvme16xhw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/openprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/oplib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/page_offset.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/q40_keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/q40_master.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/q40ints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sbus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/shm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3-head.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3_pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3_pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3ints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3x.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/swim_iop.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/traps.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/virtconvert.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/vuid_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-m68k/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/addrspace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/arc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/asm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/asmmacro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/baget/baget.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/baget/vac.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/baget/vic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/bcache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/bootinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/branch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/cachectl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/cacheops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/cpu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ddb5074.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/interrupts.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/ioasic_addrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/ioasic_ints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn01.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn02.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn02xa.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn03.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/machtype.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/tc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/tcinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/tcmodule.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ds1286.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/fp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/fpregdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/gdb-stub.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/gfx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/inst.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/inventory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/isadep.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/jazz.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/jazzdma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/mipsprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/mipsregs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ng1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ng1hw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/nile4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/orion.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/paccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/prctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/r4kcache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/reboot.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/regdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/rrm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sfp-machine.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgihpc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgimc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgint23.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgialib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgiarcs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgidefs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/shmiq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sni.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/stackframe.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/sysmips.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/umap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/usioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/watch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/wbflush.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/addrspace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/arc/hinv.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/arc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/asm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/asmmacro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bcache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bootinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/branch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/cachectl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/cpu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ds1286.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/fpregdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/gfx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/inst.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/m48t35.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mipsregs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mmzone.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ng1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/paccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pci/bridge.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r10kcache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r10kcacheops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r4kcache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r4kcacheops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/regdef.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/riscos-syscall.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sfp-machine.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgihpc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgimc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgint23.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgialib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgiarcs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgidefs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/shmiq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/addrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/agent.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/arch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/gda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/intr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/intr_public.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/ioc3.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/klconfig.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/kldir.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/klkernvars.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/launch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/mapped_kernel.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/nmi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/addrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/arch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hub.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubmd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubni.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubpi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/ip27.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/sn0_fru.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/stackframe.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sysmips.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/usioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/watch.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/xtalk/xtalk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-mips64/xtalk/xwidget.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/asmregs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/assembly.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/bootdata.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/fixmap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/gsc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hardware.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hil.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/iosapic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/led.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/machdep.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/md.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/parport_gsc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pdc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pdcpat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/psw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/real.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/runway.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/som.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/traps.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-parisc/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/8xx_immap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigahw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigaints.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigappc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigayle.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amipcmcia.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/backlight.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/board.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bootinfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bootx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bseip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/cpm_8260.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/dbdma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/est8260.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/fads.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/feature.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/gemini.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/gemini_serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/gg2.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/heathrow.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/highmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hydra.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/immap_8260.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/keylargo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/kgdb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/kmap_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/m48t35.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/machdep.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mbx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/md.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mediabay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mk48t59.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mpc8260.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mpc8xx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/nvram.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/oak.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ohare.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pci-bridge.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pnp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/prep_nvram.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/prom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/raven.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/residual.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/rpxclassic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/rpxlite.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/tqm860.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/tqm8xxL.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/traps.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/uninorth.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/vc_ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/walnut.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-ppc/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/chandev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ebcdic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/gdb-stub.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/irqextras390.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/lowcore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/major.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/mathemu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/misc390.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/queue.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390-gdbregs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390-regs-common.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390dyn.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390mach.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/setup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/sigp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-s390/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/addrspace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/hd64461.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/hitachi_se.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/hw_irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_generic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_hd64461.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_od.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_se.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_unknown.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/machvec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/machvec_init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgalloc-2level.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgtable-2level.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/sh_bios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/smc37c93x.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/ucontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sh/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/asi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/asmmacro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/audioio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/auxio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bpp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bsderrno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/btfixup.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/clock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/contregs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/cprefix.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/cypress.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ebus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ecc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/eeprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/fbio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/head.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/highmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/idprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/io-unit.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/iommu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/jsflash.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kbio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kdebug.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kgdb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kmap_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/machines.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mbus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/memreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mostek.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mpmbox.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/msi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mxcc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/obio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/openprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/openpromio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/oplib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pbm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pcic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pconf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/perfctr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtsrmmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtsun4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtsun4c.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/psr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ross.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sbi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sbus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sfp-machine.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/smpprim.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/solerrno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sun4paddr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sun4prom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sunbpp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/svr4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/swift.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sysen.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/timer.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/traps.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/tsunami.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/turbosparc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ultra.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vac-ops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vaddrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vfc_ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/viking.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vuid_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/winmacro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/apb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/asi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/atomic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/audioio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/auxio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bpp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bsderrno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bugs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/byteorder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/current.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/display7seg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/div64.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/dma.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ebus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/envctrl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fbio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fhc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/floppy.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fpumacro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/hardirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/head.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/idprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/io.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ioctls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/iommu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ipcbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/kbio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/kdebug.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/lsu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mmu_context.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mostek.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/msgbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/namei.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ns87303.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/openprom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/openpromio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/oplib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pbm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pconf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/perfctr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pgalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pgtable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/processor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/psrcompat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pstate.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sab82532.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sbus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/scatterlist.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/semaphore-helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/semaphore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sembuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sfp-machine.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/shmbuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/shmparam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sigcontext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/siginfo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/smplock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/softirq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/solerrno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/spitfire.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/starfire.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/statfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sunbpp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/svr4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/system.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/termbits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/timer.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ttable.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/uaccess.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/uctx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/unaligned.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/upa.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/utrap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/vaddrs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/visasm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/vuid_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/802_11.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/a.out.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ac97_codec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/acct.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/acpi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/adb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/adb_mouse.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/adfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/adfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/adfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/affs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/affs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/affs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/affs_hardblocks.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/agp_backend.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/agpgart.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/amifd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/amifdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/amigaffs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/apm_bios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/arcdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atalk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atari_rootsec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm_eni.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm_idt77105.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm_nicstar.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm_suni.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm_tcp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atm_zatm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmapi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmarp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmclip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmdev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmioc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmlec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmmpc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmsap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/atmsvc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/auto_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/auto_fs4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/awe_voice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ax25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/b1lli.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/b1pcmcia.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/baycom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/bfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/bfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/bfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/binfmts.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/bitops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/blk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/blkdev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/blkpg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/bootmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/bpqether.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/brlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/big_endian.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/generic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/little_endian.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/pdp_endian.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/swab.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/swabb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/capability.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/capi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cciss_ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cd1400.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cdk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cdrom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/circ_buf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coda_cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coda_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coda_linux.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coda_proc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coda_psdev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/coff.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/com20020.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/compatmac.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/comstats.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/concap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/config.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/console.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/console_struct.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/consolemap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ctype.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cuda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cyclades.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cyclomx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cycx_cfm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cycx_drv.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/cycx_x25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dasd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dcache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/delay.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/devfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/devfs_fs_kernel.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/devpts_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dirent.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/divert.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dn.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dnotify.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/dtlk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/efs_dir.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/efs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/efs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/efs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/efs_vh.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/elevator.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/elf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/elfcore.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/errno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/errqueue.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/etherdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ethtool.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ext2_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ext2_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ext2_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fat_cvf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fcdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fcntl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fd1772.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fddidevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/file.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/filter.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/fs_struct.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ftape-header-segment.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ftape-vendors.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ftape.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/gameport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/generic_serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/genhd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ghash.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hayesesp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hdlcdrv.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hdreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hdsmart.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hfs_sysdep.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/highmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/highuid.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hippidevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hpfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hpfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hpfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/hysdn_if.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c-algo-bit.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c-algo-pcf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c-dev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c-elektor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c-id.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c-old.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2c.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2o-dev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/i2o.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ibmtr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/icmp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/icmpv6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ide.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_arcnet.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_arp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_bonding.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_bridge.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_cablemodem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_ec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_eql.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_ether.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_fc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_fddi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_frad.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_hippi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_ltalk.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_packet.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_plip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_ppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_pppox.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_pppvar.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_shaper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_slip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_strip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_tr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_tun.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/if_tunnel.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/igmp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/in.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/in6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/in_route.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/in_systm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/inet.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/inetdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/init.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/input.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/interrupt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/iobuf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ioport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ipc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ipsec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ipv6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ipv6_route.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ipx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/irda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/irq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/irq_cpustat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isapnp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isdn.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isdn_divertif.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isdn_lzscomp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isdn_ppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isdnif.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/isicom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/iso_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/iso_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/iso_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/istallion.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ixjuser.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/jffs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/joystick.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kbd_diacr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kbd_kern.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kbd_ll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kdev_t.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kernel.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kernel_stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kernelcapi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/keyboard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/kmod.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lapb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/limits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/linkage.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/linux_logo.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/list.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/bind.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/lockd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/nlm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/share.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/sm_inter.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/xdr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lockd/xdr4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/locks.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/logibusmouse.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/loop.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/lvm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/major.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/malloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/matroxfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mc146818rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mc6821.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mca.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/minix_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/minix_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/minix_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/miscdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mman.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mmzone.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/modsetver.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/module.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mount.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mpp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mroute.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/msdos_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/msdos_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/msdos_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/msg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/cfi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/compatmac.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/doc2000.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/flashchip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/ftl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/iflash.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/jedec.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/map.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/mapped.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/mtd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/nand.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/nand_ids.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/nftl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/partitions.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtd/pmc551.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/mtio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/n_r3964.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nbd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ncp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ncp_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ncp_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ncp_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ncp_mount.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ncp_no.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/net.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netbeui.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ddp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_decnet.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/compat_firewall.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_core.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_ftp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_protocol.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_tcp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_tuple.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_core.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_ftp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_helper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_protocol.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_rule.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_queue.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_tables.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipchains_core.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipfwadm_core.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_LOG.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_MARK.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_REJECT.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_TOS.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_limit.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_mac.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_mark.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_multiport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_owner.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_state.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_tos.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/listhelp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/lockhelp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6_tables.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_LOG.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_MARK.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_REJECT.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_limit.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_mac.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_mark.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_multiport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_owner.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_x25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netlink.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/netrom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs2.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs3.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_flushd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_mount.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_page.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfs_xdr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/auth.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/cache.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/const.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/export.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/interface.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/nfsd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/nfsfh.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/stats.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/syscall.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/xdr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/xdr3.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nfsiod.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/notifier.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ntfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ntfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ntfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nubus.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/nvram.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/openpic.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/openprom_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pagemap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/parport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/parport_pc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pc_keyb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pci_ids.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/personality.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/phonedev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pipe_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pkt_cls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pkt_sched.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/pmu.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/poll.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/posix_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ppdev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ppp-comp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ppp_channel.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ppp_defs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/prctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/proc_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/proc_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ps2esdi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ptrace.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/qic117.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/qnx4_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/qnx4_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/qnx4_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/qnxtypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/quota.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/quotaops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/linear.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/md.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_compatible.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_k.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_p.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_u.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/raid0.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/raid1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/raid5.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raid/xor.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/random.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/raw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/reboot.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/resource.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/rocket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/romfs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/romfs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/romfs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/rose.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/route.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/rpcsock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/rtc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/rtnetlink.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sc26198.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/scc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sched.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdla.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdla_chdlc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdla_fr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdla_ppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdla_x25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdladrv.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdlapci.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sdlasfm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/securebits.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/selection.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/serial.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/serial167.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/serialP.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/serial_reg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/serio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/shm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/shmem_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/signal.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sisfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/skbuff.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/slab.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smb_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smb_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smb_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smb_mount.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smbno.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/smp_lock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/socket.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sockios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sonet.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sound.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/soundcard.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/soundmodem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/spinlock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/stallion.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/stat.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/stddef.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/string.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/auth.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/clnt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/debug.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/msg_prot.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/sched.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/stats.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/svc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/svcauth.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/svcsock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/xdr.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/xprt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/swap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/swapctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/synclink.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sys.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sysctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sysrq.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sysv_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sysv_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/sysv_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tcp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/telephony.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/termios.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/threads.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/time.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/timer.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/times.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/timex.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/toshiba.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tpqic02.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tqueue.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/trdevice.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tty.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tty_driver.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tty_flip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/tty_ldisc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/udf_167.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/udf_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/udf_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/udf_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/udf_udf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/udp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ufs_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ufs_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ufs_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/uio.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/ultrasound.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/umsdos_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/umsdos_fs.p#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/umsdos_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/un.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/unistd.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/usb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/usbdev_fs_i.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/usbdev_fs_sb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/usbdevice_fs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/user.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/utime.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/uts.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/utsname.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/vfs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/video_decoder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/video_encoder.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/videodev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/videotext.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/vmalloc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/vt.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/vt_buffer.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/vt_kern.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/wait.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/wanpipe.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/wanrouter.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/watchdog.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/wavefront.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/wireless.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/wrapper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/x25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/yam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/zftape.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/zorro.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/linux/zorro_ids.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/double.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/extended.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/op-1.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/op-2.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/op-4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/op-8.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/op-common.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/quad.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/single.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/math-emu/soft-fp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/addrconf.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/af_unix.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/arp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/atmclip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ax25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/checksum.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/datalink.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dn.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dn_dev.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dn_fib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dn_neigh.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dn_nsp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dn_route.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dsfield.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/dst.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/flow.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/icmp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/if_inet6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/inet_common.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/inet_ecn.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/inetpeer.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ip6_fib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ip6_fw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ip6_route.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ip_fib.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ipconfig.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ipip.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ipv6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ipx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/crc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/discovery.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_core.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_lmp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_param.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_ttp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_tty.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_tty_attach.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irda.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irda_device.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irdacall.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/iriap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/iriap_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irias_object.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_client.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_common.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_eth.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_filter.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_provider.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap_comp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap_frame.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlmp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlmp_event.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irlmp_frame.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irmod.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irqueue.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irttp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/irtty.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/nsc-ircc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/parameters.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/qos.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/smc-ircc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/timer.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/toshoboe.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/w83977af.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/w83977af_ir.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/irda/wrapper.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/lapb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/llc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/llc_frame.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/llc_name.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/llc_state.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/ndisc.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/neighbour.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/netrom.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/p8022.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/pkt_cls.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/pkt_sched.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/profile.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/protocol.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/psnap.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/raw.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/rawv6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/rose.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/route.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/scm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/slhc_vj.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/snmp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/sock.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/spx.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/tcp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/tcp_ecn.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/transp_v6.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/udp.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/net/x25.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/bulkmem.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/bus_ops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/ciscode.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/cisreg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/cistpl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/cs.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/cs_types.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/driver_ops.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/ds.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/ftl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/mem_op.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/memory.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/ss.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/pcmcia/version.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/scsi/scsi.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/scsi/scsi_ioctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/scsi/scsicam.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/scsi/sg.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-afb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb16.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb2.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb24.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb32.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb8.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-hga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-ilbm.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-iplan2p2.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-iplan2p4.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-iplan2p8.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-mac.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-mfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-vga-planes.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon-vga.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/fbcon.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/font.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/macmodes.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/newport.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/s3blit.h#1 branch +... //depot/linux-aic79xx-2.4.0/include/video/sbusfb.h#1 branch +... //depot/linux-aic79xx-2.4.0/init/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/init/version.c#1 branch +... //depot/linux-aic79xx-2.4.0/ipc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/ipc/msg.c#1 branch +... //depot/linux-aic79xx-2.4.0/ipc/sem.c#1 branch +... //depot/linux-aic79xx-2.4.0/ipc/shm.c#1 branch +... //depot/linux-aic79xx-2.4.0/ipc/util.c#1 branch +... //depot/linux-aic79xx-2.4.0/ipc/util.h#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/acct.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/capability.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/context.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/dma.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/exec_domain.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/exit.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/fork.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/info.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/itimer.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/kmod.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/ksyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/module.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/panic.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/pm.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/printk.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/ptrace.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/resource.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/sched.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/signal.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/softirq.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/sys.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/sysctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/time.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/uid16.c#1 branch +... //depot/linux-aic79xx-2.4.0/kernel/user.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/lib/brlock.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/cmdline.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/ctype.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/dec_and_lock.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/errno.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/inflate.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/string.c#1 branch +... //depot/linux-aic79xx-2.4.0/lib/vsprintf.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/mm/bootmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/filemap.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/highmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/memory.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/mlock.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/mmap.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/mmap_avl.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/mprotect.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/mremap.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/numa.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/oom_kill.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/page_alloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/page_io.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/shmem.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/slab.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/swap.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/swap_state.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/swapfile.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/vmalloc.c#1 branch +... //depot/linux-aic79xx-2.4.0/mm/vmscan.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/TODO#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/cl2llc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/cl2llc.pre#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/fc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/fddi.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/hippi.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/llc_macinit.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/llc_sendpdu.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/llc_utility.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/p8022.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/p8023.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/actionnm.awk#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/actionnm.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/compile.awk#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/opcd2num.sed#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/opcodes#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/opcodesnm.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/pseudocode#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/pseudo/pseudocode.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/psnap.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/sysctl_net_802.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/tr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/transit/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/transit/compile.awk#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/transit/pdutr.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/transit/pdutr.pre#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/transit/timertr.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/802/transit/timertr.pre#1 branch +... //depot/linux-aic79xx-2.4.0/net/Changes#1 branch +... //depot/linux-aic79xx-2.4.0/net/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/README#1 branch +... //depot/linux-aic79xx-2.4.0/net/TUNABLE#1 branch +... //depot/linux-aic79xx-2.4.0/net/appletalk/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/appletalk/aarp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/appletalk/ddp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/appletalk/sysctl_net_atalk.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/addr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/addr.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/atm_misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/clip.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/common.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/common.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/ipcommon.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/ipcommon.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/lec.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/lec.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/lec_arpc.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/mpc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/mpc.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/mpoa_caches.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/mpoa_caches.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/mpoa_proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/protocols.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/pvc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/raw.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/resources.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/resources.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/signaling.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/signaling.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/atm/svc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/af_ax25.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_addr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ds_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ds_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ds_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_iface.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ip.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_out.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_std_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_std_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_std_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_uid.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ax25/sysctl_net_ax25.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_device.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_fdb.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_forward.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_if.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_input.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_notify.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_private.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_private_stp.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_private_timer.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp_bpdu.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp_if.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/datagram.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/dev_mcast.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/dst.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/dv.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/filter.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/iovec.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/neighbour.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/netfilter.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/profile.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/rtnetlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/scm.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/skbuff.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/sock.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/sysctl_net_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/core/utils.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/README#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/TODO#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/af_decnet.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_fib.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_neigh.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_nsp_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_nsp_out.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_rules.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_table.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/dn_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/decnet/sysctl_net_decnet.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/econet/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/econet/af_econet.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/econet/sysctl_net_ec.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ethernet/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ethernet/eth.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ethernet/pe2.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ethernet/sysctl_net_ether.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/af_inet.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/arp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/devinet.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_frontend.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_hash.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_rules.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_semantics.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/icmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/igmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/inetpeer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_forward.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_fragment.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_gre.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_input.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_nat_dumb.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_options.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_output.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_sockglue.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ipconfig.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ipip.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/ipmr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_ftp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_icmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_tcp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_udp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_standalone.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_fw_compat.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_fw_compat_masq.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_fw_compat_redir.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_ftp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_icmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_tcp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_udp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_unknown.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_rule.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_standalone.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_queue.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_tables.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipchains_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipfwadm_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_LOG.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_MARK.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_MASQUERADE.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_MIRROR.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_REDIRECT.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_REJECT.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_TOS.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_limit.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_mac.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_mark.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_multiport.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_owner.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_state.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_tos.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_unclean.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/iptable_filter.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/iptable_mangle.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/protocol.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/raw.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/syncookies.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/sysctl_net_ipv4.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_input.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_ipv4.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_minisocks.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_output.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/udp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv4/utils.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/README#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/addrconf.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/af_inet6.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/datagram.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/exthdrs.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/icmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_fib.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_flowlabel.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_fw.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_input.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_output.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ipv6_sockglue.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/mcast.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/ndisc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6_tables.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_MARK.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_limit.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_mac.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_mark.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_multiport.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6table_filter.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/proc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/protocol.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/raw.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/reassembly.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/sit.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/sysctl_net_ipv6.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/tcp_ipv6.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipv6/udp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipx/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipx/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipx/af_ipx.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipx/af_spx.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/ipx/sysctl_net_ipx.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/af_irda.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/compressors/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/compressors/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/compressors/irda_deflate.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/crc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/discovery.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_core.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_lmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_param.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_ttp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_tty.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_tty_attach.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_tty_ioctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irda_device.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/iriap.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/iriap_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irias_object.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_client.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_client_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_common.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_eth.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_filter.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_provider.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_provider_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlap.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlap_comp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlap_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlap_frame.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlmp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlmp_event.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irlmp_frame.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_irda.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_irda.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_ppp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_ppp.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irqueue.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irsyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irsysctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/irttp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/parameters.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/qos.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/irda/wrapper.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/README#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/accept.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/datasending.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/logging.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/main.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/make_times_h.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/misc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/prototypes.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/rfc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/rfc_time.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/security.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/security.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/sockets.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/structure.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/sysctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/sysctl.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/userspace.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/khttpd/waitheaders.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/lapb/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_iface.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_out.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netlink/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/netlink/af_netlink.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netlink/netlink_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/af_netrom.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_loopback.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_out.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/nr_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netrom/sysctl_net_netrom.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/netsyms.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/packet/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/packet/af_packet.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/af_rose.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_link.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_loopback.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_out.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/rose_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/rose/sysctl_net_rose.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/Config.in#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_api.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_fw.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_rsvp.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_rsvp.h#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_rsvp6.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_tcindex.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/cls_u32.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/estimator.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/police.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_api.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_atm.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_cbq.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_csz.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_dsmark.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_fifo.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_generic.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_gred.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_ingress.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_prio.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_red.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_sfq.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_tbf.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sched/sch_teql.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/socket.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/auth.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/auth_null.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/auth_unix.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/clnt.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/pmap_clnt.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/sched.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/stats.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/sunrpc_syms.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/svc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/svcauth.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/svcauth_des.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/svcsock.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/sysctl.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/xdr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sunrpc/xprt.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/sysctl_net.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/unix/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/unix/af_unix.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/unix/garbage.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/unix/sysctl_net_unix.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/wanrouter/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/wanrouter/patchlevel#1 branch +... //depot/linux-aic79xx-2.4.0/net/wanrouter/wanmain.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/wanrouter/wanproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/af_x25.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/sysctl_net_x25.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_dev.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_facilities.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_in.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_link.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_out.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_route.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_subr.c#1 branch +... //depot/linux-aic79xx-2.4.0/net/x25/x25_timer.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/Configure#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/MAKEDEV.ide#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/Menuconfig#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/README.Menuconfig#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/checkconfig.pl#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/checkhelp.pl#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/checkincludes.pl#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/cramfs/GNUmakefile#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/cramfs/mkcramfs.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/docgen#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/docproc.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/gen-all-syms#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/header.tk#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/kernel-doc#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/ksymoops/README#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/BIG.FAT.WARNING#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/Makefile#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/checklist.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/colors.h#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/dialog.h#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/inputbox.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/lxdialog.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/menubox.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/msgbox.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/textbox.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/util.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/yesno.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/makelst#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/mkdep.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/patch-kernel#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/pathdown.sh#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/split-include.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/tail.tk#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/tkcond.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/tkgen.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/tkparse.c#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/tkparse.h#1 branch +... //depot/linux-aic79xx-2.4.0/scripts/ver_linux#1 branch + +Change 563 by gibbs@aslan on 2002/01/22 11:00:23 + + aic79xx.c: + Add initial AHD_PKT_BITBUCKET_BUG and overrun handling. + In the cases where the hardware will allow such a + situation, we will transfer data into on overrun + buffer in host memory to simulate a bitbucket. + + aic79xx.h: + AHD_PKT_BITBUCKET_BUG definition. + + aic79xx.reg: + Add per-mode location for saving the accumulator during + interrupt handlers. + + Add bits describing an overrun condition. + + Add a downloadable constant for defining the + overrun buffer location. + + aic79xx.seq: + Turn freeze_queue into a subroutine and have it + save and restore the accumulator around using it. + + Add preliminary support for handling overruns. + + aicasm/aicasm.c: + Formatting nits. + + aicasm/aicasm_gram.y: + aicasm/aicasm_symbol.h: + Allow constants to be larger than 8bits. The sequencer + will still complain if an expression doesn't manipulate + the constant into a form that fits in 8bits during an + assignment. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#22 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#15 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#18 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#19 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#13 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#13 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#9 edit + +Change 554 by gibbs@overdrive on 2002/01/22 00:14:54 + + scsi_iu.h: + Add a header file describing datastructures of + SCSI Information Units. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#1 add + +Change 552 by gibbs@overdrive on 2002/01/21 23:50:24 + + aic7xxx_osm.c: + block_size() is only available in very recent + kernels. Use 1024 for anything earlier than 2.4.17. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#84 edit + +Change 529 by gibbs@overdrive on 2002/01/21 14:19:18 + + aic7xxx_host.h: + Correct idempotency ifdefs. + + aic7xxx_osm.c: + Use "block_size" rather than a hard coded 1024 to + access the underlying device in search of an fdisk table. + + aic7xxx_osm.c: + Protect code unreferenced if MMAPIO is flase. + + Use pci_set_drvdata(), rather than touching the + PCI device structure manually. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#83 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#30 edit + +Change 504 by gibbs@aslan on 2002/01/15 13:23:22 + + aic79xx.c: + Set SAVED_SCSIID and SAVED_LUN to invalid values + everytime we restart the sequencer. + + Panic() after dumping card state should we complete + an SCB twice. This will be removed prior to release. + + Add panics after most calls to ahd_dump_card_state(). + This guarantees that we can capture any diagnostic + output. + + Implement status packet fetching. In the future we + may embed the sense data location into the SCB so + a sequencer interrupt is not necessary, but for now + we let the kernel fill in the sense address. + + Add sequencer interrupt codes for failures of diagnostics + performed by the sequencer. + + Properly set the bug variable to include all bugs we + have workarounds for. + + Add support for using the abort feature (once it works) + to catch references by a target to tag identifiers that + are not allocated. + + Protect the routines parsing the execution list from + infinite transaction loops. + + Enahance ahd_dump_card_state to include more information. + + aic79xx.h: + Move derivative register access routines to aic79xx_inline.h. + Using inline functions allows type promotion which aids in + gracefully handling quads. + + aic79xx.reg: + Add additional sequencer interrupt codes. + + Fix a typo in the definition of LQIABORT. + + Define the sequencer stack size. + + aic79xx.seq: + Revert to non-inlined version of load_first_seg. The + bug that this "worked around" has been addressed. + + Use calls to setjmp in our interrupt handler rather than + manually setting the longjmp address. + + aic79xx_inline.h: + Add routines for syncing sense buffers. + + Add inline versions of the derivative register + access methods (inw, inq, etc.). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#21 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#14 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#17 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#18 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#16 edit + +Change 503 by gibbs@aslan on 2002/01/13 20:57:51 + + Packetized checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#17 edit + +Change 495 by gibbs@aslan on 2002/01/09 09:29:03 + + aic7xxx.c: + Set both SAVED_LUN and SAVED_SCSIID to impossible values + in ahc_restart(). We can't trust these fields until the + sequencer trusts them again and since we didn't initialize + them explicitly during startup, a rogue interrupt could + have caused us to access them, generating a parity error. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#54 edit + +Change 493 by gibbs@aslan on 2002/01/08 12:39:10 + + Setup task attributes (tag type) for packetized transactions. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#15 edit + +Change 492 by gibbs@aslan on 2002/01/08 11:20:40 + + aic79xx.c: + Add additional trace sequencer interrupt codes. + + Make a fist pass at handling unexpected bus frees. We + now expect a busfree at the end of any PPR negotiation + that results in a change in the IU_REQ agreement. + + Don't set PACED transfers for async speeds. This bug + didn't seem to upset the chip, but who knows. + + Fix a bug in initialization of the per-device annex + data. Start at the PRECOMP column and allow + auto-increment to do the rest. + + Enable IU/QAS/RD_STRM/WR_FLOW negotiation. + + Enable searching through the pending list for SCBs to + abort in ahd_abort_scbs(). + + Print out FIFO status in ahd_dump_card_state(). + + aic79xx.reg: + Add more debugging SEQINTCODEs. + + Add definitions for the BUSFREETIME status bits. + + Correct definition of the PRECOMP annex column. + + Add FETCH_INPROG to SG_STATE for workaround of + SG_CACHE_AVAIL coming true soon than expected. + + Change DRAINING_SCB to LONGJMP_SCB as the SCBID + is now set for many different longjmp routines. + + aic79xx.seq: + Add code to drain the good status fifo. + + Service longjmp routines in order to clear FIFOs + for a non-packetized transaction. + + Complete the workaround for Razor #494. + + SG_CACHE_AVAIL will come true in the other FIFO as + soon as the FIFO using the SG_CACHE has provided + enough segments to satify it's transfer or has seen + saveptrs status. Use FETCH_INPROG state to guard against + this early switch confusing the other FIFO into believing + it has valid SG data. + + Clear SG_FULL_RESID from both the SCB_SGPTR and the + RESIDUAL_SGPTR by clearing the flag in SCB_SGPTR prior + to the copy to the residual field. + + Update the calc_resid subroutine to include the setting + of the residual datacnt. + + Remove the monitor_drain handler. We rely on the data + FIFO's high priority to handle this case. + + Only defer completions if a longjmp routine for the + SCB of interrest is still active. This simplifies + the check_fifo routine. + + Inline the good_status_IU handler to lose a stack level. + + aic79xx_inline.h: + Clear the task_management field if we are packetized. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#20 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#13 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#16 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#16 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#53 edit + +Change 485 by gibbs@overdrive on 2001/12/17 23:07:26 + + aic79xx_osm.c: + Correct typos and style nits. + + Properly track the transfer length in + scb->platform_data->xfer_len. We failed to + update this variable during the conversion to + use the Core ahd_sg_setup() routine. + + Increment cur_seg instead of using the first + segment for every segment in the transfer. + + Remove target_offset. Since single function + twin chips don't exist in the 79XX class, target_offset + and target are synonymous. + + If we don't have a "linux target" structure for for + a device pertaining to an async event, don't service + the event. + + aic79xx_osm_pci.c: + Linux counts every 4 bytes of config space as a bar + regardless of whether the BAR is 64bit or not. Update + use of pci_resource_start() to reflect this strange + method of indexing. + + Correct check of retrieved ioport bases. base and + base2 are pointers. + + Correct think-o in mapping regsiters. We only want to + attempt IO space if maddr is NULL indicating that + memory mapped space is not available. + + aic7xxx_osm.c: + Style nit. + + If we don't have a "linux target" structure for for + a device pertaining to an async event, don't service + the event. + + aic7xxx_osm_pci.c: + Correct check of retrieved ioport base. + base is a pointer. + + Correct think-o in mapping regsiters. We only want to + attempt IO space if maddr is NULL indicating that + memory mapped space is not available. + + aicasm/Makefile: + yacc in some distributions does not support the -o + output option. Modify the Makefile to avoid using + this feature. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#82 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#29 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#10 edit + +Change 484 by gibbs@overdrive on 2001/12/17 21:32:02 + + Disable information unit transfers for now. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#19 edit + +Change 483 by gibbs@overdrive on 2001/12/17 15:23:19 + + aic79xx_osm.c: + Remove vestigial call to aic7770_linux_probe(). This driver + does not support that chip. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#4 edit + +Change 482 by gibbs@overdrive on 2001/12/17 13:43:35 + + Include SPI4 PPR options. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#4 edit + +Change 481 by gibbs@overdrive on 2001/12/17 13:43:25 + + Set SCB_PACKETIZED on all packetized SCBs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#3 edit + +Change 480 by gibbs@overdrive on 2001/12/17 13:43:06 + + Prepare for release 0.0.0 of the aic79xx driver. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#4 edit + +Change 479 by gibbs@aslan on 2001/12/17 13:27:15 + + aic79xx.c: + aic79xx.seq: + Initialize SG_STATE to 0 for sanity on card initialization + and anytime a new transfer is started where additional + segments are not needed. + + aic79xx.reg: + SG_SENSE is no longer needed. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#18 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#15 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#15 edit + +Change 478 by gibbs@overdrive on 2001/12/17 11:44:16 + + aic7xxx.h: + Remove alternate bus space tag handles. We don't bother + holding the unused regions any more. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#37 edit + +Change 477 by gibbs@aslan on 2001/12/17 11:43:03 + + aic79xx.c: + Break out the computation of "post patch" sequencer + addresses so we can use it to compute the location + of the sequencer's interrupt handler. + + Start the process of marking Rev A bugs with the + AHD_SENT_SCB_UPDATE_BUG. + + Expand PPR option rules to include all supported + options. + + Correct the setting of precompensation values to + reflect fixes in the A2. + + Begin the process of handling PPR negotiations that + end in a bus free due to a change in IU_REQ. + + Enhance DFF mode specific initialization to include + the LongJmp address and the interrupts we want enabled. + + We must be in the SCSI mode to initialize the + negotiation table. + + Enable write flow control, read streaming and + information units if the SEEPROM tells us to enable + packetized. + + aic79xx.h: + Add AHD_SENT_SCB_UPDATE_BUG definition. + + Add SCB flags indicating packetized transaction and + a PPR that should result in a busfree. + + aic79xx.reg: + Add additional sequencer interrupt codes for packetized + failure modes. + + Allow the STACK and LASTSCB to be written two. The + STACK needs to be written for longjump operations. + LASTSCB needs to be written for the AHD_SENT_SCB_UPDATE_BUG. + + Add PRECOMP constants. + + Move DATA_COUNT_ODD to per-mode scratch. + + Add STATUS_RCVD field to SCB_CONTROL. + + A status code of STATUS_PKT_SENSE indicates sense + data was recieved for this packetized transaction. + + Set the high bit of LONGJMP_ADDR to indicate that + it is no longer valid. + + aic79xx.seq: + Add setjmp/longjmp support. + + Implement AHD_SENT_SCB_UPDATE_BUG workaround. + + Break out first segment load, SCB completion, + residual calculation and save pointers so they + can be used for packetized operations. + + Make a first cut at sequencer interrupt services + for packetized operations. + + aic79xx_inline.h: + aic79xx_osm.c: + Use an SCB flag to indicate that a transaction is + packetized freeing up a bit in SCB_CONTROL for + STATUS_RCVD. + + aic79xx_pci.c: + Add compaq IDs. + + aicasm/aicasm_gram.y: + aicasm/aicasm_scan.l: + aicasm/aicasm_symbol.c: + aicasm/aicasm_symbol.h: + Add the ability to export a sequencer label to + the host driver. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#17 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#12 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#14 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#14 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#13 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#12 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#9 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#12 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#8 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#3 edit + +Change 475 by gibbs@overdrive on 2001/12/13 14:45:21 + + aic79xx_osm.h: + Put definition of KERNEL_VERSION into a more + appropriate place. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#3 edit + +Change 474 by gibbs@overdrive on 2001/12/13 14:43:24 + + Makefile: + Delete common makefile. Each version of Linux is + so different that having one Makefile isn't practical. + Our build process has not referenced this version for + some time. + + aic7770_osm.c: + Pass port information into aic7770_config rather than + using a back door through the bus tag and handle to + get it. This allows us to properly clean up mappings + should our attach fail. + + Port is now passed into aic7770_map_registers. + + Don't set platform data irq field until allocation is + successful. This avoids freeing attempting to free + an IRQ we don't own during teardown of a failed attach. + + aic79xx_osm.c: + Clean up unmapping of SCB data. In the single buffer case, + we now store the bus address for the buffer in the SCB + platform data so we don't need to recreate it from the + S/G list. The S/G list may be changed by and auto request + sense operation, so it cannot be trusted. + + Formatting nits. + + Allow DT transfers to devices that only claim SCSI_2 if they + have the DT_REQ bit set in thier inquiry data. This fixes + slow transfers on certain IBM drivers. + + aic79xx_osm.h: + Add powerof2 #define. + + Add buf_busaddr into the SCB platform data. + + aic79xx_osm_pci.c: + Correct comments to reflect reality. + + aic7xxx_osm.c: + Only define modversion info in this file. This should fix + builds on 2.2.X kernels. + + Clean up unmapping of SCB data. In the single buffer case, + we now store the bus address for the buffer in the SCB + platform data so we don't need to recreate it from the + S/G list. The S/G list may be changed by and auto request + sense operation, so it cannot be trusted. + + Initialize platform IRQ field to unallocated value so we + don't inadvertantly free an IRQ we don't own in ahc_free(). + + Use AHC_NUM_LUNS rather than hard coded value. + + Properly initialize sg_count prior to mapping any segments. + + Allow DT transfers to devices that only claim SCSI_2 if they + have the DT_REQ bit set in thier inquiry data. This fixes + slow transfers on certain IBM drivers. + + aic7xxx_osm.h: + Add tasklet include and adjust for movement of files. + + Add buf_busaddr to scb_platform_data. + + Add define for AHC_LINUX_NOIRQ. + + Adjust for new prototype for aic7770_map_registers. + + aic7xxx_osm_pci.c: + Properly release memory regions if we fail to ioremap them. + In general clean up how we allocate memory regions. + + Don't set platform data irq field until allocation is + successful. This avoids freeing attempting to free + an IRQ we don't own during teardown of a failed attach. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#9 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#81 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#74 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#28 edit + +Change 473 by gibbs@aslan on 2001/12/07 17:48:46 + + aic79xx.c: + Initialize new SG_STATE, per DFF, scratch ram variable. + + Display SG_STATE information when dumping card state + while in a DFF mode. + + aic79xx.reg: + Add SG_STATE and SAVED_MODE scratch ram variables. + + aic79xx.seq: + Move the return label to a location where there is + already a solicatry return instruction. + + Add code to service FIFOS for packetized transactions + to the main idle loop. + + We can't rely on ARRDONE after ARREN is disabled. The + chip clears that bit at the same time ARREN is cleared. + Remove a comment about an optimization we could perform + if ARRDONE stayed set. + + Add a comment explaining why we must disable interrupts + when setting the mode pointer register. + + Have allocate FIFO service FIFOs so it can free them + up. We still require both FIFOs to be free for a + non-packetized request. + + Optimize the delivery of an unpacketized cdb. If we + are using SCB internal storage, we can bypass the + SG FIFO and set SHCNT directly. This shaves ~12 clocks + of the start of the cdb transfer. + + Start using CLRCHN instead of RSTCHN. There is still + more optimization that can occur in the non-packetized + path in terms of deferring DFIFO teardown. + + Modify data_group_idle_loop to service the other FIFO + as well as perform SCB prefetch/completion type + activities. + + Use SG_STATE to track S/G prefetch and FIFO servicing + requirements. + + Clear SG_STATE when the last segment is loaded or we + have completed this data group transfer (last segment + done or phasechange). + + If we go into an overrun condition, release the FIFO + by performing a reset channel if a FIFO is still + allocated. + + Change ultra2 -> data_group in all labels. + + Rely exclusively on SCSIEN going away to signal end + of a data transfer. SCSIEN transitions on last segment + done, so testing for it in the loop too is superfluous. + + aic79xx_inline.h: + Add a better comment for why we read from the MODE_PTR + register after every SCB ram read. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#16 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#13 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#13 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#12 edit + +Change 470 by gibbs@aslan on 2001/12/04 17:09:19 + + aic79xx.seq: + Convert ccsg idle loop into a proceedure so it can + be used in places other than the main idle loop. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.seq#12 edit + +Change 469 by gibbs@aslan on 2001/12/02 14:30:08 + + aic79xx.c: + Add a trace point for printing out saved pointer and residual + data from an SCB. + + Remove a hardware workaround that is no longer needed for + H2A2 and beyond. + + Quite some diagnostic code. + + Trim our downloaded constants down to only those needed. + + Add a #error if the number of downloaded constants grows + or shrinks from the number we currently initialize. + + Perform more robust calculations to determine the constants + used for S/G element prefetch. + + aic79xx.reg: + Add the saved/residual tracepoint to SEQINTCODE. + + Trim unused downloaded constants. + + aic79xx.seq: + Make use of SG_PREFETCH_CNT_LIMIT constant in handling + S/G fetch. This ensures that a complete segment is + still left in the buffer prior to attempting to use it. + + Assume the kernel will start the DMA after a PDATA_REINIT + call. + + Correct some comments. + + Don't clear the data channel after a data group phase. + Defer this to await busfree. This guarantees that SHADDR + is still valid should a saved data pointers occur. + + aic79xx_inline.h: + Add "ahd_inl_scbram()". + + aic79xx_osm.c: + Correct another case where we were still using an + ahd_syncrate. + + aicasm/aicasm_gram.y: + Don't complain about an immediate aliasing the accumulator + if the immediate is a downloaded constant. + + aicasm/aicasm_symbol.c: + Output a #define for the number of downloaded constants + the sequencer program is expecting. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#15 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#12 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#11 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#11 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#11 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#11 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#2 edit + +Change 468 by gibbs@overdrive on 2001/11/28 15:47:30 + + aic79xx_host.h: + aic79xx_osm.c: + aic79xx_osm.h: + aic79xx_osm_pci.c: + aic79xx_proc.c: + First cut at Linux U320 OSM layer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#1 add + +Change 467 by gibbs@aslan on 2001/11/28 15:45:19 + + aic79xx_pci.c: + Correct include location under Linux. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#7 edit + +Change 466 by gibbs@aslan on 2001/11/28 15:43:12 + + aic79xx.c: + aic79xx.reg: + Linux's kernel ffs() implementation doesn't handle + constants properly on x86. Compensate by using + a constant for the bit offset as well. Grrrr! + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#14 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#11 edit + +Change 465 by gibbs@aslan on 2001/11/28 14:55:16 + + aic79xx.c: + Remove debugging printfs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#13 edit + +Change 464 by gibbs@aslan on 2001/11/28 14:46:07 + + aic79xx.c: + Remove Debugger() statements that Linux doesn't understand. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#12 edit + +Change 463 by gibbs@overdrive on 2001/11/28 14:43:42 + + aic79xx_inline.h: + Avoid code bloat by only including 64bit S/G format + code if sizeof(bus_addr_t) > 4. The compiler should + optimize out this code if this check against a constant + fails. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#10 edit + +Change 462 by gibbs@aslan on 2001/11/28 14:41:51 + + aic79xx.h: + aic79xx_pci.c: + Put PCI BAR offsets into a header where + all OSMs can see them. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#11 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#6 edit + +Change 461 by gibbs@aslan on 2001/11/27 17:52:25 + + aic79xx.h: + Pull ahd_inw/l/q and ahd_outw/l/q into Core header file. + + aic79xx_osm.h: + Mask off top port bit when doing I/O. + + ahd_pci.c: + Map a subregion for bshs[1], offset by 256 bytes, when we are + doing memory mapped I/O. This compensates for the masking + of the port performed above. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#10 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#2 edit +... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#2 edit + +Change 459 by gibbs@overdrive on 2001/11/27 13:32:05 + + Enable ID expansion. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#11 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#9 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#10 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#10 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#9 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#5 edit + +Change 458 by gibbs@overdrive on 2001/11/27 13:29:05 + + Allow FreeBSD and Linux to fully share core files. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#16 edit +... //depot/aic7xxx/aic7xxx/aic79xx.c#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#52 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#36 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#34 edit + +Change 454 by gibbs@overdrive on 2001/11/25 17:22:22 + + Complete the update of the assembler. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#1 add +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#1 add + +Change 453 by gibbs@overdrive on 2001/11/25 15:46:40 + + aic7xxx_osm.c: + Add a function to pull out user tag depth information. + Use it to limit the per-device tag depth. The kernel + will never send us more commands than this limit anyway + since we honor this limit in select queue depths, but + this will make the information in /proc jibe with the + users settings and prevent some confusion. + + On kernels that support them (>= 2.4.0), use a tasklet + to flush any queued commands pent up in our per-device + queues + + Use an inline function, ahc_linux_next_device_to_run(), + to factor out some common code. + + aic7xxx_osm.h: + Add structures for our tasklet to the linux platform + softc. + + aicasm/Makefile: + Update for second parser/scanner in the assembler. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#80 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#73 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#9 edit + +Change 452 by gibbs@overdrive on 2001/11/25 15:32:58 + + aic7770.c: + Disable chip interrupts early in chip attach. + We poke a few registers on the chip prior to + resetting it so this narrows the window where + an unexpected interrupt could hang us. + + Convert all exported symbols to use an "ahc" + prefix to avoid conflicts with other drivers. + + Use a common SEEPROM checksum. + + aic7xxx.c: + Clear any pending message state in ahc_restart(); + + Pass the ahc softc to ahc_update_residual. + ahc_update_residual calls ahc_calc_residual which + requires the softc to print path information if + debugging is enabled. + + Don't bother clearing message state just prior + to calling ahc_restart(); + + Always perform a bus read prior to waiting in + a delay loop waiting for a bus write to take + effect. This ensures that the first time + through the loop the delay occurs after the + write has taken effect. + + Style cleanup. + + Remove some initialization code left over from + a previous way of probing SCBs. + + Always clear parity error status after reading + any SCB or scratch locations that might be + uninitialized. The debugging code that dumps + scratch ram contents could trigger such an + event. + + Initialize any scratch ram locations that might + be read (by our interrupt handler most likely) + prior to being initialized by our first transaction. + SAVED_SCSIID falls into this category, but there + may be others. + + Remove some unecessary code. In this case, the + varaible "next" was initialized unecessarily which + could hide "use before initialization" bugs. + + Add some more information to ahc_dump_card_state(); + + aic7xxx.h: + Update ahc_update_residual() declaration. + + Move AHC_DEBUG definitions to this header. + + aic7xxx.reg: + aic7xxx.seq: + Update for changes in the assembler. + + aic7xxx_93cx6.c: + aic7xxx_93cx6.h: + Prefix exported symbols with "ahc". + + aic7xxx_inline.h: + Update ahc_update_residual() definition. + + Target mode command completions come in through + the qinfifo, so we must read it even if we are + only executing the target role. + + Change to power state D0 prior to mapping our + registers. BARs are usually cleared by a power + state change. + + Disable chip interrupts early in chip attach. + We poke a few registers on the chip prior to + resetting it so this narrows the window where + an unexpected interrupt could hang us. + + Use symbols prefixed by "ahc". + + Clear any parity errors that might occur while + trying to pull uninitialized SCB2 information. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#51 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#35 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#25 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#38 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#32 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#33 edit + +Change 451 by gibbs@overdrive on 2001/11/25 15:05:14 + + Teach the assembler about simple 'C' macros. + + Add a second parser/scanner to handle macro expansions. + + The arguments to patch functions are now specified in the + source file rather than be hard coded. + + Use the "driver neutral" "aic_patch_#_func() to denote the + static functions used to patch sequencer code. + + staticize all generated code to avoid conflicts when mutliple + drivers are compiled together. + + Teach the driver about register window modes. Have the assembler + complain if a register is accessed in a window that is not supported + by the register. + + Allow '<<' and '>>' expressions. They are evaluated during assembly. + + Complain if an expression used as an "immediate or the accumulator" + argument evaluates to 0. 0 is an alias for the accumulator in these + instruction formats and referencing the accumulator in these + situations is likely not the desired effect. + + BUGS: Line numbers get screwed up on program listing when macros are + used. The assembler should output the expanded code into the + listing file so line numbers and instruction lines make sense. + Line numbers in error messages may also be wrong for macros, + but I haven't verified this. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#12 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#10 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#10 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#7 edit + +Change 448 by gibbs@aslan on 2001/11/19 21:22:51 + + Checkpoint. Tagged queuing now works. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#9 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#8 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#9 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#9 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#8 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#4 edit + +Change 447 by gibbs@aslan on 2001/11/17 21:06:51 + + Checkpoint: U160 now operational. + + Deal with the NEG table. And NEG table bugs. + + Implement IOCELL workarounds. + + Deal with missing DIS_MSGIN_DUAL in OPTIONMODE register. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#8 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#7 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#8 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#8 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#7 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#3 edit + +Change 445 by gibbs@aslan on 2001/11/14 16:49:32 + + Checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#7 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#6 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#7 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#7 edit + +Change 444 by gibbs@aslan on 2001/11/13 21:49:20 + + Checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#6 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#5 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#6 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#6 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#6 edit + +Change 442 by gibbs@aslan on 2001/11/13 14:07:10 + + Checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#5 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#4 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#5 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#5 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#5 edit + +Change 440 by gibbs@aslan on 2001/11/08 21:14:12 + + Checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#4 edit +... //depot/aic7xxx/aic7xxx/aic79xx.h#3 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#4 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#4 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#4 edit + +Change 439 by gibbs@aslan on 2001/11/07 18:54:07 + + Checkpoint. Selection Timeout path now operates. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#3 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#3 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#3 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#3 edit + +Change 438 by gibbs@aslan on 2001/11/07 17:28:10 + + Checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#2 edit + +Change 437 by gibbs@aslan on 2001/11/07 15:41:15 + + Checkpoint. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.h#2 edit +... //depot/aic7xxx/aic7xxx/aic79xx.reg#2 edit +... //depot/aic7xxx/aic7xxx/aic79xx.seq#2 edit +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#2 edit +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#2 edit + +Change 435 by gibbs@aslan on 2001/10/25 13:28:33 + + Initial 790X Core driver import. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic79xx.c#1 add +... //depot/aic7xxx/aic7xxx/aic79xx.h#1 add +... //depot/aic7xxx/aic7xxx/aic79xx.reg#1 add +... //depot/aic7xxx/aic7xxx/aic79xx.seq#1 add +... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#1 add +... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#1 add + +Change 421 by gibbs@overdrive on 2001/10/11 15:33:59 + + Bump version to 6.2.4. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#72 edit + +Change 420 by gibbs@overdrive on 2001/10/11 15:33:30 + + aic7xxx_osm.c: + Move the include of linux/module.h to our osm header file. + + Add a MODULE_LICENSE entry. + + Don't forget to include the high address bits in + calls to pci_unmap_single(). + + Fix a typo in a comment. + + Use hex instead of decimal when reporting return codes + to our exception handling routines. + + aic7xxx_osm.h: + Include, unconditionally, linux/module.h. + + aic7xxx_osm_pci.c: + Add a MODULE_DEVICE_TABLE entry for our PCI ids. + + Formatting cleanup. + + Use a simpler way of expressing "all bits set in something + the size of a bus_addr_t" without getting compiler warnings + on some platforms. + + Kill an unused variable. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#79 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#71 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#27 edit + +Change 419 by gibbs@overdrive on 2001/10/11 15:21:15 + + aic7xxx.c: + Force renegotatiation of transfer parameters on the + next command to a device after a selection timeout or + a parity error. + + Fix a typo in a comment. + + Put SCBs that aren't in the scbindex table and not already + in the free list, back into the free list. This can happen + in certain "SCB queued twice for abort processing" cases. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#50 edit + +Change 408 by gibbs@overdrive on 2001/09/13 17:49:29 + + Still part of the 6.2.3 release... + + aic7xxx.c: + Export ahc_abort_scbs() for use by OSMs. + + In ahc_abort_scbs(), only remove entries from + the busy target table that match the abort + criteria. In the past, we might take out any + entry for a particular target. + + In ahc_abort_scbs() only search the disconnected + list and busy target table if the role is not + ROLE_TARGET. + + aic7xxx.h: + Export ahc_abort_scbs() for use by OSMs. + + aic7xxx.reg: + Add a definition for the SCSI offset count in + SSTAT3 for U2+ adapters. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#49 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#34 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 edit + +Change 391 by gibbs@overdrive on 2001/09/12 13:14:51 + + Update version for 6.2.3 driver release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#70 edit + +Change 390 by gibbs@overdrive on 2001/09/12 13:14:00 + + Update copyright to reflect new binary distribution disclaimer + clause (if you choose BSD license terms) and Adaptec copyright. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#78 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#69 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#26 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#13 edit + +Change 389 by gibbs@overdrive on 2001/09/12 13:07:18 + + Update copyright to reflect new binary distribution disclaimer + clause and Adaptec copyright. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#48 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#33 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#23 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#7 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#31 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#32 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#11 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#7 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#9 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#7 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#7 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#9 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#6 edit + +Change 387 by gibbs@overdrive on 2001/09/11 15:31:45 + + aic7xxx_inline.h: + Remove spurious '{' that only came into effect if + target mode was compiled in. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#30 edit + +Change 386 by gibbs@overdrive on 2001/09/11 14:19:51 + + aic7xxx_osm.c: + Only run our shutdown hook for the SYS_DOWN and + SYS_HALT events. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#77 edit + +Change 385 by gibbs@overdrive on 2001/09/11 14:18:38 + + aic7xxx.h: + Add residual information to struct target_data to + allow residual information to be handled in the + same way as for the initiator role. Prior to this + fix, the status byte field was overwritten when the + residual count was saved to the SCB assuming the + residual was non-zero. + + aic7xxx.reg: + Adjust for change in SCB layout for target mode. + + aic7xxx.seq: + Adjust for change in SCB layout for target mode. + + Send an ignore wide residue message if we are acting + as a target in wide mode and complete a data-in phase + with an odd data count. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#32 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#36 edit + +Change 382 by gibbs@overdrive on 2001/09/10 17:31:46 + + aic7xxx_osm.c: + Initialize our host template's "max_lun" field. This may + correct an issue with probing big, multi-lun, devices in + Linux post 2.4.3. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#76 edit + +Change 381 by gibbs@overdrive on 2001/09/10 16:29:53 + + aic7xxx.c: + aic7xxx.h: + Add a new constant, AHC_SCB_MAX_ALLOC, which indicates + how many of the AHC_SCB_MAX scbs available on the card + we can actually allocate. This can be at most + AHC_MAX_QUEUE+1. The FreeBSD OSM, by virtue of CAM, already + enforced this limit. This change ensures that all OSMs + are restricted to this limit. + + aic7xxx_inline.h: + If CMDCMPLT is active in intstat, check all completion queues. + This corrects a race condition when target mode is enabled + that could allow us to miss running a queue that just received + a new command. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#47 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#31 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#29 edit + +Change 357 by gibbs@overdrive on 2001/09/06 13:25:10 + + aic7xxx_osm.h: + Add constants related to the "periodic_otag" feature. + + Increase the ordered tag threshold to 500 commands. + + Issue an mb() even when using PIO to talk to the card. + This may be necessary on platforms other than intel. + + Bump driver version to 6.2.2. + + aic7xxx_osm.c: + Remove comments/globals referencing unused driver options. + + Hook up the following driver options: + no_probe Disable EISA/VLB controller probing + no_reset Supress initial bus resets + extended Enable extended geometry on + all controllers + periodic_otag Send an ordered tagged transaction + periodically to prevent tag starvation. + This may be required by some older disk + drives/RAID arrays. + reverse_scan Sort PCI devices highest Bus/Slot to + lowest + + Don't attempt to set the PCI dma mask if we're an EISA/VLB + controller. + + Dump controller state on any abort/bdr instead of only when + the user has turned on the "verbose" option. This should + facilitate the generation of user bug reports. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#75 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#68 edit + +Change 356 by gibbs@overdrive on 2001/09/06 13:16:05 + + Only trust sub-device information on Adaptec cards. It seems + that many motherboard implementations do not follow the Adaptec + sub-device id spec. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#31 edit + +Change 340 by gibbs@overdrive on 2001/08/24 11:24:25 + + aic7xxx_osm.c: + Remove a no-longer relevant comment. + + Add information about our module parameters that + can be displayed by modinfo. + + Use the channel letter, rather than the number, as + we do in all other displays of this information. + + Never attempt PPR messages on a device that claims + to be SCSI2. Jaz drives hang, rather than reject + the message, and sending these messages to SCSI2 + devices is just too dangerous. + + Whitespace cleanup. + + aic7xxx_osm.h: + Include endian information for use by aicasm_insformat.h. + + aic7xxx_osm_pci.c: + Always reserve both our memory and I/O port range to guard + against other devices attaching to these same addresses. + We still only use one of the two regions for accessing the + card. + + aicasm/Makefile: + Add explicit dependencies on y.tab.h so it is rebuilt + prior to any files, even generated ones, that need it. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#74 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#67 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#25 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#8 edit + +Change 339 by gibbs@overdrive on 2001/08/24 11:17:35 + + aic7xxx.c: + Re-intialize LASTPHASE everytime we restart the sequencer. + This should make the value of LASTPHASE fully deterministic. + + Correct target mode handling of Abort and Abort Tag messages. + The sequencer now sets TARGET_MSG_PENDING whenever it runs + into an unexpected message while parsing "ident" messages + during a selection. We have to clear this flag whenever we + stop processing messages. We also need to restart the sequencer + for any abort message so that we return to busfree. + + Send the tag number along with the abort tag message immediate + notification message. + + The construct "foo(i++, i++, i++);" is not guaranteed to + give "expected" results by the C standard. Change some + diagnostic code to avoid this. + + Correctly set ahc->unpause to include the IRQMS bit on + non-PCI platforms. + + aic7xxx.reg: + Add TARGET_MSG_PENDING bit to the SEQ_FLAGS2 register. + + aic7xxx.seq: + During identify message processing, setup SAVED_LUN. We + may need it to handle certain types of messages. + + Handle unexpected messages that have already been REQ'ed + as well as those that have not been REQ'ed but should be + handled due to ATNI being active. + + Postpone the "queue full" determination until we are about + to transition to command phase. This should give the + initiator the ability to abort transactions even if our + queue would otherwise be full. + + aic7xxx_pci.c: + Take another stab at validating the 9005 subdevice information + prior to using it. We now ensure that the device type stated + in the device field is compatible with the one expressed in + the subdevice field. This should allow the latest report + of a "missing channel" to be probed again. + + aicasm/aicasm.c + Pull the platform endian file for userland operations from + here, so that the insformat header, which is shared with the + kernel, never gets the wrong file. The kernel driver will + deal with getting the correct endian values in its platform + specific file. + + aicasm/aicasm_insformat.h: + String #include of endian header files. This is now handled + by the client of this file. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#46 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#21 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#35 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#30 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#10 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#6 edit + +Change 330 by gibbs@overdrive on 2001/08/16 15:16:36 + + "GNU Public License" -> "GNU General Public License" + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#73 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#66 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#11 edit + +Change 329 by gibbs@overdrive on 2001/08/16 15:12:51 + + "Gnu Public License" -> "Gnu General Public License" + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#13 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#45 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#30 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#20 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#34 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#9 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#28 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#29 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#9 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#6 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#5 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#6 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#5 edit + +Change 323 by gibbs@overdrive on 2001/08/05 15:00:59 + + aic7xxx_linxu.c: + aic7xxx_osm_pci.c: + pci_set_dma_mask() became available in 2.4.3, not 2.4.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#72 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#23 edit + +Change 322 by gibbs@overdrive on 2001/08/05 14:58:46 + + aic7xxx.c: + Correct an off by one in our critical section handling. + SEQADDR always reads the next instruction to execute, + so we must subtract one from its value before making + comparisons with entries in the critical section table. + + Kill a "too verbose" bootverbose printf. + + Print a few additional registers whenever we dump + card state. + + Show the SCB_CONTROL and SCB_TAG values for all pending + SCBs in card SCB ram when dumping card state. + + aic7xxx.seq: + Fix a bug introduced while optimizing the SDPTR path. + We would ack the SDPTR message twice on Ultra2 or better + chips if it occurred after all data had been transferred + for a transaction. + + Change our workaround for the PCI2.1 retry bug on some + chips. Although the previous workaround was logically + correct, its faster method of draining the FIFO seemed + to occassionally confuse the FIFO state. We now drain + the FIFO at half the speed which avoids the problem. + + aic7xxx_pci.c: + Chips with the PCI 2.1 retry bug can't handle a 16byte + cachesize. If the cachesize is set to 16bytes, drop + it to 0. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#44 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#33 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#28 edit + +Change 317 by gibbs@overdrive on 2001/07/18 16:19:54 + + Bump version to 6.2.0 Release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#65 edit + +Change 314 by gibbs@overdrive on 2001/07/18 14:17:17 + + Remove a stray '{' after a #endif. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#27 edit + +Change 311 by gibbs@overdrive on 2001/07/18 14:14:39 + + Only set AHC_RUN_TQINFIFO if we are performing the target role. + Otherwise there is no guarantee that the tqinfifo is even allocated. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#26 edit + +Change 309 by gibbs@overdrive on 2001/07/17 18:10:35 + + aic7xxx_osm.h: + Add definition for BUS_SPACE_MAXADDR_32BIT. This + is now used in our bus_dma_tag_create() operations. + + Remove a spurious return(0) I mistakenly added when + "fixing" compiler warnings for NOTREACHED code. + + aic7xxx_osm_pci.c: + Quite a compiler warning for code that cannot be reached + unless sizeof(dma_addr_t) > 4. We now mask our 39bit + mask with a mask based on the size of dma_addr_t so + we cannot have an overflowing assignment the compiler + will complain about. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#64 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#22 edit + +Change 308 by gibbs@overdrive on 2001/07/17 18:06:31 + + aic7xxx.c: + Enforce a 4GB boundary on all DMA transactions. Due + to 32bit DAC restrictions, 64bit addressed operations + cannot cross a 4GB boundary. This is enforced manually + in the Linux driver as bus tag boundaries are not honored, + but for FreeBSD, the tags are used by the OS dma map + routines to enforce the limits. + + Bus resets (initiated or incoming) clear the ENSELI bit + in the SCSISEQ register. For this reason, we cannot + defer the re-enabling of bus reset interrupts in target + mode - select-ins might get disabled and we'd never + know. + + aic7xxx.seq: + Remove sequencer code to re-enable bus reset interrupts + when we are selected as a target. + + aic7xxx_inline.h: + Correct calls to ahc_dmamap_sync. In Linux these are + no-ops, so the fact that we didn't reference our maps + correctly didn't show up. + + aicasm/aicasm.c: + aicasm/aicasm_symbol.c: + Use queue macros instead of groveling through queue + data structures manually. + + Fix a few style bugs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#43 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#32 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#25 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#7 edit + +Change 307 by gibbs@overdrive on 2001/07/16 17:31:46 + + aic7xxx.c: + style(9) fix. + + aic7xxx.seq: + Correct high address support for non-Ultra2 chips. + + Bring back a fix for flaky external SRAM support + on the aic7895. + + aic7xxx_inline.h: + In ahc_update_residual(), don't bother setting + a 0 length residual. The residual is cleared + prior to starting the command. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#42 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#31 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#24 edit + +Change 306 by gibbs@overdrive on 2001/07/16 17:26:24 + + aic7xxx_osm.c: + Clean out PCMCIA defines. This driver does not + require any special compile environment to serve + cardbus cards. + + Clear residual data prior to starting a new SCB. + The calculate residual code now only sets residual + information should a residual exist. + + Remove a redundant assignment to platform_data->xfer_len. + Our map_seg routine already updates this field. + + Manually set the DRIVER_SENSE bit in the result word + of commands that have had auto-sense. + + aic7xxx_osm.h: + Kill silly compiler warnings for no return with value + from functions that panic. + + aic7xxx_osm_pci.c: + Use more formal "ULL" designation on some constants. + + cam.h: + Remove unused, at least in Linux, definition of + CAM_SIM_QUEUED. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#71 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#63 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#10 edit + +Change 303 by gibbs@overdrive on 2001/07/11 17:51:28 + + Bump version to 6.2.0-BETA1. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#62 edit + +Change 302 by gibbs@overdrive on 2001/07/11 17:47:06 + + Remove another diagnostic printf. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#20 edit + +Change 301 by gibbs@overdrive on 2001/07/11 17:35:55 + + Place a diagnostic behind bootverbose. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#27 edit + +Change 300 by gibbs@overdrive on 2001/07/11 17:35:34 + + Add VERSION statements. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#19 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#30 edit + +Change 299 by gibbs@overdrive on 2001/07/11 17:34:54 + + Remove debugging printfs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#70 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#19 edit + +Change 297 by gibbs@overdrive on 2001/07/10 18:23:07 + + Add support for the "VERSION" keyword. + + Print out all version information in generated files. + + Fix a bug in the handling of "include" statements. + For some reason this didn't show up until the version + changes were added. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#7 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#5 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#7 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#5 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#6 edit + +Change 295 by gibbs@overdrive on 2001/07/10 15:27:47 + + aic7xxx_osm.c: + Don't panic if the system decides to have us select + the queue depth for a non-existant device. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#69 edit + +Change 293 by gibbs@overdrive on 2001/07/10 14:23:44 + + aic7xxx_osm.c: + Properly ignore inquiry responses for VPD data or where + the amount of data that is actually transferred is not + enough for us to pull transfer negotiation information. + + Add synchronization of datastructures we share with + the hardware. + + Add a per-segment mapping helper function that deals + with 39bit addressing issues and complete 39bit + support. + + Fool the OS into always allocating our shared device/kernel + memory below the 4GB mark by changing our dma mask on + the fly. + + Add a method for determining the amount of memory in + the system. + + Run devices in a Round Robin fashion to ensure fairness. + + Correct code that handles temporary SCB resource shortages. + + Don't report bus resets until we have successfully registered + our host structure. + + aic7xxx_osm.h: + Add synchronization primatives. + + Add definition for the inquiry command for use in + our filtering function. + + Use system defined mb() macro rather than rolling our + own. Allow memory mapped I/O on the ia64. + + aic7xxx_osm_pci.c: + Enable 39Bit addressing if the system supports large + addresses on the platform and we have more than 2GB + of memory installed. Some systems move memory to + after the 4GB mark, reserving the 2-4GB range for + device memory mapping. + + Clean up a compile error when memory mapped I/O is + not enabled. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#68 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#61 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#18 edit + +Change 291 by gibbs@overdrive on 2001/07/10 13:43:58 + + aic7770.c: + Set fields directly in the softc rather than indirect + through the probe config structure. + + aic7xxx.c: + Add synchronization calls for data structures in + system memory that are shared between the kernel + driver and the controller. + + Several corrections to 39bit address support: + o 39bit support is a flag not a feature + in the ahc softc. + + o Perform endian conversions for high + address bits. + + Prevent PPR messages from being issued when acting + as a target. + + Add diagnostics in ahc_search_qinfifo() for tracking + down qinfifo corruption issues. + + aic7xxx.h: + Store a pointer to the sg_map_node in the scb to + allow scatter gather lists to be synced. + + aic7xxx.seq: + 39bit support is a flag not a feature in the ahc softc. + + aic7xxx_inline.h: + Add inlines to facilitate synchronization operations. + + Synchronize SCBs anytime we perform a lookup from + SCB ID to pending SCB and prior to queuing SCBs to + the adapter. + + Synchronize the first qoutfifo and tqinfifo when + checking for newly completed transactions. + + Fix several bugs in the spurious interrupt handling + in our interrupt handler. Hopefully this will stop + the reports of spurious PCI errors. + + aic7xxx_pci.c: + Add pci 64bit bus status bit definition for the + DEVCONFIG register. + + Be even more careful in checking that a 9005 subdevice + ID is valid prior to processing it. This should prevent + us from dropping the second channel on some MB controllers. + + Set fields directly in the softc rather than indirect + through the probe config structure. + + Set the DAC enable bit when in 39bit addressing mode. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#41 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#29 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#29 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#23 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#26 edit + +Change 277 by gibbs@overdrive on 2001/06/18 14:52:58 + + Switch to round-robin scheduling of devices to ensure fairness + during resource contention. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#67 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#60 edit + +Change 276 by gibbs@overdrive on 2001/06/18 14:47:51 + + aic7xxx.c: + Spelling fixes. + + Handling data pointers reinitialization requests + from the sequencer. This only occurs should the + target take us into the data phase twice with + an interviening non-data phase. + + On a data overrun, clear the channel of all preloaded + S/G segments if we are an Ultra2 controller. This + error path does not go through the normal dma shutdown + path, so we have to clear the S/G fifo while the kernel + is recording the overrun event. + + Clear AHC_ULTRA rather than deal with the AHC_ULTRA_DISABLED + flag. + + Fixup a few cases where we were not properly byte swapping + S/G element data in the ignore wide residue handler. Update + this routine for 39bit addressing support. Remove the + reload of the explicit HADDR registers. We now do this at + the time we re-enter the dataphase, which, in 90% of the + cases, will never happen. + + Add the ahc_reinitialize_dataptrs() routine. This is called + to fixup the dma engine's data pointers should we re-enter + a data phase with some interveining phase. This used to + be handled in the sequencer, but is so rare (i.e. almost + never happens), that there is little reason to waste + sequencer space on it. + + aic7xxx.h: + Remove AHC_ULTRA_DISABLED ahc_flag. + + Add AHC_39BIT_ADRESSING ahc_flag. + + aic7xxx.reg: + Add the DSCOMMAND1 register which holds the high + address load select bits. + + Add the PDATA_REINIT sequencer interrupt code. + This is hit should we re-enter a data phase and + need help from the kernel to restore the data ptrs. + + Remove the RESIDUAL sequencer interrupt code. + It has not been used for some time. + + aic7xxx.seq: + Spelling fixes. + + Streamline the ULTRA2 idle loop. The HADDR register + is not directly shaddowed, so we can read the contents + placed there by the bmov out of CCSGRAM. + + Remove data_phase_reinit. This is now handled by a + sequencer interrupt request to the kernel. + + Remove the assert method. We now do the test inline + which saves two instructions per call. + + Add 39bit addressing support. + + Add shortcuts for updating our residual pointers and + handling SDPTR messages when we are at the end of + a transfer. + + aic7xxx_inline.h: + Change the way that unsolicited interrupts are counted. + We now only increment and/or test the unsolicited interrupt + count if we see that we don't have any conventional + interrupts pending. More importantly, everytime we do + unsolicited interrupt processing, we clear the count. + This prevents us from constantly performing unsolicited + interrupt handling. + + aic7xxx_pci.c: + Set CLRPARERR in CLRINT for all PCI error status. The + manuals are not sufficiently clear on which status code + cause parity errors to be set, so we play it safe. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#40 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#28 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#18 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#28 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#25 edit + +Change 207 by gibbs@overdrive on 2001/05/01 16:18:08 + + Bump driver version to 6.1.13. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#59 edit + +Change 206 by gibbs@overdrive on 2001/05/01 16:16:11 + + aic7xxx.seq: + For chips without S/G pipelining, we can only ack the + SDPTR message after SHADDR has been saved. On these + chips, SHADDR increments with every bus transaction, + even PIO. This corrects a data corruption bug in the + last version of the sequencer for non-ULTRA2 chips. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#27 edit + +Change 205 by gibbs@overdrive on 2001/05/01 15:04:36 + + aic7xxx_osm.c: + Add support for the 2.4.4 scsi_set_pci_device API. + + aic7xxx_osm.h: + Move the conditional declaration of KERNEL_VERSION to + the top of aic7xxx_osm.h so it is defined before + its first usage. + + Remove late conditional include of linux/version.h. We + already include it unconditionally at the top of this file. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#66 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#58 edit + +Change 203 by gibbs@overdrive on 2001/05/01 13:07:13 + + Makefile: + Add the current directory to the include path. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#7 edit + +Change 202 by gibbs@overdrive on 2001/05/01 13:02:15 + + aic7xxx_osm.c: + Don't unregister from the reboot notification chain + from within our handler. The routine that calls down + the chain does not guard against removals. + + Create a simq_freeze method as a compliment to the + simq_release method. This method assumes that the + ahc lock is held prior to call. The release method + requires a lock as it is only called from a timeout + handler. The release method now guards (other than + for a small race that cannot be avoided without a + mid-layer change) unblocking and blocking multiple times. + Blocking is either on or off; the mid-layer does not + have semaphore type semantics for this feature. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#65 edit + +Change 196 by gibbs@overdrive on 2001/04/27 14:24:13 + + Bump version number to 6.1.12 for next release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#57 edit + +Change 195 by gibbs@overdrive on 2001/04/27 14:23:37 + + aic7xxx_osm.c: + current -> curr + + Implement a kludge to deal with inquiry requests that + are not large enough for us to pull the spi3 bits. + In this case, we assume that a device that tells us + they can provide inquiry data that spans the SPI3 + bits can handle a PPR request. If the inquiry + request has sufficient buffer space to cover these + bits, we check them to see if any ppr options are + available. This corrects the drop to async narrow + for U160 devices during a cdrecord bus scan. + + aic7xxx_osm.h: + Remove the kludge to undefine "current". We've renamed + any effected fields in the driver to avoid a conflict. + + dma_addr_t appeared in 2.2.18, not 2.2.17. + + aic7xxx_proc.c: + current -> curr + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#64 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#56 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#11 edit + +Change 194 by gibbs@overdrive on 2001/04/27 14:19:04 + + aic7xxx.c: + current->curr to avoid Linux's use of current as a + #define for the current task on some architectures. + + Add a helper function, ahc_assert_atn(), for use in + message phases we handle manually. This hides the fact + that U160 chips with the expected phase matching disabled + need to have SCSISIGO updated differently. + + if (ahc_check_residual(scb) != 0) + ahc_calc_residual(scb); + else + ahc_set_residual(scb, 0); + + becomes: + + ahc_update_residual(scb); + + Modify scsi parity error (or CRC error) handling to + reflect expected phase being disabled on U160 chips. + + Move SELTO handling above BUSFREE handling so we can + use the new busfree interrupt behavior on U160 chips. + + Correct a long standing but latent bug in + ahc_find_syncrate(). We could choose a DT only + rate even though DT transfers were disabled. + + When displaing controller characteristics, include the + speed of the chip. This way we can modify the transfer + speed based on optional features that are enabled/disabled + in a particular application. + + aic7xxx.h: + The real 7850 does not support Ultra modes, but there are + several cards that use the generic 7850 PCI ID even though + they are using an Ultra capable chip (7859/7860). We start + out with the AHC_ULTRA feature set and then check the + DEVSTATUS register to determine if the capability is really + present. + + current -> curr + + ahc_calc_residual() is no longer static allowing it to + be called from ahc_update_residual() in aic7xxx_inline.h. + + aic7xxx.reg: + Add a combined DATA_PHASE mask to the SCSIPHASE register + definition to simplify some sequencer code. + + aic7xxx.seq: + Take advantage of some performance features available only + on the U160 chips. The auto-ack feature allows us to ack + data-in phases up to the data-fifo size while the sequencer + is still setting up the DMA engine. This greatly reduces + read transfer latency and simplifies testing for transfer + complete (check SCSIEN only). We also disable the expected + phase feature, and enable the new bus free interrupt behavior, + to avoid a few instructions. + + Re-arrange the Ultra2+ data phase handling to allow us to + do more work in parallel with the data fifo flushing on a + read. + + On an SDTR, ack the message immediately so the target can + prepare the next phase or message byte in parallel with + our work to honor the message. + + aic7xxx_inline.h: + ahc_update_residual() now looks at the residual valid + flag in an endian safe way. This fixes a residual bug + on the PPC. + + aic7xxx_pci.c: + Correct a few product strings. + + Enable several U160 performance enhancing features. + + Modify Ultra capability determination so we will enable + Ultra speeds on devices with a 7850 PCI id that happen + to really be 7859 or 7860s. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#39 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#27 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#17 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#26 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#21 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#24 edit + +Change 189 by gibbs@overdrive on 2001/04/09 14:52:16 + + Bump version number to 6.1.11 for latest release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#55 edit + +Change 188 by gibbs@overdrive on 2001/04/06 16:38:18 + + aic7xxx.c: + In ahc_build_transfer_msg() filter the period and + ppr_options prior to deciding whether a PPR message + is required. ppr_options may be forced to zero + which will affect our decision. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#38 edit + +Change 187 by gibbs@overdrive on 2001/04/06 15:54:25 + + aic7xxx_osm.c: + Don't try negotiations that require PPR messages + if bus reset is enabled. We'll wait until we + successfully retrieve Inquiry data so we can make + an informed decision. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#63 edit + +Change 186 by gibbs@overdrive on 2001/04/05 16:29:33 + + aic7xxx_osm.h: + Bump version number to 6.1.10. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#54 edit + +Change 185 by gibbs@overdrive on 2001/04/05 16:29:00 + + aic7xxx_osm.c + Use scsi_(un)block_requests() to effect a freeze of the + entire controller queue. Scsi_unblock_requests() has been + modified to actually run any stalled queues in the 2.4.X + kernel sources. For 2.2.X, scsi_(un)block_requests() was + implemented. Since we now rely on this functionality, + only patch updates to the driver will be provided from + here on out. + + With this change, our bus settle delay can be of any + length and still avoid triggering command timeouts from + the midlayer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#62 edit + +Change 182 by gibbs@overdrive on 2001/04/04 16:32:27 + + Bump version number to 6.1.9 for latest release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#53 edit + +Change 181 by gibbs@overdrive on 2001/04/04 16:31:50 + + aic7xxx_osm.c: + Correct a bug in ahc_done() that prevented us from running + the in-core device queue anytime the physical device was + idle. This caused problems anytime the driver received + more than one transaction for a device that does not + support tagged transactions. Unless another transaction + was queued to us to kick the queue, the transaction would + never get run. Zip drives are the most commonly found + device that was affected by this bug. + + CONFIG_AIC7XXX_RESET_DELAY -> CONFIG_AIC7XXX_RESET_DELAY_MS + Too many people have stale settings under the old config + option name for us to use it with a different meaning. + The setting is now in milli-seconds to allow more granular + control so stale values resulted in an extremely short bus + settle delay. + + Add a shutdown hook that resets all of the controllers + to a safe state. + + Update for changes in the way negotiation prameters are + communicated with the Core. + + Correct a function name in a printf. + + tmode_tstate -> ahc_tmode_tstate. + + aic7xxx_proc.c: + tmode_tstate -> ahc_tmode_tstate. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#61 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#10 edit + +Change 180 by gibbs@overdrive on 2001/04/04 16:22:29 + + aic7770.c: + Register our interrupt driver prior to enabling our + Bus drivers. This is just added paranoia. + + aic7xxx.c: + Namespace cleanup continues: + tmode_tstate -> ahc_tmode_tstate + tmode_lstate -> ahc_tmode_lstate + + Clean up the check condition path by branching early rather + than indenting a giant block of code. + + Add support for target mode initiated sync negotiation. + The code has been tested by forcing the feature on for + all devices, but for the moment is left inaccesible until + a decent mechanism for controlling the behavior is complete. + Implementing this feature required the removal of the + old "target message request" mechanism. The old method + required setting one of the 16 bit fields to initiate + negotiation with a particular target. This had the nice + feature of being easy to change the request and have it + effect the next command. We now set the MK_MESSAGE bit + on any new command when negotiation is required. When + the negotiation is successful, we walk through and clean + up the bit on any pending commands. We have to walk + the commands to reset the SCSI syncrate values already, + so no additional work is required. The only drawback of + this approach is that the negotiation is deferred until + the next command is queued to the controller. On the plus + side, we regain two bytes of sequencer scratch ram and 6 + sequencer instructions. + + When cleaning up a target mode instance, never remove the + "master" target mode state object. The master contains + all of the saved SEEPROM settings that control things like + transfer negotiations. This data will be cloned as the + defaults if a target mode instance is re-instantiated. + + Correct a bug in ahc_set_width(). We neglected to update + the pending scbs to reflect the new parameters. Since + wide negotiation is almost always followed by sync + negotiation it is doubtful that this had any real + effect. + + When in the target role, don't complain about + "Target Initiated" negotiation requests when an initiator + negotiates with us. + + Pull all info that used to be in ahc_timeout for the FreeBSD + OSM into ahc_dump_card_state(). This info should be printed + out on all platforms. + + aic7xxx.h: + Add the SCB_AUTO_NEGOITATE scb flag. This allows us to + discern the reason the MK_MESSAGE flag is set in the hscb + control byte. We only want to clear MK_MESSAGE in + ahc_update_pending_scbs() if the MK_MESSAGE was set due + to an auto transfer negotiation. + + Add the auto_negotiate bitfield for each tstate so that + behavior can be controlled for each of our enabled SCSI + IDs. + + Use a bus interrupt handler vector in our softc rather + than hard coding the PCI interrupt handler. This makes + it easier to build the different bus attachments to + the aic7xxx driver as modules. + + Update seeprom definitions for the latest formats. + + aic7xxx.reg: + Remove the TARGET_MSG_REQUEST definition for sequencer ram. + + aic7xxx.seq: + Fix a few target mode bugs: + + o If MK_MESSAGE is set in an SCB, transition to + message in phase and notify the kernel so that + message delivery can occur. This is currently + only used for target mode initiated transfer + negotiation. + + o Allow a continue target I/O to compile without + executing a status phase or disconnecting. If + we have not been granted the disconnect privledge + but this transfer is larger than MAXPHYS, it may + take several CTIOs to get the job done. + + Remove the tests of the TARGET_MSG_REQUEST field + in scratch ram. + + aic7xxx_inline.h: + Use ahc->bus_intr rather than ahc_pci_intr. + + aic7xxx_pci.c: + Move a comment to the correct location. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#37 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#26 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#16 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#25 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#20 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#23 edit + +Change 172 by gibbs@overdrive on 2001/03/22 17:47:51 + + Bump version to 6.1.8. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#52 edit + +Change 169 by gibbs@overdrive on 2001/03/22 15:56:41 + + aic7xxx_osm.c: + aic7xxx_osm.h: + Add support for switching to from full to basic + command queuing. Flags in the ahc_linux_device + structure indicate what kind of queuing to perform. + + In the past, we issued an ordered tag every 250 + transactions. We now issue an ordered tag every + 250 transactions issued without the device queue + going empty. + + aic7xxx_proc.c: + Use an unsigned long for total number of commands + sent to a device. %q and %lld don't seem to work + under Linux or I'd have used a quad. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#60 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#51 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#9 edit + +Change 167 by gibbs@overdrive on 2001/03/22 15:45:33 + + aic7770.c: + aic7xxx_pci.c: + Don't map our interrupt until after we are fully setup to + handle interrupts. Our interrupt line may be shared so + an interrupt could occur at any time. + + aic7xxx.h: + aic7xxx.c: + Add support for switching from fully blown tagged queing + to just using simple queue tags should the device reject + an ordered tag. + + Remove per-target "current" disconnect and tag queuing + enable flags. These should be per-device and are not + referenced internally be the driver, so we let the OSM + track this state if it needs to. + + Use SCSI-3 message terminology. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#36 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#25 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#22 edit + +Change 165 by gibbs@overdrive on 2001/03/19 17:58:07 + + aic7770.c: + ahc_reset() leaves the card in a paused state. + Re-arrange the code so we reset the chip earlier + so we can avoid a manual pause during setup. + + Setup the controller without enabling card interrupts. + + aic7xxx.c: + Fix a bug in ahc_lookup_phase_entry(). We never traversed + past the first entry. This routine is only used in + diagnostics so this had only a limited effect. + + Start out life with card interrupts disabled. The bus + code will enable the interrupts once setup is complete + and our handler is in place. + + Initialize our softc unit to -1 so that code such as + ahc_linux_next_unit() can traverse the list looking for + coliding unit numbers without tripping over entries that + have not yet had their unit number set. + + Enhance ahc_dump_card_state(). OSMs should be able to + rely on this to dump any controller specific data of + interest. Most of the additional registers printed + used to be printed in the FreeBSD timeout handler. + + Add a function pointer in our softc for a bus specific + interrupt handler. This removes some dependencies on + the PCI code so that bus attachments can be compiled + as modules separate from the core. + + aic7xxx.reg: + Use the naming for bit 5 of DFSTATUS in the data book, + FIFOQWDEMP. + + aic7xxx.seq: + In our idle loop, use an or instruction to set PRELOADEN + rather than rewriting the contents of DMAPARAMS to + DFCNTRL. The later may re-enable the DMA engine if + the idle loop is called to complete the preload of at + least one segment when a target disconnects on an S/G + segment boundary but before we have completed fetching + the next segment. This correts a hang, usually in + message out phase, when this situation occurs. This + bug has been here for a long time, so the situation + is rare, but not impossible to reproduce. + + Wait for at least 8 bytes in the FIFO before testing to + see if the DMA fetch of an SCB has stalled. The old + code used FIFOEMP, which goes false on a single byte. + Since we drain the FIFO 8 bytes at a time, using FIFOQWDEMP + is safer. + + If a device happens to be exceptionally slow in asserting + HDONE, our workaround for a stalled SCB dma can be triggered. + Make this situation non-fatal by terminating our FIFO + emptying should we complete the transfer. + + aic7xxx_inline.h: + ahc_pci_intr() -> ahc->bus_intr() + + aic7xxx_pci.c: + Setup ahc->bus_intr(). + + Enable board interrupts at the appropriate time. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#9 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#35 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#24 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#24 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#19 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#21 edit + +Change 164 by gibbs@overdrive on 2001/03/19 17:44:04 + + aic7xxx_osm.c: + Format to 80 columns. + + Break after finding a matching entry in the token + table during aic7xxx_setup. + + print the correct name of a function in a diagnostic. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#59 edit + +Change 163 by gibbs@overdrive on 2001/03/10 23:51:53 + + Bump version to 6.1.7. The too leanient interpretation + of the seeprom signature could result in improper + termination settings on some MBs, and this is a big + enough bug to warant a new release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#50 edit + +Change 162 by gibbs@overdrive on 2001/03/10 23:50:09 + + Handle cross builds. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#6 edit + +Change 161 by gibbs@overdrive on 2001/03/10 23:41:16 + + We now generate a header file for the db include + under linux to handle the build on more distribution + types. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#5 edit + +Change 160 by gibbs@overdrive on 2001/03/10 23:40:38 + + aic7xxx.h: + Add a definition for the 3.X BIOS signature. + + aic7xxx_inline.h: + We must setup queuestat before processing + command complete interrupts in case target + mode is enabled. + + aic7xxx_pci.c: + Be more selective in the BIOS signatures we + support. Some seeproms have a signature of + 0xFFFF, so testing greater than 0x250 resulted + in false positives. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.h#23 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#18 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#20 edit + +Change 159 by gibbs@overdrive on 2001/03/09 18:37:25 + + To be compatible with older kernels, our setup routine + must be called aic7xxx_setup(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#58 edit + +Change 158 by gibbs@overdrive on 2001/03/09 18:00:41 + + Play some games so we have a better chance of actually + building on more systems. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#5 edit + +Change 157 by gibbs@overdrive on 2001/03/09 17:04:49 + + aic7770_osm.c: + aic7xxx_osm.h: + Adjust aic7770_map_int() to not rely on a passed in "shared" + argument. We can now look at ahc->flags to see whether the + interrupt source is edge or level. + + aic7xxx_osm.c: + Only adjust our goal negotiation settings if the device + is actually present. This prevents a disconnected lun + that does not claim to support negotiations from messing + up the settings for a successfully probed lun whose inquiry + data properly reflects the abilities of the device. + + Set the device structure as releasable should the inquiry + come back with anything other than lun connected. We + should also do this if the device goes away as evidenced + by a selection timeout, but as we can't know if this + condition is persistant and there is no guarantee that + the mid-layer will reissue the inquiry command we use + to validate the device, I've simply added a comment + this effect. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#57 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#49 edit + +Change 156 by gibbs@overdrive on 2001/03/09 16:58:41 + + Adjust our interrupt handler so it will work in the edge + interrupt case. We must process all interrupt sources + when the interrupt fires or risk not ever getting an + interrupt from them. This involves marking the fact + that we are relying on an edge interrupt in ahc->flags + and checking for this condition in addition to the + AHC_ALL_INTERRUPTS flag. + + This will make it into the 6.1.6 Linux driver release. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#17 edit + +Change 155 by gibbs@overdrive on 2001/03/08 17:00:32 + + Bump version number for new release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#48 edit + +Change 154 by gibbs@overdrive on 2001/03/08 16:59:57 + + Convert to ahc_* and ahc_linux_* function names. + + aic7770_osm.c: + Drop the SA_INTERRUPT flag. According to Linus, + it should not be set. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#56 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#47 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#8 edit + +Change 153 by gibbs@overdrive on 2001/03/08 16:58:20 + + Cleanup exported symbol names. We now use ahc_* exclusively + to reduce the chance of conflicts with other modules. + + Staticize symbols that should have always been static. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#34 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#21 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#16 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#19 edit + +Change 152 by gibbs@overdrive on 2001/03/07 18:54:38 + + aic7xxx_osm.c: + Correct our softc comparison routine so that, regardless + of which function is seen first, the primary channel of + a multi-function chip is probed first. + + Note that the host structure only records a single scsi + ID. This means that multi-channel controllers, such as + the 2742T, cannot inform the SCSI layer of the IDs used + by channels other than the first. + + There is also no way to communicate the probe order of + channels on a multi-channel adapter. We could swap the + channels internally, but that would probably be more + confusing than just not supporting the option. + + Add a crude hack to make modunload/modload cycles work + now that we are using the new PCI methods. We must + detach our driver from each PCI device referenced by + a call to our release method. The PCI code doesn't have + a method to do this, so we muck with the pci_dev ourselves. + + Deregister our PCI driver when aic7xxx_release releases + the last host instance. + + Fix a bug in the inquiry sniffing code. It was possible + to set our period to a non-zero value even though the + offset was zero. This might have confused some async + devices. + + aic7xxx_osm.h: + ahc_power_state_change() is now an OSM routine. + + aic7xxx_osm_pci.c + Make our pci_driver non-static so that aic7xxx_osm.c + can reference it during module unload. + + Add an implementation to change the power state for + kernel versions that don't have a PCI method to do + this. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#55 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#46 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#16 edit + +Change 151 by gibbs@overdrive on 2001/03/07 18:45:53 + + aic7770.c: + Store a 2 bit channel number in ahc->flags. + + aic7xxx.c: + AHC_SUPPORT_PCI has never been defined. Use + AHC_PCI_CONFIG instead. + + Modify multi-function option merging to work + regardless of the order the functions are presented + to the driver. + + Adjust for the primary channel being a 2 bit integer + rather than a flag for 'B' channel being the primary. + + aic7xxx.h: + Adjust for the primary channel being represented as + a 2 bit integer in the flags member of the ahc softc. + + Cleanup the flags definitions so that comment blocks are + not cramped. + + Update seeprom definitions to correctly reflect the fact + that the primary channel is represented as a 2 bit + integer. + + aic7xxx.reg: + Add DFCACHETH to the definition of DFSTATUS for + completness sake. + + aic7xxx.seq: + On some chips, at least the aic7856, the transition from + MREQPEND to HDONE can take a full 4 clock cycles. Test + HDONE one more time to avoid this race. We only want our + FIFO hung recovery code to execute when the engine is + really hung. + + aic7xxx_pci.c: + Move the powerstate manipulation code into the OSM. Several + OSes now provide this functionality natively. + + Take another shot at using the data stored in scratch ram + if the SCB2 signature is correct and no SEEPROM data is + available. In the past this failed if external SCB ram + was configured because the memory port was locked. We + now release the memory port prior to testing the values + in SCB2 and re-acquire it prior to doing termination control. + + Adjust for new 2 bit primary channel setting. + + Trust the STPWLEVEL setting on any BIOS v 2.5X and above. + 3.X bioses have started to ship. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#7 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#33 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#20 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#23 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#18 edit + +Change 150 by gibbs@overdrive on 2001/02/28 17:44:09 + + aic7xxx_osm.c: + Fix the setup for the selection timeout setting. + + During exception processing dump the card state if + we are in verbose mode. + + Keep "driver_template" static so as not to conflict + with other files in the system. Instead, export a + pointer to the driver template with a more unique + symbol name. + + aic7xxx.h: + Export our pointer to the driver template. + + Bump driver version number to 6.1.5. + + aic7xxx_osm_pci.c: + Use the newly exported pointer to the driver template. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#54 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#45 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#15 edit + +Change 149 by gibbs@overdrive on 2001/02/28 17:36:26 + + aic7xxx.c: + Take advantage of a new flag managed by the sequencer + that indicates if an SCB fetch is in progress. If so, + the currently selected SCB needs to be returned to the + free list to prevent an SCB leak. This leak is a rarity + and would only occur if a bus reset or timeout resulting + in a bus reset occurred in the middle of an SCB fetch. + + Don't attempt to perform ULTRA transfers on ultra capable + adapters missing the external precision resistor required + for ultra speeds. I've never encountered an adapter + configured this way, but better safe than sorry. + + aic7xxx.h: + Add AHC_ULTRA_DIASABLED softc flag to denote controllers + missing the external precision resistor. + + aic7xxx.reg: + Add SEQ_FLAGS2 which currently only contains the SCB_DMA + (SCB DMA in progress) flag. + + aic7xxx.seq: + Manage the SCB_DMA flag of SEQ_FLAGS2. + + More carefully shutdown the S/G dma engine in + all cases by using a subroutine. Supposedly not + doing this can cause an arbiter hang on some ULTRA2 + chips. + + Formatting cleanup. + + aic7xxx_pci.c: + Configure any 785X ID in the same fashion and assume + that any device with a rev id of 1 or higher has the + PCI 2.1 retry bug. It seems that at least some revisions + of the 7856 have this bug. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#32 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#19 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#13 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#17 edit + +Change 148 by gibbs@overdrive on 2001/02/27 17:39:56 + + Correct a problem when one lun has a disconnected untagged + transaction and another lun has disconnected tagged transactions. + Just because an entry is found in the untagged table doesn't + mean that it will match. If the match on the lun fails, cleanup + the SCB (return it to the disconnected list or free it), and snoop + for a tag message. Before this change, we reported an unsolicited + reselection. This bug was introduced about a month ago during an + overly aggressive optimization pass on the reselection code. + + When cleaning up an SCB, we can't just blindly free the SCB. In + the paging case, if the SCB came off of the disconnected list, its + state may never have been updated in host memory. So, check the + disconnected bit in SCB_CONTROL and return the SCB to the disconnected + list if appropriate. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#21 edit + +Change 147 by gibbs@overdrive on 2001/02/26 17:05:34 + + Handle the case of 5MHz user sync rate set as "0" instead of 0x1c + in scratch ram. + + If we lookup a period of 0 in our table (async), clear the scsi offset. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#31 edit + +Change 146 by gibbs@overdrive on 2001/02/21 20:48:22 + + Put our exception handling semaphore into the softc rather + than as a global. I don't know what I was thinking when + I wrote this code, but having two different controllers sleeping + on the same mutex for error recovery is a recipe for disaster. + + Implement a controller global queue freeze function. We use this + feature to handle the initial reset bus settle delay. The queue + is unfrozen by a timer so all bus settle delays occur in parallel + and without stopping other kernel tasks from running. My only + remaining concern is that the specification of too long of a + reset delay might trigger a mid-layer timeout. The default + under linux is 5 seconds which is substantially less than the + timeouts used during probe. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#53 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#44 edit + +Change 145 by gibbs@overdrive on 2001/02/21 13:26:52 + + Bump version for 6.1.3 release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#43 edit + +Change 144 by gibbs@overdrive on 2001/02/21 13:26:21 + + Properly use the target offset rather than the target id + for choosing the correct untagged Q to manipulate. This + should correct problems with the 2742T. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#52 edit + +Change 143 by gibbs@overdrive on 2001/02/21 13:25:10 + + Identify adapters in ARO mode as such. + + Ensure that not only the subvendor ID is correct (9005) + but also that the controller type field is valid before + looking at other information in the subdevice id. Intel + seems to have decided that their subdevice id of 8086 + is more appropriate than Adaptec's sanctioned scheme. + + Add an exclusion entry for SISL (AAC on MB based adapters). + Adapters in SISL mode are owned by the RAID controller, so + even if a driver for the RAID controller is not present, + it isn't safe for us to touch them. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#16 edit + +Change 142 by gibbs@overdrive on 2001/02/21 13:21:47 + + Use the target offset rather than the target Id to reference + the untagged SCB array. The offset and id are identical save + in the twin channel case. This should correct several issues + with the 2742T. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#30 edit + +Change 141 by gibbs@overdrive on 2001/02/21 13:21:00 + + Correct an issue with the aic7770 in twin channel mode. + We could continually attempt to start a selection even + though a selection was already occurring on one channel. + This might have the side effect of hanging our selection + or causing us to select the wrong device. + + While here, create a separate polling loop for when we + have already started a selection. This should reduce + the latency of our response to a (re)selection. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#20 edit + +Change 140 by gibbs@overdrive on 2001/02/17 14:44:19 + + Bump version number to 6.1.2. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#42 edit + +Change 139 by gibbs@overdrive on 2001/02/16 16:15:57 + + Don't require iospace or mem space to be enabled in order to + attach to a PCI device. We only require that one of the mapping + registers is properly setup. + + This fix allows us to run on a G3 PowerMac. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#14 edit + +Change 138 by gibbs@overdrive on 2001/02/15 10:43:52 + + Use dma_addr_t as the Linux equivalent to bus_addr_t. uint32_t + works for only some platforms. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#41 edit + +Change 137 by gibbs@overdrive on 2001/02/15 10:42:44 + + Set the goal and user settings for sync and wide negotiation + prior to setting the current. This makes it easier for some + code in the Linux OSM to know when is an oportune time to + display a user message about transfer negotiation status. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#29 edit + +Change 136 by gibbs@overdrive on 2001/02/09 20:09:59 + + On second thought, don't test for ATN just before a + command complete message is processed. We probably + want to test for SCSIPERR, but this needs more thought. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#19 edit + +Change 135 by gibbs@overdrive on 2001/02/09 20:06:02 + + aic7xxx.c: + Style nits. + + Make sure that our selection hardware is disabled + as soon as possible after detecting a busfree and + even go so far as to disable the selection hardware + in advance of an event that will cause a busfree + (ABORT or BUS DEVICE RESET message). The concern + is that the selection hardware will select a target + for which, after processing the bus free, there + will be no commands pending. The sequencer idle + loop will re-enable the selection should still be + necessary. + + In ahc_handle_scsiint(), clear SSTAT0 events several + PCI transactions (most notably reads) prior to clearing + SCSIINT. The newer chips seem to take a bit of time + see the change which can make the clearing of SCSIINT + ineffective. + + Don't bother panicing at the end of ahc_handle_scsiint(). + Getting to the final else just means we lost the race + with clearing SCSIINT. + + In ahc_free(), handle case 0. This can happen when we fail + the attach for RAID devices. While I'm here, also kill + the parent dma tag. + + In ahc_match_scb(), consider initiator ccbs to be any + that are not from the target mode group. This fixes + a bug where an external reset CCB was not getting cleaned + up by the reset code. + + Don't bother freezing a ccb in any of our "abort" routines + when the status is set to CAM_REQ_CMP. + + aic7xxx.reg: + Reserve space for a completion queue. This will be used + to enhance performance in the near future. + + Remove an optimization for the 7890 autoflush bug that + turned out to allow, in rare cases, some data to get + lost. + + Even though we need a critical section to fully close + the command complete loophole, test for ATN anyway in + the command complete handler. Its better than nothing. + + Implement a simpler, faster, fix for the PCI_2_1 retry + bug that hangs the sequencer on an SCB dma. + + aic7xxx_pci.c + Use the correct mask for checking the generic aic7892 + entry. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#28 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#18 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#15 edit + +Change 134 by gibbs@overdrive on 2001/02/09 19:29:14 + + aic7xxx_osm.c: + Pull the host_no out of the host structure rather + than storing a copy of the field in our own platform + softc. + + Use the host_no rather than our unit nuber for any + "scsi%d" type printfs. In this case, the result is + a corrected printf for tagged queue depth. + + Anytime we run the complete queue, we must clear it. + We missed the clearing part when running the device + queue after queuing a new command. + + Use the same format for reporting transfer rates as the + /proc code. Only print transfer info if no further + negotiations are pending and the value is different from + the last one reported. + + Correctly format a printf used during error recovery. + + Don't forget to set the result before returning from + one case in ahc_queue_recovery_scb. + + Fix inverted test for the non-paging case. The result of + this bug was that we would set the MK_MESSAGE bit in an + SCB unrelated to the SCB we were trying to abort. + + Add a missing add_timer() call. It's hard to timeout + on a recovery action when no timer is running. This + also explains why I had to invert the test of the status + returned by del_timer() in the past. We always thought + the timer had expired because it was no longer active. + + Don't forget to run the device queue after error recovery + is complete. We don't want to leave any stray commands + stuck in our queues. + + aic7xxx_osm.h + Bump version for next release. + + Add a "last_tinfo" field to the ahc_linux_target to track + what negotiation settings have been announced. + + Kill unneeded host_no field in the platform softc. + + Bring the info_str structure into this header file so + we can export ahc_format_transinfo() outside of the + /proc code. + + aic7xxx_proc.c: + Export ahc_format_transinfo(). + + Use the host_no in the host structure rather than + removed field in the platform softc. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#51 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#40 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#7 edit + +Change 133 by gibbs@overdrive on 2001/01/28 15:49:09 + + aic7770_osm.c: + Convert to "aic7xxx_osm.h". + + On newer kernels, check the return of request_region. + + aic7xxx_osm.c: + Cleanup comment blocks for consistent style. + + Convert to "aic7xxx_osm.h". + + Add support for attachment of devices found after + the initial probe during "aic7xxx_detect". We do + this by setting a global, aic7xxx_detect_complete, + which tells the pci probe code to do its own registration + call if initial detection has already occurred. This way, + we maintain the "sane ordering" of devices that the + old driver had for statically configured devices. + + Split out the host registration code into its own function + so that hot-plug devices can call this code after + aic7xxx_detect has already completed. + + Use request/release_mem_region on 2.4.0 or higher kernels. + + Restore SCBPTR after setting up an abort for a + disconnected SCB. The sequencer will become confused + if this is not done. + + Always look for the SCB that timedout first and result to + a more generic search only if that fails. The timedout SCB + is more likely to be the one on the bus. + + Don't bother to drop and reaquire our mutex at the tail + of the recovery handler unless we are going to sleep. + + aic7xxx_osm.h: + Comment cleanup. + + Export our SCSI host template so the hot-plug PCI stuff + can use it. + + Bump revision to 6.1.0... our first release. + + aic7xxx_osm_pci.c: + Add support for new PCI probe mechanism in 2.4.0 while + maintaining compatibility with older kernels. + + aic7xxx_proc.c: + Fix several bugs in Gerard's proc code. We would never + properly deal with reads at offsets other than 0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#50 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#39 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#6 edit + +Change 132 by gibbs@overdrive on 2001/01/28 15:32:59 + + aic7770.c: + aic7xxx.c: + aic7xxx_93cx6.c: + Convert to "aic7xxx_osm.h" setup rather than ifdef hell. + + aic7xxx_pci.c: + Document the layout of the DEVID for cards with the 9005 + Adaptec vendor ID. Use a more generic mask for the generic + 9005 product tests. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#27 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#7 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#14 edit + +Change 131 by gibbs@overdrive on 2001/01/23 15:29:46 + + When flipping the first entry in the qinfifo with the + "next queued SCB", we must also inform the card of this + change. Otherwise the sequencer will traverse a corrupt + list of SCBS. The side effects of this problem were unknown + SCBs completing in the qoutfifo or worse yet, panics due + to sequencer interrupts that referenced what, to the kernel, + were invalid SCB ids. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#26 edit + +Change 130 by gibbs@overdrive on 2001/01/22 17:44:12 + + Update copyrights. + + aic7xxx.seq: + Handle busfree early in selection correctly. We + must clear ENSELO so that we will make future attempts + at selection. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#25 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#18 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#17 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#13 edit + +Change 129 by gibbs@overdrive on 2001/01/22 17:03:07 + + Bump revision level. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#38 edit + +Change 128 by gibbs@overdrive on 2001/01/19 16:09:10 + + Bump version number. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#37 edit + +Change 127 by gibbs@overdrive on 2001/01/19 15:57:40 + + It's Adaptec Inc., not just Adaptec. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#2 edit + +Change 126 by gibbs@overdrive on 2001/01/19 15:57:16 + + Correct a typo. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#4 edit + +Change 125 by gibbs@overdrive on 2001/01/19 10:35:11 + + aic7xxx.c: + Remove aic7895 stack corruption work-around. + This seems to only apply if you are mucking + with the stack register to effect a "long-jump". + We don't do this and don't plan to either. + + Add additional diagnostic output for when things + go wrong. + + AHC_SCB_BTT is set in the flags area of the softc, + not features. + + Don't loop forever if the INTSTAT register gets + locked up when flushing work. This can happen if + we are a removable device (register goes away) or + the card dies. + + aic7xxx.h: + Add a removable feature designation to ahc_features. + This is currently only used for the apa1480 and the 29160C. + + aic7xxx.reg: + Don't use the sequencer intcode 0xF0. It makes it possible + for the kernel to see INTSTAT as 0xFF and believe a hot-eject + has occurred. + + Align the busy target table on a 16byte boundary. This + appears to correct a sequencer execution issue for the + 7895. + + aic7xxx.seq: + Don't bother performing a "diagnostic" sequencer interupt + should an abort collision occur. + + Have the bus-free after selection code apply to + reselections too. + + Always follow the clearing of SELDI with a jmp instruction. + This corrects a sequencer execution issue on the 7895. + + In the target mode command loop, don't bother re-enabling + SPIOEN for each byte. It only needs to be enabled once. + + Fix AHC_SCB_BTT tests to test the correct field in the softc. + + Correctly clean up resources should an incoming reselection + reference a transaction we don't believe is pending. Add + some additional sequencer diagnostics for the SCB_BTT case + too. + + aic7xxx_inline.h: + Fix AHC_SCB_BTT tests to test the correct field in the softc. + + Only believe a hot eject to have occurred if the device + is removable. + + aic7xxx_pci.c: + Set the removable feature for the apa1480 and 29160C. + + Don't print information about high byte termination on + narrow adapters. + + Use a pci bus read instead of a questionable read for + safety when manipulating external termination logic. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#24 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#17 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#16 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#12 edit + +Change 124 by gibbs@overdrive on 2001/01/15 05:12:30 + + aic7770_osm.c: + Whitespace cleanup. + + Don't reference a NULL pointer. + + aic7xxx_osm.c: + Honor kernel configuration settings for bus + settle delay and max tagged commands. + + Correct accuracy of tagged command setup comments. + + Limit linux to 253 total commands due to command + complete FIFO cleanup restrictions. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#49 edit + +Change 123 by gibbs@overdrive on 2001/01/12 09:08:27 + + aic7770.c: + Add softcs for new EISA instances into the global list + of aic7xxx controllers as they are found. Leaving the + softcs out of the list prevented these controller instances + from being attached. + + aic7xxx.c: + Remove code that corrected for a state that cannot occur. + The sequencer now increments its position in the qinfifo + only once it has successfully DMAed the SCB from that queue + position down to the controller. In the past the sequencer + incremented before attempting the DMA. + + To ensure that the sequencer always notices an abort + collision, swap the first entry in the qinfifo with + the held, next to dma, hscb only after we have completed + our pass through the array. In the past, we did this + before clearing out the queue, and this did not provide + the same guarantee since the queue could be cleared leaving + the next pointer to be the same as it was originally. + + Print out the next queued SCB as seen by both the kernel + and the sequencer in ahc_dump_card_state(). + + aic7xxx.h: + Introduce a new constant, AHC_MAX_QUEUE. This is now set + to 253 to make sure that our 32bit writes to clear the + qoutfifo can never clobber a valid entry in the queue. + All OSMs should use this new define to throttle their + controller wide queue depth. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#23 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#16 edit + +Change 122 by gibbs@overdrive on 2001/01/08 11:32:55 + + Kill old insqueue interface. It will not be used by the + aic7xxx driver. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#4 edit + +Change 121 by gibbs@overdrive on 2001/01/08 11:30:36 + + Reduce the university's copyright per Kirk. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#3 edit + +Change 120 by gibbs@overdrive on 2001/01/08 11:27:30 + + Bump version number for next release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#36 edit + +Change 119 by gibbs@overdrive on 2001/01/08 11:20:17 + + Turn on ID expansion. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#3 edit + +Change 118 by gibbs@overdrive on 2001/01/08 08:10:19 + + aic7xxx_osm.c: + Honor selection timeout settings set by the user. + + Style cleanup of initial setup routine. + + Use sense buffer access inlines. + + Check for critical underflow only if there are no + other errors reported at the time the command is ahc_done()'d. + In the past, we might have marked the command as critically + failed before retrieving sense. Sense data should take + priority. + + aic7xxx_osm.h: + Second part of underflow cleanup. Just store the residual + in ahc_set_residual(). Leave policy decision to ahc_done(). + + aic7xxx_proc.c: + Add per-device statistics to proc output. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#48 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#35 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#5 edit + +Change 117 by gibbs@overdrive on 2001/01/08 08:03:54 + + aic7xxx.c: + Use inline accessors to get to the sense buffer associated + with a particular auto-sense transaction. This buffer is + now indexed by scb offset, not hscb offset, so any qinfifo + manipulations will not effect the buffer referenced. + + Honor the selection timeout setting in ahc_softc. The + OSM is responsible for setting this to any non-default + value. + + Modify our suspend and resume routines to take into account + twin channel adapters. + + aic7xxx.h: + Add fields for twin channel suspend state storage and + selection timeout timer to ahc_softc. + + aic7xxx_inline.h: + Inline accessors for sense buffer bus address and buffer. + + aic7xxx_pci.c: + Correct subdevice id data extraction routines to work + correctly on motherboard devices. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#22 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#13 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#11 edit + +Change 116 by gibbs@overdrive on 2000/12/21 09:22:20 + + Makefile: + Generate module in SCSI directory so it can be + named just like its predecessor. + + aic7xxx_osm.c: + Fix semaphore declarations for newer kernels. + + Use new ahc_* byte order functions. + + Cleanup some unused code. + + Implement platform_flush_work. + + aic7xxx_osm.hosts.h: + Split out our host template definition so we don't + muck up the namespace when our template is included + in hosts.c + + aic7xxx_inline.h: + Define ahc_endian functions. + + Bump version number. + + aic7xxx_proc.c: + First stab at /proc support. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#47 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#34 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#4 edit + +Change 115 by gibbs@overdrive on 2000/12/21 08:59:37 + + Add untested support for big endian machines. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#21 edit + +Change 114 by gibbs@overdrive on 2000/12/13 08:00:07 + + Bring in the optimized interrupts handler. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#12 edit + +Change 113 by gibbs@overdrive on 2000/12/13 07:57:15 + + aic7xxx_osm.c: + Use a semaphore and a timer to cause our exception + handler to sleep while recovery actions are in progress. + + Mark the correct recovery type in the SCB instead of + always marking DEVICE_RESET. + + aic7xxx_osm.h: + We are now at 6.0.6 BETA. + + Use a simple "do/while" construct to serve as a + memory barier on ia32. lock instructions are + expensive and all we need is something to prevent + the compiler from reordering our store order. + + aic7xxx_pci.c: + Turn off either I/O or Mem access depending on which + mapping type is not in use. This prevents our EISA + probe from kicking one of our cards. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#46 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#33 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#12 edit + +Change 112 by gibbs@overdrive on 2000/12/13 07:39:03 + + Complete preliminary resume support. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#20 edit + +Change 111 by gibbs@overdrive on 2000/12/12 12:09:54 + + aic7xxx.c: + During initialization, be sure to initialize all scratch + ram locations before they are read to avoid parity errors. + In this case, we use a new function, ahc_unbusy_tcl() to + initialize the scratch ram busy target table. + + Replace instances of ahc_index_busy_tcl() used to unbusy + a tcl without looking at the old value with ahc_unbusy_tcl(). + + Modify ahc_sent_msg so that it can find single byte messages. + ahc_sent_msg is now used to determine if a transfer negotiation + attempt resulted in a bus free. + + Be more careful in filtering out only the SCSI interrupts + of interest in ahc_handle_scsiint. + + Rearrange interrupt clearing code to ensure that at least + one PCI transaction occurrs after hitting CLRSINT1 and + writting to CLRINT. CLRSINT1 writes take a bit to + take effect, and the re-arrangement provides sufficient + delay to ensure the write to CLRINT is effective. + + export ahc-update_target_msg_request for use by OSM code. + + If a target does not respond to our ATN request, clear + it once we move to a non-message phase. This avoids + sending a MSG_NOOP in some later message out phase. + + Use max lun and max target constants instead of + hard-coded values. + + Use softc storage built into our device_t under FreeBSD. + + Fix a bug in ahc_free() that caused us to delete + resources that were not allocated. + + Clean up any tstate/lstate info in ahc_free(). + + Clear the powerdown state in ahc_reset() so that + registers can be accessed. + + Add a preliminary function for pausing the chip and + processing any posted work. + + Add a preliminary suspend and resume functions. + + aic7xxx.h: + Limit the number of supported luns to 64. We don't + support information unit transfers, so this is the + maximum that makes sense for these chips. + + Add a new flag AHC_ALL_INTERRUPTS that forces the + processing of all interrupt state in a single invokation + of ahc_intr(). When the flag is not set, we use the + lazy interrupt handling scheme. + + Add data structures to store controller state while + we are suspended. + + Use constants instead of hard coded values where appropriate. + + Correct some harmless "unsigned/signed" conflicts. + + aic7xxx.seq: + Only perform the SCSIBUSL fix on ULTRA2 or newer controllers. + Older controllers seem to be confused by this. + + In target mode, ignore PHASEMIS during data phases. + This bit seems to be flakey on U160 controllers acting + in target mode. + + aic7xxx_pci.c: + Add support for the 29160C CPCI adapter. + + Add definitions for subvendor ID information + available for devices with the "9005" vendor id. + We currently use this information to determine + if a multi-function device doesn't have the second + channel hooked up on a board. + + Add rudimentary power mode code so we can put the + controller into the D0 state. + + Only capture "left over BIOS state" if the POWRDN + setting is not set in HCNTRL. + + In target mode, don't bother sending incremental + CRC data. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#19 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#10 edit + +Change 110 by gibbs@overdrive on 2000/12/01 09:43:59 + + When bus resets are disabled, call update_target_msgreq after + setting initial transfer settings so that negotiation takes place + on the first command to the target. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#45 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#32 edit + +Change 109 by gibbs@overdrive on 2000/11/10 09:37:15 + + Add IOMODE support. + + Remove recurring interrupts during scsi bus resets by + disabling scsi bus reset notifications until we start + sending or receiving transactions again. + + Issue a missed busfree sequencer interrupt instead of + overloading bad phase. The code was getting confused + before because last phase was not set in all cases + to distinguish the two cases. + + Don't assume the SCB tag is valid unless SEEN_IDENTIFY + is set in SEQ_FLAGS during timeout handling. + + Add critical sections to protect the sequencer from list + corruption during timeout handling. + + Sync with FreeBSD IDs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#18 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#13 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#9 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#9 edit + +Change 108 by gibbs@overdrive on 2000/11/10 09:33:33 + + Bump version for next release. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#31 edit + +Change 107 by gibbs@overdrive on 2000/11/06 09:36:35 + + The core driver takes care to clean up any doubly queued SCBs + now, so don't call ahc_search_qinfifo from ahc_done(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#44 edit + +Change 106 by gibbs@overdrive on 2000/11/06 09:35:50 + + Fix 8bit math errors when tweaking the qinfifo. + + Don't allow ahc_search_qinfifo to be called recursively. + + Use a subroutine to make sure we don't coast into any + important sequencer instructions when issuing a pausing + interrupt. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#17 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#13 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#10 edit + +Change 105 by gibbs@overdrive on 2000/11/01 12:01:08 + + Linux EISA support, support for 2.4.X kernels, and updates to + match changes in the core aic7xxx code. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#43 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#30 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#11 edit + +Change 104 by gibbs@overdrive on 2000/11/01 11:59:42 + + Too many changes to mention. Lots of bug fixes. Filtering of + incoming transfer negotiation messages based on user settings, + bmov instruction for all moves, additional debugging code, etc. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.c#16 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#7 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#9 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#8 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#6 edit + +Change 103 by gibbs@overdrive on 2000/10/13 10:01:42 + + aic7xxx.c: + Limit our sync period correctly based on tinfo data. + We now send a period of 0 if we want async. + + Fix problem with DMA'ed CDBs. The pointer to the + physical cdb was not being setup properly during + the HSCB swap. We now compute this value in + ahc_setup_scb(). + + aic7xxx.seq: + Make sure that DFON stays on in SXFRCTL0. + + Fix DMA'ed cdbs for adapters without a command channel. + The length in HCNT was not properly set. + + Clear STCNT on U2 controllers when we exit command + phase. This is an attempt to clear the preload circuit. + It is not yet clear that this works. + + aic7xxx_inline.h: + Copy the whole 64 bytes of the hscb when queuing it. + If we need to recalculate the cdb physical pointer for + a large cdb, do so at this time as well. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#15 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#11 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#8 edit + +Change 102 by gibbs@overdrive on 2000/10/12 11:12:41 + + Make the no_reset option work and also honor the seeprom/nvram + reset options at boot time. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#42 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#29 edit + +Change 101 by gibbs@overdrive on 2000/10/12 10:00:34 + + Update for changes in aic7xxx core files: UNTAGGED_Q flag, + ahc_validate*() now take a tinfo. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#41 edit + +Change 100 by gibbs@overdrive on 2000/10/12 09:59:11 + + Limit transfer settings to that of our goal at all times. This + ensures that a target initiated sync/wide negotiation never goes + above the limits specified by the user. + + When switching to non-tagged queuing, be sure to set the + SCB_UNTAGGEDQ flag when inserting the SCB onto the untagged q. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#14 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#10 edit + +Change 99 by gibbs@overdrive on 2000/10/09 11:21:46 + + Remove AIC7XXX_STRICT_PCI_SETUP. We don't currently honor it + and don't have a reason to honor it in the future. + + Handle temporary resource shortages such as an attempt to allocate + additional SCBs failing. + + Complete the first pass at Linux error recovery code. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#40 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#28 edit + +Change 98 by gibbs@overdrive on 2000/10/09 11:17:46 + + Export ahc_match_scb() to OSMs. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#13 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#9 edit + +Change 97 by gibbs@overdrive on 2000/10/09 07:49:38 + + aic7xxx.c: + export ahc_qinfifo_requeue and a new routine + ahc_qinfifo_count for use by OSM error recovery + routines. + + Resync the tqinfifo position during every restart of + the sequencer. In the past, we would do this only + for bus resets but there are other situations where + restarting the sequencer might cause a discrepency. + + Print the scb's path information before running an + abort command that will include that scb. There is + no guarantee that the path information will be valid + after an SCB is freed. + + In ahc_clear_critical_sections(), disable all SCSIINT + interrupt sources and clear SCSIINT. SCSIINT is a pausing + interrupt and the sequencer will not step if it is paused + by an interrupt condition. Any SCSIINT sourc that is + active prior to or becomes active during the stepping + process will cause SCSIINT to be re-asserted when we + re-enable these interrupt sources at the tail of + ahc_clear_critical_sections(). + + Send the correct async notifications for BDR and bus reset. + + Fix an error in ahc_search_qinfifo() that would update + QINFIFO at the wrong time. + + In ahc_loadseq, properly calculate the critical section + regions for the current firmware load. The old code was + confused if a critical sections boundary occurred on + an instruction not downloaded to the chip. + + aic7xxx.h: + Remove an unused SCB_FLAG. + + Export ahc_qinfifo_requeue() and ahc_qinfifo_count(). + + aic7xxx.seq: + The MK_MESSAGE flag is cleared by the kernel. Don't + bother duplicating that effort in the sequencer. + + aic7xxx_pci.c: + 7880's prior to rev B have the MWI boundary bug. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#12 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#7 edit + +Change 96 by gibbs@overdrive on 2000/10/06 06:40:57 + + Convert to keeping a queue of Scsi_Cmnd structures instead of SCBs. + This will allow us to queue domain validation and other requests + internally to the driver without fear of an SCB shortage related + deadlock. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#39 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#27 edit + +Change 95 by gibbs@overdrive on 2000/10/06 06:39:42 + + Simplify ahc_update_pending_syncrates(). + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#11 edit + +Change 94 by gibbs@overdrive on 2000/10/06 06:19:23 + + Update FreeBSD ids. + + Move verbose logging of negotiation into the *construct* methods + so that logging occurs in all cases. + + Correct ahc_search_qinfifo to properly deal with an SCB out of + the qinfifo but mid-dma in the SEARCH_REMOVE case. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#10 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#7 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#9 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#7 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#6 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#6 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#5 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#4 edit + +Change 93 by gibbs@overdrive on 2000/10/03 11:11:11 + + Fix non-module build on 2.2.14. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#38 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#26 edit + +Change 92 by gibbs@overdrive on 2000/10/03 11:10:45 + + aic7xxx.c: + panic with a reasonable message if we do not have a valid + SCB when handling a HOST_MSG_LOOP event. + + Clear any critical sections when a bus reset or any unexpected + SCSI event occurs. + + Fix an off by one in testing whether we are inside a + critical section. + + Set the step bit in the correct register. + + Also check whether the PPR options have changed when + deciding to update our syncrate. + + Add some bootverbose logging about transfer negotiations. + + If we are going to reject a PPR, explicitly set all options + to async/narrow. It may be that only one of the many options + was filtered to an unacceptable value. + + Have the ahc_search_qinfifo routing properly handle the + case where an SCB has left the qinfifo but has not yet + been added to the waiting list. + + aic7xxx.seq: + Correct critical sections for input queue handling. + + Fix a bug in input queue handling that caused us to + smash the next scb to download value as we were putting + the new SCB onto the waiting list. + + If the qinfifo changes to not include the just DMAed + SCB, throw it away... it has been aborted by the kernel. + + aic7xxx_inline.h: + Simplify a statement. No fucntional change. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#9 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#6 edit + +Change 91 by gibbs@overdrive on 2000/09/28 10:59:15 + + Limit prefetch to a PCI cacheline amount instead of pulling + a full (and expensive) 128 bytes. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#8 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#7 edit + +Change 90 by gibbs@overdrive on 2000/09/28 10:31:17 + + Make sure we tell the OS that we can only take 254 or + AHC_SCB_MAX - 1 requests at a time due to the new QINFIFO + scheme. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#37 edit + +Change 89 by gibbs@overdrive on 2000/09/28 10:30:48 + + Correct ahc_search_qinfifo by reading and resetting the + SNSCB_QOFF register. A read of this register increments it, + requiring the reset. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#7 edit + +Change 88 by gibbs@overdrive on 2000/09/28 09:24:14 + + Use an array of scb pointers to map from HSCB tag to + SCB. + + Take a first shot at correcting ahc_search_qinfifo for the + new qinfifo mechanism. We don't currently handle the case + of an SCB in transit to the card after it has been removed + from the QINFIFO. + + There still appears to be a problem with the QINFIFO handling + that I have yet to address. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#6 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#5 edit + +Change 87 by gibbs@overdrive on 2000/09/27 09:03:56 + + Put the Linux aic7770 support into its final location. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_eisa.c#3 delete + +Change 86 by gibbs@overdrive on 2000/09/27 09:03:16 + + Implement new, single DMA, strategy for getting commands to + the controller. + + Still need to implement qinfifo cleanup routine. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#5 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#4 edit + +Change 85 by gibbs@overdrive on 2000/09/27 09:02:01 + + Clean up code formating so extraineous commas are not + generated. + + Output a constant indicating the size of the critical + section table. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#5 edit + +Change 84 by gibbs@overdrive on 2000/09/27 08:58:38 + + Switch to only allowing 254 commands outstanding in preparation + for new input queue handling. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#36 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#25 edit + +Change 83 by gibbs@overdrive on 2000/09/25 08:40:23 + + aic7xxx_osm.c: + Correct a KERNEL_VERSION test. + + Reset the bus only after we've finished setting + up the controller fully. + + Update for new ahc_send_async() API. + + Only attempt to report bus resets if the kernel + we're building for supports it. + + aic7xxx_osm.h: + Bump driver version in preparation for next release. + + Fix compilation on older kernels. The Scsi_Cmnd is now + available through the scb->io_ctx. + + Update for new ahc_send_async() API. + + aic7xxx_osm_pci.c: + Correctly handle the I/O mapped case. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#35 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#10 edit + +Change 82 by gibbs@overdrive on 2000/09/25 08:35:25 + + Rely on CACHETHEN bug entries to limit its use. Otherwise, + default to turning it on. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#5 edit + +Change 81 by gibbs@overdrive on 2000/09/22 07:55:30 + + aic7xxx.c: + Clear scsi interrupts via the CLRINT register if we + see a spurios SCSI interrupt. + + Modify the ahc_send_async interface so that the client + can directly specify which devices (through the use of + wildcards) are affected. + + When sending a PPR message we need to filter the syncrate + we attempt to negotiate with the target just as when using + the older SDTR message. Combine these two cases so we can + share the code that does this. + + Correct a panic message. + + Handle a MSG_MESSAGE_REJ for a PPR request. Simplify the + ahc_handle_msg_reject routine by calling + ahc_build_transfer_msg in cases where further negotiation + is required rather than doing this manually. + + In ahc_controller_info(), don't bother updating len and + buf for the last sprintf since no-one will look at them + again. + + aic7xxx.h: + Increase the size of both msgout_buf and msgin_buf[]. + The PPR message is 8 bytes in length and we might + (on some platforms) combine the PPR with inquiry and + tag data. We now allocate 12 bytes in each. + + aic7xxx.seq: + Use quoted includes in the sequencer file and make up + for the lack of path information in some OS dependent + manner (sys/conf/files for FreeBSD, placement of files + in Linux). The assembler doesn't understand #ifdef + directives and this allows the files to be completely + shared between platforms. + + Remove an unnecessary nop instruction. + + aic7xxx_pci.c: + In ahc_pci_intr(), look at the error register to + determine whether a PCI error has occurred before + rushing into a configuration cycle to read the error. + Configuration cycles are more expensive than a single + memory read transaction and we may end up thinking + we have a PCI interrupt waiting just because we share + an IRQ with other devices. + + unpause the sequencer after clearing any PCI status. + For some errors (such as received Master Abort), the + error had nothing to do with this controller, but the + chip was automatically paused. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#4 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#4 edit + +Change 80 by gibbs@overdrive on 2000/09/19 09:20:44 + + Add ahc_send_async() for Linux and have it report bus resets. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#34 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#23 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#9 edit + +Change 79 by gibbs@overdrive on 2000/09/19 09:06:42 + + include inttypes.h. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#4 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#4 edit + +Change 78 by gibbs@overdrive on 2000/09/19 08:43:13 + + Bring back the Linux Makefile for the assembler. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#4 add + +Change 77 by gibbs@overdrive on 2000/09/19 08:15:07 + + Bring in latest FreeBSD port changes. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7770.c#1 add +... //depot/aic7xxx/aic7xxx/aic7xxx.c#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#3 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#3 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#3 edit + +Change 76 by gibbs@overdrive on 2000/09/19 07:24:37 + + Make sure these all have RCS ID expansion enabled. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.h#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#2 edit +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#2 edit +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#2 edit + +Change 75 by gibbs@overdrive on 2000/09/19 07:21:44 + + Move core files to core location in the repository. + +Affected files ... + +... //depot/aic7xxx/aic7xxx/aic7xxx.c#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx.h#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx.reg#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx.seq#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#1 branch +... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#1 branch +... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#25 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#12 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.reg#5 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#12 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#4 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_eisa.c#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#10 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#7 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.c#5 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.h#4 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#7 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#2 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#5 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#4 delete + +Change 74 by gibbs@overdrive on 2000/09/12 11:57:59 + + Cleanup and changes to support FreeBSD + + aic7xxx.c: + FreeBSD includes. FreeBSD uses -nostdinc so + we must explicitly state the path to any referenced + files. + + staticize + + Inline ahc_intr(). It is only referenced once by + the OSM. + + Call ahc_notify_xfer_settings_change() in all locations + where settings change. + + Simplify ahc_platform_set_tags. Don't bother calling + it if the tags setting has not changed. + + Don't leak ahc->name() in ahc_free(). + + Add functions used only for target mode. + + pci_softc -> dev_softc. + + Move FreeBSD specific calls into aic7xxx_freebsd.c. + + Add marker to cleanup tstate info in ahc_free(). + + Bring back SEARCH_REMOVE to ahc_search_qinfifo(). + The FreeBSD error recovery code uses it. + + aic7xxx.h: + Add the io_ctx field into the scb. This represents a + pointer to the ccb or Scsi_Cmnd or whatever a platform + uses to keep track of the OSes io context. This is + faster and simpler than rooting around in the scb_platform + data object. + + Bring back in more target mode stuff. + + ahc_pci_softc_t -> ahc_dev_softc_t. + + inline ahc_intr. + + export functions referenced by FreeBSD's error recovery code. + + aic7xxx_93cx6.c: + FreeBSD inludes. + + aic7xxx_inline.h: + Inline ahc_intr. + + aic7xxx_osm.c: + Cleanup unused and #if 0'd code. + + platform_data->cmd -> io_ctx. + + ahc->pci_softc -> ahc->dev_softc. + + Cleanup unused (or should have been unused) fields + in ahc_platform_softc. + + ahc_platform_set_tags() simplification. Changed argument + goes away and the function is only called when the + tags setting changes. + + aic7xxx_osm.h: + Cleanup unused and #if 0'd code. + + Add ahc_insb() for use by ahc_dump_seq(). + + pci_softc -> dev_softc. + + platform_data->cmd -> io_ctx. + + aic7xxx_osm_pci.c: + pci_softc -> dev_softc. + + aic7xxx_pci.c: + FreeBSD includes + + pci_softc -> dev_softc. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#33 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#22 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#6 edit + +Change 72 by gibbs@overdrive on 2000/09/07 10:47:56 + + aic7xxx.c: + TAILQ_FOREACH is not safe to use when the list you + are traversing is modified in the body of the loop. + Manually traverse the list instead. + + aic7xxx_osm.h: + aic7xxx_osm.c: + Avoid re-entry issues during abort processing by + deferring the run of any device queues until after + ahc_intr() has completed. Just as in the case of + running the complete queue, the device queues will + need to be run from any abort processing performed + outside the interrupt handler as well. + + Bump our version number in preparation for another release. + + cam.h: + Make get and set transaction status work the same way as + in FreeBSD. Notably, mask with CAM_STATUS_MASK. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#23 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#32 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#8 edit + +Change 68 by gibbs@overdrive on 2000/09/06 10:25:15 + + aic7xxx.c: + Start the port back to FreeBSD.... + o Include FreeBSD header on FreeBSD + + o ahc_freeze_ccb -> ahc_freeze_scb() and unifdef. + + o Change XXX to __FreeBSD__ on sections of code + we still need additional special accessors for. + + o Bring in the rest of the target mode code. + + Move the pci_softc from platform_data into its own + field in ahc_softc. This makes it less cumbersome + to perform PCI operations. + + Add a routine, ahc_dump_card_state, that dumps the + state of all of our queues. This can be called when + something unexpected occurs to aid in debugging problems. + It is currently only called when we see an inactive + SCB come through ahc_done(). + + aic7xxx.h: + struct ahc_pci_softc -> ahc_pci_softc_t. + On both Linux and FreeBSD, the pci_softc need only + be a pointer to the platform provided PCI instance + object, so we let the OSM define this type to be + whatever is convenient. + + Add bug definition for SCB corruption on upload + with aic7899s on 66MHz PCI. + + Use bus space tag/handle pair for accessing the + card on all platforms. This removes an extra + pointer dereference and matches what FreeBSD + has been doing for some time. + + Move the platform_softc lower in the ahc_softc. + Since it no-longer includes the fields required + to access card registers, it is accessed less often + than the fields that now appear before it. + + aic7xxx.seq: + Implement a workaround for the 66MHz PCI SCB upload + corruption problem. By transferring first from the + SCB into SCBRAM and then performing the DMA, we + avoid the corruption. + + aic7xxx_osm.c: + ahc_pci_softc_t fallout. + + bus space fallout. + + Implement the platform dependant portions of + ahc_dump_card_state(). + + Fix a nasty bug in ahc_run_device_queue(). We + cannot send any SCB that does not have CAM_SIM_QUEUED + set to the card or it will get sent twice. Once + by the queue run routine and again by aic7xxx_queue(). + + aic7xxx_osm.h: + Implement bus space fields for PIO/MEMIO. + + struct ahc_pci_softc -> ahc_pci_softc_t + + Implement ahc_freeze_scb() which is a no-op on Linux. + + aic7xxx_osm_pci.c: + ahc_pci_softc_t fallout. + + bus space fallout. + + aic7xxx_pci.c: + ahc_pci_softc_t fallout. + + aicasm_symbol.c: + Pick up the correct db header on non-linux platforms. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#11 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#31 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#2 edit + +Change 64 by gibbs@overdrive on 2000/09/02 12:46:16 + + aic7xxx.c: + Add a chip name for the aic7895 Rev C. We differentiate + between the C and all other revs, so it is best to report + explicitly to the user when we find this chip. + + Export ahc_print_scb(); + + In restart_sequencer() do all of the things that the + sequencer used to do at startup. This shaves quite + a few instructions and there is no reason to "optimize" + these steps as they happen very rarely. + + Add some useful TRACEPOINT code. + + Use SCB_BASE instead of SCB_CONTROL to reference the + start of SCB ram. SCB_CONTROL is no longer the first + element in the SCB and this show why using a variable + location instead of a fixed constant is unwise. + + Explictily export controller information + (width, scsiid, number of SCBS, etc) via + ahc_controller_info() instead of spraying this + data out from all through ahc_init(). This + allows OSMs to display the data in any way + they see fit. + + Correct some SCB_BTT bugs. + + Size the downloaded constants table correctly. + + aic7xxx.h: + Give the aic7895C isn't own chip identifier. + + Note which controllers have the AUTOPAUSE feature. + + Add a bug entry for controllers that fail to handle + residual transfers after a PCI MWI transaction correctly. + + Move the status packet up to the top of the SCB in + preparation for shortening the number of bytes uploaded + during check condition and other errors. + + Store in our softc information about the pci cacheline size. + + aic7xxx.reg: + Move the SCB status packet up to the top of the SCB. + + Add a different download size for external SCB memory. + This appears to avoid a download corruption problem. + + Add the MWI_RESIDUAL field for the MWI sequencer workaround. + + Add a downloaded constants describing the PCI cachline size. + + aic7xxx.seq: + Move reset code into kernel space. + + Add MWI bug workaround. Essentially we save off the + portion of the current S/G segment that goes beyond the + last cacheline and transfer this separately. + + Use SCB_BASE instead of SCB_CONTROL for referencing the + start of SCB space. + + Add a workaround for transferring an embedded CDB from + external scratch ram on the aic7895. We must wait to + enable the DMA engine until after we have filled the + FIFO. + + Fix index_busy_target in the SCB_BTT case. + + Factor out some more code that is not needed when + we don't page SCBs. + + Replace explicit test against aic7895 in command channel + code with != ULTRA2. This gives the same effect and + doesn't require us to also check to see if this is an aic7895C. + + If we have large external SCBs, download 48 bytes of + SCB instead of 32. This appears to avoid an SCB + corruption problem. + + Solidify the PCI 2.1 retry problem on SCB dma operations + bug. We now wait until we are sure the chip is hung + before touching the FIFO. The old system seemed to + sometimes pull out data too soon or corrupt the + data. + + aic7xxx_inline.h: + Only explicitly pause the sequencer on command enqueue + operations if the chip does not have the auto-pause + feature or the queue registers feature. + + aic7xxx_osm.c: + Fix the number of trasactions we report as supporting + to the mid layer. Also fix our max opening count. + It was possible to overrun the FIFOs if we were using + the SCB busy target table. + + Provide more controller information through aic7xxx_info() + via the ahc_controller_info() routine. + + aic7xxx_osm.h: + More "number of transactions" cleanups. + + Our per-device active and openings count must be + signed so we can properly reduce our opening count + when downgrading from tagged to untagged. + + Add a bit definition for the memory write and invalidate + enable PCI space bit. + + Provide more information to the user on underflow conditions. + + aic7xxx_pci.c: + Clean up the way that large SCBs are enabled. This is + now only done in the ahc_probe_extscbs() routine. + + Fetch PCI cache line size information and put it in the + softc. + + Correct the seletion of large SCBs for Ultra2+ controllers + in the SCB config routine. + + If external SCBs are not present, run through the SCB + config routine with the default settings. This avoids + having to put code to attain the defaults somewhere + else. + + Correct SCB_BTT feature enable logic. We must have + external 64byte SCBs for this to work. + + If bootverbose, mention whether large SCBs are being + used. + + SCB_CONTROL->SCB_BASE. + + Output the Sequencer program address if we get a PCI + error. Useful in debugging. + + Note which controllers require MWI workarounds. + + Differentiate even more between the aic7895 and aic7895C. + Add code to deal the the spurious DAC cycle problem, + but don't enable it just yet. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.reg#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#30 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#4 edit + +Change 62 by gibbs@overdrive on 2000/08/29 05:51:37 + + Move to just a single driver version stored in aic7xxx_osm.h. + Cleanup information printed out at driver load time. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#29 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#18 edit + +Change 61 by gibbs@overdrive on 2000/08/29 05:46:33 + + aic7xxx.seq: + Be a little more careful in how we empty the FIFO + on PCI 2.1 compliant aic78XX chips. After pulling + out 8 bytes, wait for the FIFO to get some data + before testing to see if we are hung. + + aic7xxx_osm.c: + Fix the abort collision case in the device queue by + setting CAM_SIM_QUEUED only once aic7xxx_queue() has + released ownership of the SCB. The old code was somewhat + confused in how it flagged transactions as still being + owned by aic7xxx_queue(). + + Revert ahc_queue_busy_scb() and instead implement a + roll_back function ahc_free_busy_scb(). This makes + it much clearer who is aborting which scbs and how. + This required implementing ahc_unmap_scb() for use + by both ahc_done() and ahc_free_busy_scb(). + + Correct ahc_platform_abort_scbs to abort the correct + device. It was not checking wide/twin controller + properties and also suffered from a cut 'n paste error + that corrupted how the luns to traverse were determined. + + aic7xxx_osm.h: + Only return the low byte of the transaction status to + the rest of the world, but allow the high byte to be + set. This simplifies handling of the CAM_SIM_QUEUED + flag. + + cam.h: + Add the CAM_SIM_QUEUED flag. This flag is only used + in the device busy queue and indicates that the transaction + in the queue is no longer being operated on by aic7xxx_queue(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#28 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#7 edit + +Change 60 by gibbs@overdrive on 2000/08/24 12:12:57 + + Turn on ktext expansion for all files. + + Add $Id$ where appropriate. + + Add PCI 2.1 Retry bug workaround. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#19 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_eisa.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#27 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_eisa.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#3 edit + +Change 59 by gibbs@overdrive on 2000/08/22 08:26:27 + + Change the name of our controller to scsi%d once we know the host + number. Until that time, use a bus specific name. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#26 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#6 edit + +Change 58 by gibbs@overdrive on 2000/08/22 07:29:04 + + Remove old, #ifdef'd out, abort/reset implementations. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#25 edit + +Change 57 by gibbs@overdrive on 2000/08/22 07:20:46 + + Remove debugging printfs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#5 edit + +Change 56 by gibbs@overdrive on 2000/08/22 06:53:44 + + aic7xxx.c: + For no, leave all locking to OSM layer. + + aic7xxx_osm.c: + Correct Adaptec copyright. + + Conditionalize inclusion of linux/init.h + + Add proc_dir_entry for older kernels. + + Don't declare static, entry points that may be + called externally in a static kernel linkage + configuration. + + Fixup abort processing for entries in the dev + queue. We first bring these transactions up + to a state where ahc_done() will work on them, + and then call ahc_done(). This ensures that + all mapped memory for the transaction, etc. is + released. + + Becareful not to overwrite the sense data buffer + in Scsi_Cmnd's. + + Guard against null host structures in aic7xxx_release. + + aic7xxx_osm.h: + Remove bogus status checking in ahc_set_transaction_status(). + + aic7xxx_osm_pci.c: + Use pci_find_class() to enumerate PCI devices. This should + work acceptably in all kernel versions we support. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#24 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#4 edit + +Change 54 by gibbs@overdrive on 2000/08/21 12:30:49 + + When aborting commands in our per-device queues, queue them + to the complete queue, thus avoiding the dead-lock of a direct + completion. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#23 edit + +Change 53 by gibbs@overdrive on 2000/08/21 09:50:38 + + Use DID_BUS_BUSY for CAM_REQUEUE_REQ. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#22 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#5 edit + +Change 52 by gibbs@overdrive on 2000/08/21 09:37:53 + + Implement aic7xxx_biosparam, finish tagged queuing implementation, + and complete the port to 2.2.14. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#21 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#14 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#4 edit + +Change 51 by gibbs@overdrive on 2000/08/12 10:40:14 + + aic7xxx.c: + Add a platform callback to notify the system when + tag settings change. We use this to freeze the + device queue until all oustanding transaction complete + when the tag type changes. + + aic7xxx_osm.c: + Add support for releasing the queue when the active + count goes to 0 for a particular device. + + Implement ahc_platform_set_tags() which will freeze + the queue when tag types change. + + In ahc_filter_cmd(), enable tags if the device supports them. + + aic7xxx_osm.h: + Prototype for ahc_platform_set_tags(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#20 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#13 edit + +Change 50 by gibbs@overdrive on 2000/08/12 10:10:26 + + Kill a diagnostic printf. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#19 edit + +Change 49 by gibbs@overdrive on 2000/08/12 10:06:51 + + Switch to queing SCBs not Linux scsi commands in our busy + queues. This avoids a locking and latency issues when we + have to run the queues from interrupt context. + + Run the busyq at the end of ahc_done. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#18 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#12 edit + +Change 48 by gibbs@overdrive on 2000/08/12 09:25:34 + + aic7xxx.c: + Add a platform callbacks for aborting transactions + sitting in OSM queues. + + aic7xxx_inline.h: + Don't lock in ahc_get_scb. Let the OSM do this + as it may need to lock other data structures (using + the same lock) around the time it aquires the SCB. + + aic7xxx_osm.c: + Implement Linux version of the transaction abort + callbacks. + + Modify ahc_get_device() to only allocate device + entries if asked. This allows this routine to + be used to see if a device exists at that location. + + Modify aic7xxx_queue() so that incoming commands + are placed into the device busy queue and that + transactions are only run if the device has + openings available and is not frozen. + + Check to see if a command has been aborted after + re-acquiring the ahc lock at the tail end of + aic7xxx_queue(). + + Modify ahc_alloc_device() to initialize the openings + and maxtags fields. + + aic7xxx_osm.h: + Add Adaptec Copyright. + + Add device fields required to handle tagged queuing. + + Add function prototypes for ahc_platform abort routines. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#17 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#11 edit + +Change 47 by gibbs@overdrive on 2000/08/12 07:00:10 + + Swith to using a union in ahc_cmd so we can avoid excessive + casting. + + Sort entries as they are inserted onto the completeq so that + transaction ordering for retried transactions is maintained. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#16 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#10 edit + +Change 46 by gibbs@overdrive on 2000/08/12 06:25:07 + + aic7xxx.c: + Remove some debugging printfs. + + Correctly deal with TWIN channel adapters when + dealing with the busy target table or busy target + queues. + + aic7xxx_osm.c: + Correct memset call in ahc_alloc_device() to + zero the correct nuber of bytes. + + aic7xxx_osm_pci.c: + Remove some debugging printfs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#14 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#15 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#2 edit + +Change 45 by gibbs@overdrive on 2000/08/11 09:20:01 + + Set scb->platform_data->dev in aic7xxx_queue(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#14 edit + +Change 44 by gibbs@overdrive on 2000/08/11 08:47:10 + + Correct addressing for per-device data-structures for + twin channel devices. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#9 edit + +Change 43 by gibbs@overdrive on 2000/08/11 08:40:12 + + aic7xxx.c: + Remove the "SEARCH_REMOVE" case from ahc_search_action. + It is never used and it would be hard to create sane + semantics for its use. + + scbp->scb to match most of the rest of the driver. + + In ahc_search_qinfifo(), handle the untagged queues + as well. To the rest of the system, these are just + another part of the input fifo. + + aic7xxx_osm.c: + Add Adaptec Inc. copyright. + + Add a mechanism for allocating and freeing a per-device + data-structure for queue and other management. The + data structure is persistent so long as commands for + that device are outstanding and/or we've seen a proper + inquiry response from that device that makes us believe + there is a persistent device at that location (target/lun). + + aic7xxx_osm.h: + Per-device data structure definitions. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#13 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#12 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#8 edit + +Change 42 by gibbs@overdrive on 2000/08/11 04:43:03 + + Initialize the completeq with STAILQ_INIT now that it is an + STAILQ. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#11 edit + +Change 41 by gibbs@overdrive on 2000/08/11 04:37:07 + + Use a shaddow structure of scsi_cmnd so we can name fields + "reserved" for HBA use however we wish. This lets us use + the queue macros for queuing these structures. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#10 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#7 edit + +Change 37 by gibbs@overdrive on 2000/08/10 08:07:55 + + aic7xxx.c: + aic7xxx.h: + Move more function declarations to global scope. + + aic7xxx_osm.c: + Implement a mechanism to sniff completed commands + that complete with good status. We use this to + sniff completed inquiry responses for targets to + determine there transfer capabilities. + + aic7xxx_osm.h: + Add a definition for the inquiry response format + for use by our transaction sniffer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#9 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#6 edit + +Change 36 by gibbs@overdrive on 2000/08/10 06:34:34 + + Spaces to tabs. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#8 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#8 edit + +Change 35 by gibbs@overdrive on 2000/08/10 05:33:22 + + aic7xxx.c: + Add ahc_busy_tcl(). This routine is used to add + an SCBID to the busy target's table. Right now this + is only used when transitioning a transaction from + tagged to untagged when a tag message is rejected. + + Move some function prototypes to aic7xxx.h for use + by other modules. + + Re-enable code that sets transaction status now that + we have an OSM method for doing this. + + Kill some debugging printfs. + + aic7xxx.h: + Added function prototypes for methods in aic7xxx.c + + aic7xxx.seq: + For added safety, when handling a data overrun, + clear STCNT before going into bit-bucket mode. + clearing STCNT should ensure that the data channel + will not resume a previous transfer setup via + PRELOADEN. + + aic7xxx_inline.h: + The controller lock is always held when a transaction is + freed. Don't bother re-acquiring it is ahc_free_scb(). + + Kill more diagnostic printfs. + + aic7xxx_osm.c: + Inline completion queue routines. + + Reset the bus on startup for now. Later we will honor + non-volatile card setting and if no reset is requested, + we will negotiate on the first transaction. + + Store a pointer to a scsi command's scb in the host_scribble + area while the command is outstanding. This allows us + to get back to the SCB from within the abort/reset routines. + + Check cmd->use_sg consistently. Even if only one SG is + provided, we must still treat the request_buffer pointer + as a pointer to a list of SG structures, not a contiguous + buffer. + + Fixup some bugs in how were were initializing SCBs in the + aic7xxx_queue routine. + + Keep track of pending SCBs in the pending_scb list. The + core routines in aic7xxx.c expect to find pending SCBS + here. + + Properly remove untagged transactions from the untagged + queue when they complete. + + Set transaction status to DID_OK (CAM_REQ_CMP) if, at + ahc_done time, the status is still CAM_REQ_INPROG. + + Add some diagnostic code to the abort routine so we + can determine why the mid-layer decided an abort was + necessary. + + aic7xxx_osm.h: + Make the ahc_done_lock a no-op on systems that use + interrupt blocking for locks. The softc lock is always + while the done lock is held, so no additional protection + is required. + + Add accessers for both the transaction and scsi status + fields. These are used by core code. + + cam.h: + Switch CAM_SEL_TIMEOUT from "DID_TIME_OUT" to + "DID_NO_CONNECT". This seems more correct based + on a quick look at scsi_error.c of the mid-layer. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#7 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#5 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#3 edit + +Change 32 by gibbs@overdrive on 2000/08/09 07:31:45 + + aic7xxx.c: + Remove duplicate OSM function ahc_scb_set_residual(). + We already had ahc_set_residual(). + + Use platform independent method for storing retrieved + sense data. + + aic7xxx_osm.c: + Add a deferred completion queue. The queue is filled + by ahc_done() and run from either our interrupt handler, + or error recovery routines after all commands are queued + for completion. + + Keep track of the size of our transfer. This is later + used in residual handling. + + Implement basic ahc_done() routine. This will need to + be enhanced to deal with things like queue full. + + aic7xxx_osm.h: + Implement the completeq. Due to the nature of the + scsi_cmnd structure, we cannot use a + style queue for this, so create a simple LIFO. + + Flesh out the inline accessors to OSM dependent + per transaction data fields. + + cam.h: + Map CAM status to Linux SCSI status codes. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#6 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#2 edit + +Change 31 by gibbs@overdrive on 2000/08/08 13:11:38 + + Debug adapter queue command path. We can now queue a command, + have the sequencer complete it, and route the compelted + command to ahc_done(). + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#5 edit + +Change 30 by gibbs@overdrive on 2000/08/08 10:01:08 + + First pass at the aic7xxx_queue routine. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#4 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#3 edit + +Change 29 by gibbs@overdrive on 2000/08/08 07:41:45 + + Missed in prior checkin. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#2 edit + +Change 27 by gibbs@overdrive on 2000/08/08 07:10:41 + + Add definitions to properly lock the system when returning + commands back to the OS. + + Hook up our interrupt handler. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#2 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#3 edit +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#2 edit + +Change 26 by gibbs@overdrive on 2000/08/08 05:59:33 + + Get us to the point where we can successfully register + PCI adapters. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#2 edit + +Change 25 by gibbs@overdrive on 2000/08/08 05:58:36 + + More infrastructure - mostly from FreeBSD. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_eisa.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_eisa.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#1 add + +Change 19 by gibbs@overdrive on 2000/07/28 03:12:09 + + Move into our sub-directory. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx_proc.c#4 delete + +Change 18 by gibbs@overdrive on 2000/07/27 12:00:48 + + Use the old Linux driver as the foundation for the Linux + specific core file. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#1 branch + +Change 7 by gibbs@overdrive on 2000/07/13 07:09:24 + + Latest SCSI message file from FreeBSD. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#2 edit + +Change 5 by gibbs@overdrive on 2000/07/13 07:07:29 + + Move the assembler to its own subdirectory. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm.c#2 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm.h#2 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.c#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.h#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#1 branch +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_gram.y#2 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_insformat.h#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_scan.l#2 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_symbol.c#3 delete +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_symbol.h#2 delete + +Change 1 by gibbs@overdrive on 2000/07/12 11:01:33 + + Initial import of Doug Ledford's aic7xxx driver v5.2.0. + +Affected files ... + +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx.c#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.reg#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#1 add +... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/sequencer.h#1 add + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/Config.in linux.21pre4-ac6/drivers/scsi/aic7xxx/Config.in --- linux.21pre4/drivers/scsi/aic7xxx/Config.in 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/Config.in 2003-01-22 22:10:29.000000000 +0000 @@ -2,12 +2,35 @@ dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then int ' Maximum number of TCQ commands per device' \ - CONFIG_AIC7XXX_CMDS_PER_DEVICE 253 + CONFIG_AIC7XXX_CMDS_PER_DEVICE 32 int ' Initial bus reset delay in milli-seconds' \ CONFIG_AIC7XXX_RESET_DELAY_MS 15000 bool ' Probe for EISA and VL AIC7XXX Adapters' \ CONFIG_AIC7XXX_PROBE_EISA_VL bool ' Build Adapter Firmware with Kernel Build' \ CONFIG_AIC7XXX_BUILD_FIRMWARE + bool ' Compile in Debugging Code' \ + CONFIG_AIC7XXX_DEBUG_ENABLE + int ' Debug code enable mask (2048 for all debugging)' \ + CONFIG_AIC7XXX_DEBUG_MASK 0 + bool ' Decode registers during diagnostics' \ + CONFIG_AIC7XXX_REG_PRETTY_PRINT fi fi +dep_tristate 'Adaptec AIC79xx support' CONFIG_SCSI_AIC79XX $CONFIG_SCSI +if [ "$CONFIG_SCSI_AIC79XX" != "n" ]; then + int ' Maximum number of TCQ commands per device' \ + CONFIG_AIC79XX_CMDS_PER_DEVICE 32 + int ' Initial bus reset delay in milli-seconds' \ + CONFIG_AIC79XX_RESET_DELAY_MS 15000 + bool ' Build Adapter Firmware with Kernel Build' \ + CONFIG_AIC79XX_BUILD_FIRMWARE + bool ' Enable Read Streaming for All Targets' \ + CONFIG_AIC79XX_ENABLE_RD_STRM + bool ' Compile in Debugging Code' \ + CONFIG_AIC79XX_DEBUG_ENABLE + int ' Debug code enable mask (16384 for all debugging)' \ + CONFIG_AIC79XX_DEBUG_MASK 0 + bool ' Decode registers during diagnostics' \ + CONFIG_AIC79XX_REG_PRETTY_PRINT +fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/Makefile linux.21pre4-ac6/drivers/scsi/aic7xxx/Makefile --- linux.21pre4/drivers/scsi/aic7xxx/Makefile 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/Makefile 2003-01-22 22:10:29.000000000 +0000 @@ -6,23 +6,38 @@ O_TARGET := aic7xxx_drv.o -list-multi := aic7xxx.o +list-multi := aic7xxx.o aic79xx.o obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o +endif +EXTRA_CFLAGS += -I.. #EXTRA_CFLAGS += -g # Platform Specific Files obj-aic7xxx = aic7xxx_osm.o aic7xxx_proc.o aic7770_osm.o -#PCI Specific Platform Files -ifeq ($(CONFIG_PCI),y) -obj-aic7xxx += aic7xxx_osm_pci.o -endif + # Core Files obj-aic7xxx += aic7xxx_core.o aic7xxx_93cx6.o aic7770.o -#PCI Specific Core Files +ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y) +obj-aic7xxx += aic7xxx_reg_print.o +endif + +#PCI Specific Files ifeq ($(CONFIG_PCI),y) -obj-aic7xxx += aic7xxx_pci.o + obj-aic7xxx += aic7xxx_pci.o + # Platform Specific PCI Files + obj-aic7xxx += aic7xxx_osm_pci.o +endif + +# Platform Specific U320 Files +obj-aic79xx = aic79xx_osm.o aic79xx_proc.o aic79xx_osm_pci.o +# Core Files +obj-aic79xx += aic79xx_core.o aic79xx_pci.o +ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y) +obj-aic79xx += aic79xx_reg_print.o endif # Override our module desitnation @@ -30,17 +45,45 @@ include $(TOPDIR)/Rules.make -aic7xxx.o: $(obj-aic7xxx) +aic7xxx_core.o: aic7xxx_seq.h +$(obj-aic7xxx): aic7xxx_reg.h +aic7xxx.o: aic7xxx_seq.h aic7xxx_reg.h $(obj-aic7xxx) $(LD) $(LD_RFLAG) -r -o $@ $(obj-aic7xxx) -ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y) -aic7xxx_core.o: aic7xxx_seq.h +aic79xx_core.o: aic79xx_seq.h +$(obj-aic79xx): aic79xx_reg.h +aic79xx.o: aic79xx_seq.h aic79xx_reg.h $(obj-aic79xx) + $(LD) $(LD_RFLAG) -r -o $@ $(obj-aic79xx) -$(obj-aic7xxx): aic7xxx_reg.h +ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y) +aic7xxx_gen = aic7xxx_seq.h aic7xxx_reg.h +ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y) +aic7xxx_gen += aic7xxx_reg_print.c +aic7xxx_asm_cmd = aicasm/aicasm -I. -r aic7xxx_reg.h \ + -p aic7xxx_reg_print.c -i aic7xxx_osm.h \ + -o aic7xxx_seq.h aic7xxx.seq +else +aic7xxx_asm_cmd = aicasm/aicasm -I. -r aic7xxx_reg.h \ + -o aic7xxx_seq.h aic7xxx.seq +endif +$(aic7xxx_gen): aic7xxx.seq aic7xxx.reg aicasm/aicasm + $(aic7xxx_asm_cmd) +endif -aic7xxx_seq.h aic7xxx_reg.h: aic7xxx.seq aic7xxx.reg aicasm/aicasm - aicasm/aicasm -I. -r aic7xxx_reg.h -o aic7xxx_seq.h aic7xxx.seq +ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y) +aic79xx_gen = aic79xx_seq.h aic79xx_reg.h +ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y) +aic79xx_gen += aic79xx_reg_print.c +aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \ + -p aic79xx_reg_print.c -i aic79xx_osm.h \ + -o aic79xx_seq.h aic79xx.seq +else +aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \ + -o aic79xx_seq.h aic79xx.seq endif +$(aic79xx_gen): aic79xx.seq aic79xx.reg aicasm/aicasm + $(aic79xx_asm_cmd) aicasm/aicasm: aicasm/*.[chyl] $(MAKE) -C aicasm +endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx/scsi_iu.h linux.21pre4-ac6/drivers/scsi/aic7xxx/scsi_iu.h --- linux.21pre4/drivers/scsi/aic7xxx/scsi_iu.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx/scsi_iu.h 2003-01-22 22:10:29.000000000 +0000 @@ -0,0 +1,39 @@ +/* + * This file is in the public domain. + */ +#ifndef _SCSI_SCSI_IU_H +#define _SCSI_SCSI_IU_H 1 + +struct scsi_status_iu_header +{ + u_int8_t reserved[2]; + u_int8_t flags; +#define SIU_SNSVALID 0x2 +#define SIU_RSPVALID 0x1 + u_int8_t status; + u_int8_t sense_length[4]; + u_int8_t pkt_failures_length[4]; + u_int8_t pkt_failures[1]; +}; + +#define SIU_PKTFAIL_OFFSET(siu) 12 +#define SIU_PKTFAIL_CODE(siu) (scsi_4btoul((siu)->pkt_failures) & 0xFF) +#define SIU_PFC_NONE 0 +#define SIU_PFC_CIU_FIELDS_INVALID 2 +#define SIU_PFC_TMF_NOT_SUPPORTED 4 +#define SIU_PFC_TMF_FAILED 5 +#define SIU_PFC_INVALID_TYPE_CODE 6 +#define SIU_PFC_ILLEGAL_REQUEST 7 +#define SIU_SENSE_OFFSET(siu) \ + (12 + (((siu)->flags & SIU_RSPVALID) \ + ? scsi_4btoul((siu)->pkt_failures_length) \ + : 0)) + +#define SIU_TASKMGMT_NONE 0x00 +#define SIU_TASKMGMT_ABORT_TASK 0x01 +#define SIU_TASKMGMT_ABORT_TASK_SET 0x02 +#define SIU_TASKMGMT_CLEAR_TASK_SET 0x04 +#define SIU_TASKMGMT_LUN_RESET 0x08 +#define SIU_TASKMGMT_TARGET_RESET 0x20 +#define SIU_TASKMGMT_CLEAR_ACA 0x40 +#endif /*_SCSI_SCSI_IU_H*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/aic7xxx_old.c linux.21pre4-ac6/drivers/scsi/aic7xxx_old.c --- linux.21pre4/drivers/scsi/aic7xxx_old.c 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/aic7xxx_old.c 2003-02-06 16:04:53.000000000 +0000 @@ -5435,9 +5435,9 @@ target_mask = (0x01 << tindex); /* - * Parse as much of the message as is availible, + * Parse as much of the message as is available, * rejecting it if we don't support it. When - * the entire message is availible and has been + * the entire message is available and has been * handled, return TRUE indicating that we have * parsed an entire message. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/cpqfcTSinit.c linux.21pre4-ac6/drivers/scsi/cpqfcTSinit.c --- linux.21pre4/drivers/scsi/cpqfcTSinit.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/cpqfcTSinit.c 2003-02-11 17:45:30.000000000 +0000 @@ -41,6 +41,7 @@ #include #include // ioremap() #include +#include #ifdef __alpha__ #define __KERNEL_SYSCALLS__ #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/dpt_i2o.c linux.21pre4-ac6/drivers/scsi/dpt_i2o.c --- linux.21pre4/drivers/scsi/dpt_i2o.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/dpt_i2o.c 2003-02-06 22:46:55.000000000 +0000 @@ -1498,7 +1498,7 @@ pDev->next_lun; pDev = pDev->next_lun){ } pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL); - if(pDev == NULL) { + if(pDev->next_lun == NULL) { return -ENOMEM; } memset(pDev->next_lun,0,sizeof(struct adpt_device)); @@ -2560,7 +2560,7 @@ if(pHba->initialized ) { if (adpt_i2o_status_get(pHba) < 0) { - if((rcode = adpt_i2o_reset_hba(pHba) != 0)){ + if((rcode = adpt_i2o_reset_hba(pHba)) != 0){ printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name); return rcode; } @@ -2586,7 +2586,7 @@ } } } else { - if((rcode = adpt_i2o_reset_hba(pHba) != 0)){ + if((rcode = adpt_i2o_reset_hba(pHba)) != 0){ printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name); return rcode; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/eata_generic.h linux.21pre4-ac6/drivers/scsi/eata_generic.h --- linux.21pre4/drivers/scsi/eata_generic.h 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/eata_generic.h 2003-01-31 11:45:21.000000000 +0000 @@ -97,7 +97,7 @@ #define DELAY(x) { ulong flags, i; \ save_flags(flags); sti(); \ i = jiffies + (x * HZ); \ - while (jiffies < i); \ + while (time_before(jiffies, i)) cpu_relax(); \ restore_flags(flags); } /*********************************************** diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/ips.c linux.21pre4-ac6/drivers/scsi/ips.c --- linux.21pre4/drivers/scsi/ips.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/ips.c 2003-02-06 16:04:53.000000000 +0000 @@ -7211,7 +7211,7 @@ /* Assumes that ips_read_adapter_status() is called first filling in */ /* the data for SubSystem Parameters. */ /* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */ -/* Data is availaible. */ +/* Data is available. */ /* */ /*---------------------------------------------------------------------------*/ static void ips_version_check(ips_ha_t *ha, int intr) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/Makefile linux.21pre4-ac6/drivers/scsi/Makefile --- linux.21pre4/drivers/scsi/Makefile 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/Makefile 2003-01-16 22:04:00.000000000 +0000 @@ -27,6 +27,7 @@ subdir-$(CONFIG_SCSI_AACRAID) += aacraid subdir-$(CONFIG_SCSI_AIC7XXX) += aic7xxx +subdir-$(CONFIG_SCSI_AIC79XX) += aic7xxx subdir-$(CONFIG_PCMCIA) += pcmcia @@ -71,6 +72,9 @@ ifeq ($(CONFIG_SCSI_AIC7XXX),y) obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx.o endif +ifeq ($(CONFIG_SCSI_AIC79XX),y) + obj-$(CONFIG_SCSI_AIC79XX) += aic7xxx/aic79xx.o +endif obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o obj-$(CONFIG_SCSI_IPS) += ips.o obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/megaraid.c linux.21pre4-ac6/drivers/scsi/megaraid.c --- linux.21pre4/drivers/scsi/megaraid.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/megaraid.c 2003-02-11 18:05:13.000000000 +0000 @@ -4936,7 +4936,7 @@ if( ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) { put_user( scsicmd->result, &uioc->pthru.scsistatus ); if (copy_to_user( uioc->pthru.reqsensearea, scsicmd->sense_buffer, - MAX_REQ_SENSE_LEN )); + MAX_REQ_SENSE_LEN )) ret= -EFAULT; } else { put_user(1, &uioc->mbox[16]); /* numstatus */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/NCR5380.c linux.21pre4-ac6/drivers/scsi/NCR5380.c --- linux.21pre4/drivers/scsi/NCR5380.c 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/NCR5380.c 2003-02-06 16:03:49.000000000 +0000 @@ -2460,8 +2460,9 @@ hostdata->issue_queue; hostdata->issue_queue = (Scsi_Cmnd *) cmd; dprintk(NDEBUG_QUEUES, ("scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no)); - } else { + } else #endif /* def AUTOSENSE */ + { collect_stats(hostdata, cmd); cmd->scsi_done(cmd); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/pcmcia/nsp_cs.c linux.21pre4-ac6/drivers/scsi/pcmcia/nsp_cs.c --- linux.21pre4/drivers/scsi/pcmcia/nsp_cs.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/pcmcia/nsp_cs.c 2003-02-06 16:04:53.000000000 +0000 @@ -707,7 +707,7 @@ ocount += res; //DEBUG(0, " ptr=0x%p this_residual=0x%x ocount=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount); - /* go to next scatter list if availavle */ + /* go to next scatter list if available */ if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.buffers_residual != 0 ) { //DEBUG(0, " scatterlist next timeout=%d\n", time_out); @@ -780,7 +780,7 @@ SCpnt->SCp.this_residual -= res; ocount += res; - /* go to next scatter list if availavle */ + /* go to next scatter list if available */ if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.buffers_residual != 0 ) { //DEBUG(0, " scatterlist next\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/scsi.c linux.21pre4-ac6/drivers/scsi/scsi.c --- linux.21pre4/drivers/scsi/scsi.c 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/scsi.c 2003-01-06 15:38:22.000000000 +0000 @@ -352,8 +352,9 @@ int interruptable) { struct Scsi_Host *host; - Scsi_Cmnd *SCpnt = NULL; + Scsi_Cmnd *SCpnt; Scsi_Device *SDpnt; + struct list_head *lp; unsigned long flags; if (!device) @@ -364,7 +365,6 @@ spin_lock_irqsave(&device_request_lock, flags); while (1 == 1) { - SCpnt = NULL; if (!device->device_blocked) { if (device->single_lun) { /* @@ -404,26 +404,21 @@ * If asked to wait, we need to wait, otherwise * return NULL. */ - SCpnt = NULL; goto busy; } } /* - * Now we can check for a free command block for this device. + * Is there a free command block for this device? */ - for (SCpnt = device->device_queue; SCpnt; SCpnt = SCpnt->next) { - if (SCpnt->request.rq_status == RQ_INACTIVE) - break; - } + if (!list_empty(&device->sdev_free_q)) + goto found; } + /* - * If we couldn't find a free command block, and we have been + * Couldn't find a free command block, and we have been * asked to wait, then do so. */ - if (SCpnt) { - break; - } - busy: +busy: /* * If we have been asked to wait for a free block, then * wait here. @@ -475,12 +470,20 @@ return NULL; } } + continue; } else { spin_unlock_irqrestore(&device_request_lock, flags); return NULL; } } +found: + lp = device->sdev_free_q.next; + list_del(lp); + SCpnt = list_entry(lp, Scsi_Cmnd, sc_list); + if (SCpnt->request.rq_status != RQ_INACTIVE) + BUG(); + SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.waiting = NULL; /* And no one is waiting for this * to complete */ @@ -526,6 +529,9 @@ SDpnt = SCpnt->device; + /* command is now free - add to list */ + list_add(&SCpnt->sc_list, &SDpnt->sdev_free_q); + SCpnt->request.rq_status = RQ_INACTIVE; SCpnt->state = SCSI_STATE_UNUSED; SCpnt->owner = SCSI_OWNER_NOBODY; @@ -1333,14 +1339,10 @@ */ int scsi_retry_command(Scsi_Cmnd * SCpnt) { - memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd, - sizeof(SCpnt->data_cmnd)); - SCpnt->request_buffer = SCpnt->buffer; - SCpnt->request_bufflen = SCpnt->bufflen; - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; - SCpnt->underflow = SCpnt->old_underflow; + /* + * Restore the SCSI command state. + */ + scsi_setup_cmd_retry(SCpnt); /* * Zero the sense information from the last time we tried @@ -1448,6 +1450,7 @@ spin_lock_irqsave(&device_request_lock, flags); for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCnext) { SDpnt->device_queue = SCnext = SCpnt->next; + list_del(&SCpnt->sc_list); kfree((char *) SCpnt); } SDpnt->has_cmdblocks = 0; @@ -1484,6 +1487,7 @@ SDpnt->queue_depth = 1; /* live to fight another day */ } SDpnt->device_queue = NULL; + INIT_LIST_HEAD(&SDpnt->sdev_free_q); for (j = 0; j < SDpnt->queue_depth; j++) { SCpnt = (Scsi_Cmnd *) @@ -1513,6 +1517,7 @@ SDpnt->device_queue = SCpnt; SCpnt->state = SCSI_STATE_UNUSED; SCpnt->owner = SCSI_OWNER_NOBODY; + list_add(&SCpnt->sc_list, &SDpnt->sdev_free_q); } if (j < SDpnt->queue_depth) { /* low on space (D.Gilbert 990424) */ printk(KERN_WARNING "scsi_build_commandblocks: want=%d, space for=%d blocks\n", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/scsi_error.c linux.21pre4-ac6/drivers/scsi/scsi_error.c --- linux.21pre4/drivers/scsi/scsi_error.c 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/scsi_error.c 2003-01-06 15:38:22.000000000 +0000 @@ -385,16 +385,10 @@ */ STATIC int scsi_eh_retry_command(Scsi_Cmnd * SCpnt) { - memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd, - sizeof(SCpnt->data_cmnd)); - SCpnt->request_buffer = SCpnt->buffer; - SCpnt->request_bufflen = SCpnt->bufflen; - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; - SCpnt->underflow = SCpnt->old_underflow; - - scsi_send_eh_cmnd(SCpnt, SCpnt->timeout_per_command); + do { + scsi_setup_cmd_retry(SCpnt); + scsi_send_eh_cmnd(SCpnt, SCpnt->timeout_per_command); + } while (SCpnt->eh_state == NEEDS_RETRY); /* * Hey, we are done. Let's look to see what happened. @@ -425,12 +419,6 @@ ASSERT_LOCK(&io_request_lock, 0); - memcpy((void *) SCpnt->cmnd, (void *) generic_sense, - sizeof(generic_sense)); - - if (SCpnt->device->scsi_level <= SCSI_2) - SCpnt->cmnd[1] = SCpnt->lun << 5; - scsi_result = (!SCpnt->host->hostt->unchecked_isa_dma) ? &scsi_result0[0] : kmalloc(512, GFP_ATOMIC | GFP_DMA); @@ -438,24 +426,40 @@ printk("cannot allocate scsi_result in scsi_request_sense.\n"); return FAILED; } - /* - * Zero the sense buffer. Some host adapters automatically always request - * sense, so it is not a good idea that SCpnt->request_buffer and - * SCpnt->sense_buffer point to the same address (DB). - * 0 is not a valid sense code. - */ - memset((void *) SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer)); - memset((void *) scsi_result, 0, 256); saved_result = SCpnt->result; - SCpnt->request_buffer = scsi_result; - SCpnt->request_bufflen = 256; - SCpnt->use_sg = 0; - SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); - SCpnt->sc_data_direction = SCSI_DATA_READ; - SCpnt->underflow = 0; - scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT); + do { + memcpy((void *) SCpnt->cmnd, (void *) generic_sense, + sizeof(generic_sense)); + + if (SCpnt->device->scsi_level <= SCSI_2) + SCpnt->cmnd[1] = SCpnt->lun << 5; + + /* + * Zero the sense buffer. Some host adapters automatically + * always request sense, so it is not a good idea that + * SCpnt->request_buffer and SCpnt->sense_buffer point to + * the same address (DB). 0 is not a valid sense code. + */ + memset((void *) SCpnt->sense_buffer, 0, + sizeof(SCpnt->sense_buffer)); + memset((void *) scsi_result, 0, 256); + + SCpnt->request_buffer = scsi_result; + SCpnt->request_bufflen = 256; + SCpnt->use_sg = 0; + SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); + SCpnt->sc_data_direction = SCSI_DATA_READ; + SCpnt->underflow = 0; + + scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT); + /* + * If the SCSI device responded with "logical unit + * is in process of becoming ready", we need to + * retry this command. + */ + } while (SCpnt->eh_state == NEEDS_RETRY); /* Last chance to have valid sense data */ if (!scsi_sense_valid(SCpnt)) @@ -497,26 +501,34 @@ static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; - memcpy((void *) SCpnt->cmnd, (void *) tur_command, - sizeof(tur_command)); + do { + memcpy((void *) SCpnt->cmnd, (void *) tur_command, + sizeof(tur_command)); - if (SCpnt->device->scsi_level <= SCSI_2) - SCpnt->cmnd[1] = SCpnt->lun << 5; + if (SCpnt->device->scsi_level <= SCSI_2) + SCpnt->cmnd[1] = SCpnt->lun << 5; - /* - * Zero the sense buffer. The SCSI spec mandates that any - * untransferred sense data should be interpreted as being zero. - */ - memset((void *) SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer)); + /* + * Zero the sense buffer. The SCSI spec mandates that any + * untransferred sense data should be interpreted as being zero. + */ + memset((void *) SCpnt->sense_buffer, 0, + sizeof(SCpnt->sense_buffer)); - SCpnt->request_buffer = NULL; - SCpnt->request_bufflen = 0; - SCpnt->use_sg = 0; - SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); - SCpnt->underflow = 0; - SCpnt->sc_data_direction = SCSI_DATA_NONE; + SCpnt->request_buffer = NULL; + SCpnt->request_bufflen = 0; + SCpnt->use_sg = 0; + SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); + SCpnt->underflow = 0; + SCpnt->sc_data_direction = SCSI_DATA_NONE; - scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT); + scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT); + /* + * If the SCSI device responded with "logical unit + * is in process of becoming ready", we need to + * retry this command. + */ + } while (SCpnt->eh_state == NEEDS_RETRY); /* * When we eventually call scsi_finish, we really wish to complete @@ -589,7 +601,6 @@ host = SCpnt->host; - retry: /* * We will use a queued command if possible, otherwise we will emulate the * queuing and calling of completion function ourselves. @@ -672,14 +683,13 @@ SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_send_eh_cmnd: scsi_eh_completed_normally %x\n", ret)); switch (ret) { - case SUCCESS: - SCpnt->eh_state = SUCCESS; - break; - case NEEDS_RETRY: - goto retry; - case FAILED: default: - SCpnt->eh_state = FAILED; + ret = FAILED; + /*FALLTHROUGH*/ + case FAILED: + case NEEDS_RETRY: + case SUCCESS: + SCpnt->eh_state = ret; break; } } else { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/scsi.h linux.21pre4-ac6/drivers/scsi/scsi.h --- linux.21pre4/drivers/scsi/scsi.h 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/scsi.h 2003-02-21 16:32:35.000000000 +0000 @@ -465,6 +465,7 @@ int sectors); extern struct Scsi_Device_Template *scsi_get_request_dev(struct request *); extern int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt); +extern void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt); extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int); extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, int block_sectors); @@ -558,6 +559,7 @@ int (*scsi_init_io_fn) (Scsi_Cmnd *); /* Used to initialize new request */ Scsi_Cmnd *device_queue; /* queue of SCSI Command structures */ + struct list_head sdev_free_q; /* list of free cmds */ /* public: */ unsigned int id, lun, channel; @@ -775,6 +777,8 @@ * received on original command * (auto-sense) */ + struct list_head sc_list; /* Inactive cmd list linkage, guarded + * by device_request_lock. */ unsigned flags; /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/scsi_lib.c linux.21pre4-ac6/drivers/scsi/scsi_lib.c --- linux.21pre4/drivers/scsi/scsi_lib.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/scsi_lib.c 2003-01-06 15:38:22.000000000 +0000 @@ -208,6 +208,30 @@ } /* + * Function: scsi_setup_cmd_retry() + * + * Purpose: Restore the command state for a retry + * + * Arguments: SCpnt - command to be restored + * + * Returns: Nothing + * + * Notes: Immediately prior to retrying a command, we need + * to restore certain fields that we saved above. + */ +void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt) +{ + memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd, + sizeof(SCpnt->data_cmnd)); + SCpnt->request_buffer = SCpnt->buffer; + SCpnt->request_bufflen = SCpnt->bufflen; + SCpnt->use_sg = SCpnt->old_use_sg; + SCpnt->cmd_len = SCpnt->old_cmd_len; + SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; + SCpnt->underflow = SCpnt->old_underflow; +} + +/* * Function: scsi_queue_next_request() * * Purpose: Handle post-processing of completed commands. @@ -720,7 +744,7 @@ printk("scsi%d: ERROR on channel %d, id %d, lun %d, CDB: ", SCpnt->host->host_no, (int) SCpnt->channel, (int) SCpnt->target, (int) SCpnt->lun); - print_command(SCpnt->cmnd); + print_command(SCpnt->data_cmnd); print_sense("sd", SCpnt); SCpnt = scsi_end_request(SCpnt, 0, block_sectors); return; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/scsi_scan.c linux.21pre4-ac6/drivers/scsi/scsi_scan.c --- linux.21pre4/drivers/scsi/scsi_scan.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/scsi_scan.c 2003-01-28 16:17:48.000000000 +0000 @@ -596,6 +596,7 @@ } else { /* assume no peripheral if any other sort of error */ scsi_release_request(SRpnt); + scsi_release_commandblocks(SDpnt); return 0; } } @@ -619,6 +620,7 @@ */ if ((scsi_result[0] >> 5) == 3) { scsi_release_request(SRpnt); + scsi_release_commandblocks(SDpnt); return 0; /* assume no peripheral if any sort of error */ } /* The Toshiba ROM was "gender-changed" here as an inline hack. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/sd.c linux.21pre4-ac6/drivers/scsi/sd.c --- linux.21pre4/drivers/scsi/sd.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/sd.c 2003-01-29 17:21:32.000000000 +0000 @@ -848,10 +848,13 @@ break; } - /* Look for non-removable devices that return NOT_READY. + /* Look for non-removable devices that return NOT_READY, + * and don't require manual intervention. * Issue command to spin up drive for these cases. */ if (the_result && !rscsi_disks[i].device->removable && - SRpnt->sr_sense_buffer[2] == NOT_READY) { + SRpnt->sr_sense_buffer[2] == NOT_READY && + ! ( SRpnt->sr_sense_buffer[12] == 0x04 && /* ASC */ + SRpnt->sr_sense_buffer[13] == 0x03 )) { /* ASCQ */ unsigned long time1; if (!spintime) { printk("%s: Spinning up disk...", nbuff); @@ -1001,7 +1004,7 @@ */ int m; int hard_sector = sector_size; - int sz = rscsi_disks[i].capacity * (hard_sector/256); + unsigned int sz = (rscsi_disks[i].capacity/2) * (hard_sector/256); /* There are 16 minors allocated for each major device */ for (m = i << 4; m < ((i + 1) << 4); m++) { @@ -1009,9 +1012,9 @@ } printk("SCSI device %s: " - "%d %d-byte hdwr sectors (%d MB)\n", + "%u %d-byte hdwr sectors (%d MB)\n", nbuff, rscsi_disks[i].capacity, - hard_sector, (sz/2 - sz/1250 + 974)/1950); + hard_sector, (sz - sz/625 + 974)/1950); } /* Rescale capacity to 512-byte units */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/sd.h linux.21pre4-ac6/drivers/scsi/sd.h --- linux.21pre4/drivers/scsi/sd.h 2003-01-29 16:26:49.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/sd.h 2003-02-21 16:32:35.000000000 +0000 @@ -24,13 +24,13 @@ #endif typedef struct scsi_disk { - unsigned capacity; /* size in blocks */ Scsi_Device *device; - unsigned char ready; /* flag ready for FLOPTICAL */ - unsigned char write_prot; /* flag write_protect for rmvable dev */ - unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */ - unsigned char sector_bit_shift; /* power of 2 sectors per FS block */ + unsigned capacity; /* size in blocks */ + unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */ + unsigned char sector_bit_shift; /* power of 2 sectors per FS block */ unsigned has_part_table:1; /* has partition table */ + unsigned ready:1; /* flag ready for FLOPTICAL */ + unsigned write_prot:1; /* flag write_protect for rmvable dev */ } Scsi_Disk; extern int revalidate_scsidisk(kdev_t dev, int maxusage); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/sim710_d.h linux.21pre4-ac6/drivers/scsi/sim710_d.h --- linux.21pre4/drivers/scsi/sim710_d.h 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/sim710_d.h 2003-01-06 15:38:23.000000000 +0000 @@ -18,15 +18,12 @@ ABSOLUTE reselected_identify = 0 ABSOLUTE msgin_buf = 0 +ABSOLUTE msg_reject = 0 +ABSOLUTE test1_src = 0 +ABSOLUTE test1_dst = 0 -ABSOLUTE int_bad_extmsg1a = 0xab930000 -ABSOLUTE int_bad_extmsg1b = 0xab930001 -ABSOLUTE int_bad_extmsg2a = 0xab930002 -ABSOLUTE int_bad_extmsg2b = 0xab930003 -ABSOLUTE int_bad_extmsg3a = 0xab930004 -ABSOLUTE int_bad_extmsg3b = 0xab930005 ABSOLUTE int_bad_msg1 = 0xab930006 ABSOLUTE int_bad_msg2 = 0xab930007 ABSOLUTE int_bad_msg3 = 0xab930008 @@ -50,7 +47,7 @@ ABSOLUTE int_disc2 = 0xab93001a ABSOLUTE int_disc3 = 0xab93001b ABSOLUTE int_not_rej = 0xab93001c - +ABSOLUTE int_test1 = 0xab93001d @@ -65,6 +62,9 @@ +ABSOLUTE did_reject = 0x01 + + @@ -74,1641 +74,1709 @@ at 0x00000000 : */ 0x60000200,0x00000000, /* - MOVE SCRATCH0 & 0 TO SCRATCH0 - -at 0x00000002 : */ 0x7c340000,0x00000000, -/* ; Enable selection timer MOVE CTEST7 & 0xef TO CTEST7 -at 0x00000004 : */ 0x7c1bef00,0x00000000, +at 0x00000002 : */ 0x7c1bef00,0x00000000, /* SELECT ATN FROM dsa_select, reselect -at 0x00000006 : */ 0x43000000,0x00000c48, +at 0x00000004 : */ 0x43000000,0x00000cd0, /* JUMP get_status, WHEN STATUS -at 0x00000008 : */ 0x830b0000,0x000000a0, +at 0x00000006 : */ 0x830b0000,0x00000098, /* ; Disable selection timer MOVE CTEST7 | 0x10 TO CTEST7 -at 0x0000000a : */ 0x7a1b1000,0x00000000, +at 0x00000008 : */ 0x7a1b1000,0x00000000, /* MOVE SCRATCH0 | had_select TO SCRATCH0 -at 0x0000000c : */ 0x7a340100,0x00000000, +at 0x0000000a : */ 0x7a340100,0x00000000, /* INT int_sel_no_ident, IF NOT MSG_OUT -at 0x0000000e : */ 0x9e020000,0xab930013, +at 0x0000000c : */ 0x9e020000,0xab930013, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x00000010 : */ 0x7a340200,0x00000000, +at 0x0000000e : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x00000012 : */ 0x1e000000,0x00000008, +at 0x00000010 : */ 0x1e000000,0x00000008, /* ENTRY done_ident done_ident: JUMP get_status, IF STATUS -at 0x00000014 : */ 0x830a0000,0x000000a0, +at 0x00000012 : */ 0x830a0000,0x00000098, /* redo_msgin1: JUMP get_msgin1, WHEN MSG_IN -at 0x00000016 : */ 0x870b0000,0x00000920, +at 0x00000014 : */ 0x870b0000,0x00000918, /* INT int_sel_not_cmd, IF NOT CMD -at 0x00000018 : */ 0x9a020000,0xab930014, +at 0x00000016 : */ 0x9a020000,0xab930014, /* ENTRY resume_cmd resume_cmd: MOVE SCRATCH0 | had_cmdout TO SCRATCH0 -at 0x0000001a : */ 0x7a340400,0x00000000, +at 0x00000018 : */ 0x7a340400,0x00000000, /* MOVE FROM dsa_cmnd, WHEN CMD -at 0x0000001c : */ 0x1a000000,0x00000010, +at 0x0000001a : */ 0x1a000000,0x00000010, /* ENTRY resume_pmm resume_pmm: redo_msgin2: JUMP get_msgin2, WHEN MSG_IN -at 0x0000001e : */ 0x870b0000,0x00000a20, +at 0x0000001c : */ 0x870b0000,0x00000a48, /* JUMP get_status, IF STATUS -at 0x00000020 : */ 0x830a0000,0x000000a0, +at 0x0000001e : */ 0x830a0000,0x00000098, /* JUMP input_data, IF DATA_IN -at 0x00000022 : */ 0x810a0000,0x000000e0, +at 0x00000020 : */ 0x810a0000,0x000000d8, /* JUMP output_data, IF DATA_OUT -at 0x00000024 : */ 0x800a0000,0x000004f8, +at 0x00000022 : */ 0x800a0000,0x000004f0, /* INT int_cmd_bad_phase -at 0x00000026 : */ 0x98080000,0xab930009, +at 0x00000024 : */ 0x98080000,0xab930009, /* get_status: ; Disable selection timer MOVE CTEST7 | 0x10 TO CTEST7 -at 0x00000028 : */ 0x7a1b1000,0x00000000, +at 0x00000026 : */ 0x7a1b1000,0x00000000, /* MOVE FROM dsa_status, WHEN STATUS -at 0x0000002a : */ 0x1b000000,0x00000018, +at 0x00000028 : */ 0x1b000000,0x00000018, /* INT int_status_not_msgin, WHEN NOT MSG_IN -at 0x0000002c : */ 0x9f030000,0xab930015, +at 0x0000002a : */ 0x9f030000,0xab930015, /* MOVE FROM dsa_msgin, WHEN MSG_IN -at 0x0000002e : */ 0x1f000000,0x00000020, +at 0x0000002c : */ 0x1f000000,0x00000020, /* INT int_not_cmd_complete, IF NOT 0x00 -at 0x00000030 : */ 0x98040000,0xab930012, +at 0x0000002e : */ 0x98040000,0xab930012, /* CLEAR ACK -at 0x00000032 : */ 0x60000040,0x00000000, +at 0x00000030 : */ 0x60000040,0x00000000, /* ENTRY wait_disc_complete wait_disc_complete: WAIT DISCONNECT -at 0x00000034 : */ 0x48000000,0x00000000, +at 0x00000032 : */ 0x48000000,0x00000000, /* INT int_cmd_complete -at 0x00000036 : */ 0x98080000,0xab93000a, +at 0x00000034 : */ 0x98080000,0xab93000a, /* input_data: MOVE SCRATCH0 | had_datain TO SCRATCH0 -at 0x00000038 : */ 0x7a340800,0x00000000, +at 0x00000036 : */ 0x7a340800,0x00000000, /* ENTRY patch_input_data patch_input_data: JUMP 0 -at 0x0000003a : */ 0x80080000,0x00000000, +at 0x00000038 : */ 0x80080000,0x00000000, /* MOVE FROM dsa_datain+0x0000, WHEN DATA_IN -at 0x0000003c : */ 0x19000000,0x00000028, +at 0x0000003a : */ 0x19000000,0x00000028, /* MOVE FROM dsa_datain+0x0008, WHEN DATA_IN -at 0x0000003e : */ 0x19000000,0x00000030, +at 0x0000003c : */ 0x19000000,0x00000030, /* MOVE FROM dsa_datain+0x0010, WHEN DATA_IN -at 0x00000040 : */ 0x19000000,0x00000038, +at 0x0000003e : */ 0x19000000,0x00000038, /* MOVE FROM dsa_datain+0x0018, WHEN DATA_IN -at 0x00000042 : */ 0x19000000,0x00000040, +at 0x00000040 : */ 0x19000000,0x00000040, /* MOVE FROM dsa_datain+0x0020, WHEN DATA_IN -at 0x00000044 : */ 0x19000000,0x00000048, +at 0x00000042 : */ 0x19000000,0x00000048, /* MOVE FROM dsa_datain+0x0028, WHEN DATA_IN -at 0x00000046 : */ 0x19000000,0x00000050, +at 0x00000044 : */ 0x19000000,0x00000050, /* MOVE FROM dsa_datain+0x0030, WHEN DATA_IN -at 0x00000048 : */ 0x19000000,0x00000058, +at 0x00000046 : */ 0x19000000,0x00000058, /* MOVE FROM dsa_datain+0x0038, WHEN DATA_IN -at 0x0000004a : */ 0x19000000,0x00000060, +at 0x00000048 : */ 0x19000000,0x00000060, /* MOVE FROM dsa_datain+0x0040, WHEN DATA_IN -at 0x0000004c : */ 0x19000000,0x00000068, +at 0x0000004a : */ 0x19000000,0x00000068, /* MOVE FROM dsa_datain+0x0048, WHEN DATA_IN -at 0x0000004e : */ 0x19000000,0x00000070, +at 0x0000004c : */ 0x19000000,0x00000070, /* MOVE FROM dsa_datain+0x0050, WHEN DATA_IN -at 0x00000050 : */ 0x19000000,0x00000078, +at 0x0000004e : */ 0x19000000,0x00000078, /* MOVE FROM dsa_datain+0x0058, WHEN DATA_IN -at 0x00000052 : */ 0x19000000,0x00000080, +at 0x00000050 : */ 0x19000000,0x00000080, /* MOVE FROM dsa_datain+0x0060, WHEN DATA_IN -at 0x00000054 : */ 0x19000000,0x00000088, +at 0x00000052 : */ 0x19000000,0x00000088, /* MOVE FROM dsa_datain+0x0068, WHEN DATA_IN -at 0x00000056 : */ 0x19000000,0x00000090, +at 0x00000054 : */ 0x19000000,0x00000090, /* MOVE FROM dsa_datain+0x0070, WHEN DATA_IN -at 0x00000058 : */ 0x19000000,0x00000098, +at 0x00000056 : */ 0x19000000,0x00000098, /* MOVE FROM dsa_datain+0x0078, WHEN DATA_IN -at 0x0000005a : */ 0x19000000,0x000000a0, +at 0x00000058 : */ 0x19000000,0x000000a0, /* MOVE FROM dsa_datain+0x0080, WHEN DATA_IN -at 0x0000005c : */ 0x19000000,0x000000a8, +at 0x0000005a : */ 0x19000000,0x000000a8, /* MOVE FROM dsa_datain+0x0088, WHEN DATA_IN -at 0x0000005e : */ 0x19000000,0x000000b0, +at 0x0000005c : */ 0x19000000,0x000000b0, /* MOVE FROM dsa_datain+0x0090, WHEN DATA_IN -at 0x00000060 : */ 0x19000000,0x000000b8, +at 0x0000005e : */ 0x19000000,0x000000b8, /* MOVE FROM dsa_datain+0x0098, WHEN DATA_IN -at 0x00000062 : */ 0x19000000,0x000000c0, +at 0x00000060 : */ 0x19000000,0x000000c0, /* MOVE FROM dsa_datain+0x00a0, WHEN DATA_IN -at 0x00000064 : */ 0x19000000,0x000000c8, +at 0x00000062 : */ 0x19000000,0x000000c8, /* MOVE FROM dsa_datain+0x00a8, WHEN DATA_IN -at 0x00000066 : */ 0x19000000,0x000000d0, +at 0x00000064 : */ 0x19000000,0x000000d0, /* MOVE FROM dsa_datain+0x00b0, WHEN DATA_IN -at 0x00000068 : */ 0x19000000,0x000000d8, +at 0x00000066 : */ 0x19000000,0x000000d8, /* MOVE FROM dsa_datain+0x00b8, WHEN DATA_IN -at 0x0000006a : */ 0x19000000,0x000000e0, +at 0x00000068 : */ 0x19000000,0x000000e0, /* MOVE FROM dsa_datain+0x00c0, WHEN DATA_IN -at 0x0000006c : */ 0x19000000,0x000000e8, +at 0x0000006a : */ 0x19000000,0x000000e8, /* MOVE FROM dsa_datain+0x00c8, WHEN DATA_IN -at 0x0000006e : */ 0x19000000,0x000000f0, +at 0x0000006c : */ 0x19000000,0x000000f0, /* MOVE FROM dsa_datain+0x00d0, WHEN DATA_IN -at 0x00000070 : */ 0x19000000,0x000000f8, +at 0x0000006e : */ 0x19000000,0x000000f8, /* MOVE FROM dsa_datain+0x00d8, WHEN DATA_IN -at 0x00000072 : */ 0x19000000,0x00000100, +at 0x00000070 : */ 0x19000000,0x00000100, /* MOVE FROM dsa_datain+0x00e0, WHEN DATA_IN -at 0x00000074 : */ 0x19000000,0x00000108, +at 0x00000072 : */ 0x19000000,0x00000108, /* MOVE FROM dsa_datain+0x00e8, WHEN DATA_IN -at 0x00000076 : */ 0x19000000,0x00000110, +at 0x00000074 : */ 0x19000000,0x00000110, /* MOVE FROM dsa_datain+0x00f0, WHEN DATA_IN -at 0x00000078 : */ 0x19000000,0x00000118, +at 0x00000076 : */ 0x19000000,0x00000118, /* MOVE FROM dsa_datain+0x00f8, WHEN DATA_IN -at 0x0000007a : */ 0x19000000,0x00000120, +at 0x00000078 : */ 0x19000000,0x00000120, /* MOVE FROM dsa_datain+0x0100, WHEN DATA_IN -at 0x0000007c : */ 0x19000000,0x00000128, +at 0x0000007a : */ 0x19000000,0x00000128, /* MOVE FROM dsa_datain+0x0108, WHEN DATA_IN -at 0x0000007e : */ 0x19000000,0x00000130, +at 0x0000007c : */ 0x19000000,0x00000130, /* MOVE FROM dsa_datain+0x0110, WHEN DATA_IN -at 0x00000080 : */ 0x19000000,0x00000138, +at 0x0000007e : */ 0x19000000,0x00000138, /* MOVE FROM dsa_datain+0x0118, WHEN DATA_IN -at 0x00000082 : */ 0x19000000,0x00000140, +at 0x00000080 : */ 0x19000000,0x00000140, /* MOVE FROM dsa_datain+0x0120, WHEN DATA_IN -at 0x00000084 : */ 0x19000000,0x00000148, +at 0x00000082 : */ 0x19000000,0x00000148, /* MOVE FROM dsa_datain+0x0128, WHEN DATA_IN -at 0x00000086 : */ 0x19000000,0x00000150, +at 0x00000084 : */ 0x19000000,0x00000150, /* MOVE FROM dsa_datain+0x0130, WHEN DATA_IN -at 0x00000088 : */ 0x19000000,0x00000158, +at 0x00000086 : */ 0x19000000,0x00000158, /* MOVE FROM dsa_datain+0x0138, WHEN DATA_IN -at 0x0000008a : */ 0x19000000,0x00000160, +at 0x00000088 : */ 0x19000000,0x00000160, /* MOVE FROM dsa_datain+0x0140, WHEN DATA_IN -at 0x0000008c : */ 0x19000000,0x00000168, +at 0x0000008a : */ 0x19000000,0x00000168, /* MOVE FROM dsa_datain+0x0148, WHEN DATA_IN -at 0x0000008e : */ 0x19000000,0x00000170, +at 0x0000008c : */ 0x19000000,0x00000170, /* MOVE FROM dsa_datain+0x0150, WHEN DATA_IN -at 0x00000090 : */ 0x19000000,0x00000178, +at 0x0000008e : */ 0x19000000,0x00000178, /* MOVE FROM dsa_datain+0x0158, WHEN DATA_IN -at 0x00000092 : */ 0x19000000,0x00000180, +at 0x00000090 : */ 0x19000000,0x00000180, /* MOVE FROM dsa_datain+0x0160, WHEN DATA_IN -at 0x00000094 : */ 0x19000000,0x00000188, +at 0x00000092 : */ 0x19000000,0x00000188, /* MOVE FROM dsa_datain+0x0168, WHEN DATA_IN -at 0x00000096 : */ 0x19000000,0x00000190, +at 0x00000094 : */ 0x19000000,0x00000190, /* MOVE FROM dsa_datain+0x0170, WHEN DATA_IN -at 0x00000098 : */ 0x19000000,0x00000198, +at 0x00000096 : */ 0x19000000,0x00000198, /* MOVE FROM dsa_datain+0x0178, WHEN DATA_IN -at 0x0000009a : */ 0x19000000,0x000001a0, +at 0x00000098 : */ 0x19000000,0x000001a0, /* MOVE FROM dsa_datain+0x0180, WHEN DATA_IN -at 0x0000009c : */ 0x19000000,0x000001a8, +at 0x0000009a : */ 0x19000000,0x000001a8, /* MOVE FROM dsa_datain+0x0188, WHEN DATA_IN -at 0x0000009e : */ 0x19000000,0x000001b0, +at 0x0000009c : */ 0x19000000,0x000001b0, /* MOVE FROM dsa_datain+0x0190, WHEN DATA_IN -at 0x000000a0 : */ 0x19000000,0x000001b8, +at 0x0000009e : */ 0x19000000,0x000001b8, /* MOVE FROM dsa_datain+0x0198, WHEN DATA_IN -at 0x000000a2 : */ 0x19000000,0x000001c0, +at 0x000000a0 : */ 0x19000000,0x000001c0, /* MOVE FROM dsa_datain+0x01a0, WHEN DATA_IN -at 0x000000a4 : */ 0x19000000,0x000001c8, +at 0x000000a2 : */ 0x19000000,0x000001c8, /* MOVE FROM dsa_datain+0x01a8, WHEN DATA_IN -at 0x000000a6 : */ 0x19000000,0x000001d0, +at 0x000000a4 : */ 0x19000000,0x000001d0, /* MOVE FROM dsa_datain+0x01b0, WHEN DATA_IN -at 0x000000a8 : */ 0x19000000,0x000001d8, +at 0x000000a6 : */ 0x19000000,0x000001d8, /* MOVE FROM dsa_datain+0x01b8, WHEN DATA_IN -at 0x000000aa : */ 0x19000000,0x000001e0, +at 0x000000a8 : */ 0x19000000,0x000001e0, /* MOVE FROM dsa_datain+0x01c0, WHEN DATA_IN -at 0x000000ac : */ 0x19000000,0x000001e8, +at 0x000000aa : */ 0x19000000,0x000001e8, /* MOVE FROM dsa_datain+0x01c8, WHEN DATA_IN -at 0x000000ae : */ 0x19000000,0x000001f0, +at 0x000000ac : */ 0x19000000,0x000001f0, /* MOVE FROM dsa_datain+0x01d0, WHEN DATA_IN -at 0x000000b0 : */ 0x19000000,0x000001f8, +at 0x000000ae : */ 0x19000000,0x000001f8, /* MOVE FROM dsa_datain+0x01d8, WHEN DATA_IN -at 0x000000b2 : */ 0x19000000,0x00000200, +at 0x000000b0 : */ 0x19000000,0x00000200, /* MOVE FROM dsa_datain+0x01e0, WHEN DATA_IN -at 0x000000b4 : */ 0x19000000,0x00000208, +at 0x000000b2 : */ 0x19000000,0x00000208, /* MOVE FROM dsa_datain+0x01e8, WHEN DATA_IN -at 0x000000b6 : */ 0x19000000,0x00000210, +at 0x000000b4 : */ 0x19000000,0x00000210, /* MOVE FROM dsa_datain+0x01f0, WHEN DATA_IN -at 0x000000b8 : */ 0x19000000,0x00000218, +at 0x000000b6 : */ 0x19000000,0x00000218, /* MOVE FROM dsa_datain+0x01f8, WHEN DATA_IN -at 0x000000ba : */ 0x19000000,0x00000220, +at 0x000000b8 : */ 0x19000000,0x00000220, /* MOVE FROM dsa_datain+0x0200, WHEN DATA_IN -at 0x000000bc : */ 0x19000000,0x00000228, +at 0x000000ba : */ 0x19000000,0x00000228, /* MOVE FROM dsa_datain+0x0208, WHEN DATA_IN -at 0x000000be : */ 0x19000000,0x00000230, +at 0x000000bc : */ 0x19000000,0x00000230, /* MOVE FROM dsa_datain+0x0210, WHEN DATA_IN -at 0x000000c0 : */ 0x19000000,0x00000238, +at 0x000000be : */ 0x19000000,0x00000238, /* MOVE FROM dsa_datain+0x0218, WHEN DATA_IN -at 0x000000c2 : */ 0x19000000,0x00000240, +at 0x000000c0 : */ 0x19000000,0x00000240, /* MOVE FROM dsa_datain+0x0220, WHEN DATA_IN -at 0x000000c4 : */ 0x19000000,0x00000248, +at 0x000000c2 : */ 0x19000000,0x00000248, /* MOVE FROM dsa_datain+0x0228, WHEN DATA_IN -at 0x000000c6 : */ 0x19000000,0x00000250, +at 0x000000c4 : */ 0x19000000,0x00000250, /* MOVE FROM dsa_datain+0x0230, WHEN DATA_IN -at 0x000000c8 : */ 0x19000000,0x00000258, +at 0x000000c6 : */ 0x19000000,0x00000258, /* MOVE FROM dsa_datain+0x0238, WHEN DATA_IN -at 0x000000ca : */ 0x19000000,0x00000260, +at 0x000000c8 : */ 0x19000000,0x00000260, /* MOVE FROM dsa_datain+0x0240, WHEN DATA_IN -at 0x000000cc : */ 0x19000000,0x00000268, +at 0x000000ca : */ 0x19000000,0x00000268, /* MOVE FROM dsa_datain+0x0248, WHEN DATA_IN -at 0x000000ce : */ 0x19000000,0x00000270, +at 0x000000cc : */ 0x19000000,0x00000270, /* MOVE FROM dsa_datain+0x0250, WHEN DATA_IN -at 0x000000d0 : */ 0x19000000,0x00000278, +at 0x000000ce : */ 0x19000000,0x00000278, /* MOVE FROM dsa_datain+0x0258, WHEN DATA_IN -at 0x000000d2 : */ 0x19000000,0x00000280, +at 0x000000d0 : */ 0x19000000,0x00000280, /* MOVE FROM dsa_datain+0x0260, WHEN DATA_IN -at 0x000000d4 : */ 0x19000000,0x00000288, +at 0x000000d2 : */ 0x19000000,0x00000288, /* MOVE FROM dsa_datain+0x0268, WHEN DATA_IN -at 0x000000d6 : */ 0x19000000,0x00000290, +at 0x000000d4 : */ 0x19000000,0x00000290, /* MOVE FROM dsa_datain+0x0270, WHEN DATA_IN -at 0x000000d8 : */ 0x19000000,0x00000298, +at 0x000000d6 : */ 0x19000000,0x00000298, /* MOVE FROM dsa_datain+0x0278, WHEN DATA_IN -at 0x000000da : */ 0x19000000,0x000002a0, +at 0x000000d8 : */ 0x19000000,0x000002a0, /* MOVE FROM dsa_datain+0x0280, WHEN DATA_IN -at 0x000000dc : */ 0x19000000,0x000002a8, +at 0x000000da : */ 0x19000000,0x000002a8, /* MOVE FROM dsa_datain+0x0288, WHEN DATA_IN -at 0x000000de : */ 0x19000000,0x000002b0, +at 0x000000dc : */ 0x19000000,0x000002b0, /* MOVE FROM dsa_datain+0x0290, WHEN DATA_IN -at 0x000000e0 : */ 0x19000000,0x000002b8, +at 0x000000de : */ 0x19000000,0x000002b8, /* MOVE FROM dsa_datain+0x0298, WHEN DATA_IN -at 0x000000e2 : */ 0x19000000,0x000002c0, +at 0x000000e0 : */ 0x19000000,0x000002c0, /* MOVE FROM dsa_datain+0x02a0, WHEN DATA_IN -at 0x000000e4 : */ 0x19000000,0x000002c8, +at 0x000000e2 : */ 0x19000000,0x000002c8, /* MOVE FROM dsa_datain+0x02a8, WHEN DATA_IN -at 0x000000e6 : */ 0x19000000,0x000002d0, +at 0x000000e4 : */ 0x19000000,0x000002d0, /* MOVE FROM dsa_datain+0x02b0, WHEN DATA_IN -at 0x000000e8 : */ 0x19000000,0x000002d8, +at 0x000000e6 : */ 0x19000000,0x000002d8, /* MOVE FROM dsa_datain+0x02b8, WHEN DATA_IN -at 0x000000ea : */ 0x19000000,0x000002e0, +at 0x000000e8 : */ 0x19000000,0x000002e0, /* MOVE FROM dsa_datain+0x02c0, WHEN DATA_IN -at 0x000000ec : */ 0x19000000,0x000002e8, +at 0x000000ea : */ 0x19000000,0x000002e8, /* MOVE FROM dsa_datain+0x02c8, WHEN DATA_IN -at 0x000000ee : */ 0x19000000,0x000002f0, +at 0x000000ec : */ 0x19000000,0x000002f0, /* MOVE FROM dsa_datain+0x02d0, WHEN DATA_IN -at 0x000000f0 : */ 0x19000000,0x000002f8, +at 0x000000ee : */ 0x19000000,0x000002f8, /* MOVE FROM dsa_datain+0x02d8, WHEN DATA_IN -at 0x000000f2 : */ 0x19000000,0x00000300, +at 0x000000f0 : */ 0x19000000,0x00000300, /* MOVE FROM dsa_datain+0x02e0, WHEN DATA_IN -at 0x000000f4 : */ 0x19000000,0x00000308, +at 0x000000f2 : */ 0x19000000,0x00000308, /* MOVE FROM dsa_datain+0x02e8, WHEN DATA_IN -at 0x000000f6 : */ 0x19000000,0x00000310, +at 0x000000f4 : */ 0x19000000,0x00000310, /* MOVE FROM dsa_datain+0x02f0, WHEN DATA_IN -at 0x000000f8 : */ 0x19000000,0x00000318, +at 0x000000f6 : */ 0x19000000,0x00000318, /* MOVE FROM dsa_datain+0x02f8, WHEN DATA_IN -at 0x000000fa : */ 0x19000000,0x00000320, +at 0x000000f8 : */ 0x19000000,0x00000320, /* MOVE FROM dsa_datain+0x0300, WHEN DATA_IN -at 0x000000fc : */ 0x19000000,0x00000328, +at 0x000000fa : */ 0x19000000,0x00000328, /* MOVE FROM dsa_datain+0x0308, WHEN DATA_IN -at 0x000000fe : */ 0x19000000,0x00000330, +at 0x000000fc : */ 0x19000000,0x00000330, /* MOVE FROM dsa_datain+0x0310, WHEN DATA_IN -at 0x00000100 : */ 0x19000000,0x00000338, +at 0x000000fe : */ 0x19000000,0x00000338, /* MOVE FROM dsa_datain+0x0318, WHEN DATA_IN -at 0x00000102 : */ 0x19000000,0x00000340, +at 0x00000100 : */ 0x19000000,0x00000340, /* MOVE FROM dsa_datain+0x0320, WHEN DATA_IN -at 0x00000104 : */ 0x19000000,0x00000348, +at 0x00000102 : */ 0x19000000,0x00000348, /* MOVE FROM dsa_datain+0x0328, WHEN DATA_IN -at 0x00000106 : */ 0x19000000,0x00000350, +at 0x00000104 : */ 0x19000000,0x00000350, /* MOVE FROM dsa_datain+0x0330, WHEN DATA_IN -at 0x00000108 : */ 0x19000000,0x00000358, +at 0x00000106 : */ 0x19000000,0x00000358, /* MOVE FROM dsa_datain+0x0338, WHEN DATA_IN -at 0x0000010a : */ 0x19000000,0x00000360, +at 0x00000108 : */ 0x19000000,0x00000360, /* MOVE FROM dsa_datain+0x0340, WHEN DATA_IN -at 0x0000010c : */ 0x19000000,0x00000368, +at 0x0000010a : */ 0x19000000,0x00000368, /* MOVE FROM dsa_datain+0x0348, WHEN DATA_IN -at 0x0000010e : */ 0x19000000,0x00000370, +at 0x0000010c : */ 0x19000000,0x00000370, /* MOVE FROM dsa_datain+0x0350, WHEN DATA_IN -at 0x00000110 : */ 0x19000000,0x00000378, +at 0x0000010e : */ 0x19000000,0x00000378, /* MOVE FROM dsa_datain+0x0358, WHEN DATA_IN -at 0x00000112 : */ 0x19000000,0x00000380, +at 0x00000110 : */ 0x19000000,0x00000380, /* MOVE FROM dsa_datain+0x0360, WHEN DATA_IN -at 0x00000114 : */ 0x19000000,0x00000388, +at 0x00000112 : */ 0x19000000,0x00000388, /* MOVE FROM dsa_datain+0x0368, WHEN DATA_IN -at 0x00000116 : */ 0x19000000,0x00000390, +at 0x00000114 : */ 0x19000000,0x00000390, /* MOVE FROM dsa_datain+0x0370, WHEN DATA_IN -at 0x00000118 : */ 0x19000000,0x00000398, +at 0x00000116 : */ 0x19000000,0x00000398, /* MOVE FROM dsa_datain+0x0378, WHEN DATA_IN -at 0x0000011a : */ 0x19000000,0x000003a0, +at 0x00000118 : */ 0x19000000,0x000003a0, /* MOVE FROM dsa_datain+0x0380, WHEN DATA_IN -at 0x0000011c : */ 0x19000000,0x000003a8, +at 0x0000011a : */ 0x19000000,0x000003a8, /* MOVE FROM dsa_datain+0x0388, WHEN DATA_IN -at 0x0000011e : */ 0x19000000,0x000003b0, +at 0x0000011c : */ 0x19000000,0x000003b0, /* MOVE FROM dsa_datain+0x0390, WHEN DATA_IN -at 0x00000120 : */ 0x19000000,0x000003b8, +at 0x0000011e : */ 0x19000000,0x000003b8, /* MOVE FROM dsa_datain+0x0398, WHEN DATA_IN -at 0x00000122 : */ 0x19000000,0x000003c0, +at 0x00000120 : */ 0x19000000,0x000003c0, /* MOVE FROM dsa_datain+0x03a0, WHEN DATA_IN -at 0x00000124 : */ 0x19000000,0x000003c8, +at 0x00000122 : */ 0x19000000,0x000003c8, /* MOVE FROM dsa_datain+0x03a8, WHEN DATA_IN -at 0x00000126 : */ 0x19000000,0x000003d0, +at 0x00000124 : */ 0x19000000,0x000003d0, /* MOVE FROM dsa_datain+0x03b0, WHEN DATA_IN -at 0x00000128 : */ 0x19000000,0x000003d8, +at 0x00000126 : */ 0x19000000,0x000003d8, /* MOVE FROM dsa_datain+0x03b8, WHEN DATA_IN -at 0x0000012a : */ 0x19000000,0x000003e0, +at 0x00000128 : */ 0x19000000,0x000003e0, /* MOVE FROM dsa_datain+0x03c0, WHEN DATA_IN -at 0x0000012c : */ 0x19000000,0x000003e8, +at 0x0000012a : */ 0x19000000,0x000003e8, /* MOVE FROM dsa_datain+0x03c8, WHEN DATA_IN -at 0x0000012e : */ 0x19000000,0x000003f0, +at 0x0000012c : */ 0x19000000,0x000003f0, /* MOVE FROM dsa_datain+0x03d0, WHEN DATA_IN -at 0x00000130 : */ 0x19000000,0x000003f8, +at 0x0000012e : */ 0x19000000,0x000003f8, /* MOVE FROM dsa_datain+0x03d8, WHEN DATA_IN -at 0x00000132 : */ 0x19000000,0x00000400, +at 0x00000130 : */ 0x19000000,0x00000400, /* MOVE FROM dsa_datain+0x03e0, WHEN DATA_IN -at 0x00000134 : */ 0x19000000,0x00000408, +at 0x00000132 : */ 0x19000000,0x00000408, /* MOVE FROM dsa_datain+0x03e8, WHEN DATA_IN -at 0x00000136 : */ 0x19000000,0x00000410, +at 0x00000134 : */ 0x19000000,0x00000410, /* MOVE FROM dsa_datain+0x03f0, WHEN DATA_IN -at 0x00000138 : */ 0x19000000,0x00000418, +at 0x00000136 : */ 0x19000000,0x00000418, /* MOVE FROM dsa_datain+0x03f8, WHEN DATA_IN -at 0x0000013a : */ 0x19000000,0x00000420, +at 0x00000138 : */ 0x19000000,0x00000420, /* JUMP end_data_trans -at 0x0000013c : */ 0x80080000,0x00000908, +at 0x0000013a : */ 0x80080000,0x00000900, /* output_data: MOVE SCRATCH0 | had_dataout TO SCRATCH0 -at 0x0000013e : */ 0x7a341000,0x00000000, +at 0x0000013c : */ 0x7a341000,0x00000000, /* ENTRY patch_output_data patch_output_data: JUMP 0 -at 0x00000140 : */ 0x80080000,0x00000000, +at 0x0000013e : */ 0x80080000,0x00000000, /* MOVE FROM dsa_dataout+0x0000, WHEN DATA_OUT -at 0x00000142 : */ 0x18000000,0x00000428, +at 0x00000140 : */ 0x18000000,0x00000428, /* MOVE FROM dsa_dataout+0x0008, WHEN DATA_OUT -at 0x00000144 : */ 0x18000000,0x00000430, +at 0x00000142 : */ 0x18000000,0x00000430, /* MOVE FROM dsa_dataout+0x0010, WHEN DATA_OUT -at 0x00000146 : */ 0x18000000,0x00000438, +at 0x00000144 : */ 0x18000000,0x00000438, /* MOVE FROM dsa_dataout+0x0018, WHEN DATA_OUT -at 0x00000148 : */ 0x18000000,0x00000440, +at 0x00000146 : */ 0x18000000,0x00000440, /* MOVE FROM dsa_dataout+0x0020, WHEN DATA_OUT -at 0x0000014a : */ 0x18000000,0x00000448, +at 0x00000148 : */ 0x18000000,0x00000448, /* MOVE FROM dsa_dataout+0x0028, WHEN DATA_OUT -at 0x0000014c : */ 0x18000000,0x00000450, +at 0x0000014a : */ 0x18000000,0x00000450, /* MOVE FROM dsa_dataout+0x0030, WHEN DATA_OUT -at 0x0000014e : */ 0x18000000,0x00000458, +at 0x0000014c : */ 0x18000000,0x00000458, /* MOVE FROM dsa_dataout+0x0038, WHEN DATA_OUT -at 0x00000150 : */ 0x18000000,0x00000460, +at 0x0000014e : */ 0x18000000,0x00000460, /* MOVE FROM dsa_dataout+0x0040, WHEN DATA_OUT -at 0x00000152 : */ 0x18000000,0x00000468, +at 0x00000150 : */ 0x18000000,0x00000468, /* MOVE FROM dsa_dataout+0x0048, WHEN DATA_OUT -at 0x00000154 : */ 0x18000000,0x00000470, +at 0x00000152 : */ 0x18000000,0x00000470, /* MOVE FROM dsa_dataout+0x0050, WHEN DATA_OUT -at 0x00000156 : */ 0x18000000,0x00000478, +at 0x00000154 : */ 0x18000000,0x00000478, /* MOVE FROM dsa_dataout+0x0058, WHEN DATA_OUT -at 0x00000158 : */ 0x18000000,0x00000480, +at 0x00000156 : */ 0x18000000,0x00000480, /* MOVE FROM dsa_dataout+0x0060, WHEN DATA_OUT -at 0x0000015a : */ 0x18000000,0x00000488, +at 0x00000158 : */ 0x18000000,0x00000488, /* MOVE FROM dsa_dataout+0x0068, WHEN DATA_OUT -at 0x0000015c : */ 0x18000000,0x00000490, +at 0x0000015a : */ 0x18000000,0x00000490, /* MOVE FROM dsa_dataout+0x0070, WHEN DATA_OUT -at 0x0000015e : */ 0x18000000,0x00000498, +at 0x0000015c : */ 0x18000000,0x00000498, /* MOVE FROM dsa_dataout+0x0078, WHEN DATA_OUT -at 0x00000160 : */ 0x18000000,0x000004a0, +at 0x0000015e : */ 0x18000000,0x000004a0, /* MOVE FROM dsa_dataout+0x0080, WHEN DATA_OUT -at 0x00000162 : */ 0x18000000,0x000004a8, +at 0x00000160 : */ 0x18000000,0x000004a8, /* MOVE FROM dsa_dataout+0x0088, WHEN DATA_OUT -at 0x00000164 : */ 0x18000000,0x000004b0, +at 0x00000162 : */ 0x18000000,0x000004b0, /* MOVE FROM dsa_dataout+0x0090, WHEN DATA_OUT -at 0x00000166 : */ 0x18000000,0x000004b8, +at 0x00000164 : */ 0x18000000,0x000004b8, /* MOVE FROM dsa_dataout+0x0098, WHEN DATA_OUT -at 0x00000168 : */ 0x18000000,0x000004c0, +at 0x00000166 : */ 0x18000000,0x000004c0, /* MOVE FROM dsa_dataout+0x00a0, WHEN DATA_OUT -at 0x0000016a : */ 0x18000000,0x000004c8, +at 0x00000168 : */ 0x18000000,0x000004c8, /* MOVE FROM dsa_dataout+0x00a8, WHEN DATA_OUT -at 0x0000016c : */ 0x18000000,0x000004d0, +at 0x0000016a : */ 0x18000000,0x000004d0, /* MOVE FROM dsa_dataout+0x00b0, WHEN DATA_OUT -at 0x0000016e : */ 0x18000000,0x000004d8, +at 0x0000016c : */ 0x18000000,0x000004d8, /* MOVE FROM dsa_dataout+0x00b8, WHEN DATA_OUT -at 0x00000170 : */ 0x18000000,0x000004e0, +at 0x0000016e : */ 0x18000000,0x000004e0, /* MOVE FROM dsa_dataout+0x00c0, WHEN DATA_OUT -at 0x00000172 : */ 0x18000000,0x000004e8, +at 0x00000170 : */ 0x18000000,0x000004e8, /* MOVE FROM dsa_dataout+0x00c8, WHEN DATA_OUT -at 0x00000174 : */ 0x18000000,0x000004f0, +at 0x00000172 : */ 0x18000000,0x000004f0, /* MOVE FROM dsa_dataout+0x00d0, WHEN DATA_OUT -at 0x00000176 : */ 0x18000000,0x000004f8, +at 0x00000174 : */ 0x18000000,0x000004f8, /* MOVE FROM dsa_dataout+0x00d8, WHEN DATA_OUT -at 0x00000178 : */ 0x18000000,0x00000500, +at 0x00000176 : */ 0x18000000,0x00000500, /* MOVE FROM dsa_dataout+0x00e0, WHEN DATA_OUT -at 0x0000017a : */ 0x18000000,0x00000508, +at 0x00000178 : */ 0x18000000,0x00000508, /* MOVE FROM dsa_dataout+0x00e8, WHEN DATA_OUT -at 0x0000017c : */ 0x18000000,0x00000510, +at 0x0000017a : */ 0x18000000,0x00000510, /* MOVE FROM dsa_dataout+0x00f0, WHEN DATA_OUT -at 0x0000017e : */ 0x18000000,0x00000518, +at 0x0000017c : */ 0x18000000,0x00000518, /* MOVE FROM dsa_dataout+0x00f8, WHEN DATA_OUT -at 0x00000180 : */ 0x18000000,0x00000520, +at 0x0000017e : */ 0x18000000,0x00000520, /* MOVE FROM dsa_dataout+0x0100, WHEN DATA_OUT -at 0x00000182 : */ 0x18000000,0x00000528, +at 0x00000180 : */ 0x18000000,0x00000528, /* MOVE FROM dsa_dataout+0x0108, WHEN DATA_OUT -at 0x00000184 : */ 0x18000000,0x00000530, +at 0x00000182 : */ 0x18000000,0x00000530, /* MOVE FROM dsa_dataout+0x0110, WHEN DATA_OUT -at 0x00000186 : */ 0x18000000,0x00000538, +at 0x00000184 : */ 0x18000000,0x00000538, /* MOVE FROM dsa_dataout+0x0118, WHEN DATA_OUT -at 0x00000188 : */ 0x18000000,0x00000540, +at 0x00000186 : */ 0x18000000,0x00000540, /* MOVE FROM dsa_dataout+0x0120, WHEN DATA_OUT -at 0x0000018a : */ 0x18000000,0x00000548, +at 0x00000188 : */ 0x18000000,0x00000548, /* MOVE FROM dsa_dataout+0x0128, WHEN DATA_OUT -at 0x0000018c : */ 0x18000000,0x00000550, +at 0x0000018a : */ 0x18000000,0x00000550, /* MOVE FROM dsa_dataout+0x0130, WHEN DATA_OUT -at 0x0000018e : */ 0x18000000,0x00000558, +at 0x0000018c : */ 0x18000000,0x00000558, /* MOVE FROM dsa_dataout+0x0138, WHEN DATA_OUT -at 0x00000190 : */ 0x18000000,0x00000560, +at 0x0000018e : */ 0x18000000,0x00000560, /* MOVE FROM dsa_dataout+0x0140, WHEN DATA_OUT -at 0x00000192 : */ 0x18000000,0x00000568, +at 0x00000190 : */ 0x18000000,0x00000568, /* MOVE FROM dsa_dataout+0x0148, WHEN DATA_OUT -at 0x00000194 : */ 0x18000000,0x00000570, +at 0x00000192 : */ 0x18000000,0x00000570, /* MOVE FROM dsa_dataout+0x0150, WHEN DATA_OUT -at 0x00000196 : */ 0x18000000,0x00000578, +at 0x00000194 : */ 0x18000000,0x00000578, /* MOVE FROM dsa_dataout+0x0158, WHEN DATA_OUT -at 0x00000198 : */ 0x18000000,0x00000580, +at 0x00000196 : */ 0x18000000,0x00000580, /* MOVE FROM dsa_dataout+0x0160, WHEN DATA_OUT -at 0x0000019a : */ 0x18000000,0x00000588, +at 0x00000198 : */ 0x18000000,0x00000588, /* MOVE FROM dsa_dataout+0x0168, WHEN DATA_OUT -at 0x0000019c : */ 0x18000000,0x00000590, +at 0x0000019a : */ 0x18000000,0x00000590, /* MOVE FROM dsa_dataout+0x0170, WHEN DATA_OUT -at 0x0000019e : */ 0x18000000,0x00000598, +at 0x0000019c : */ 0x18000000,0x00000598, /* MOVE FROM dsa_dataout+0x0178, WHEN DATA_OUT -at 0x000001a0 : */ 0x18000000,0x000005a0, +at 0x0000019e : */ 0x18000000,0x000005a0, /* MOVE FROM dsa_dataout+0x0180, WHEN DATA_OUT -at 0x000001a2 : */ 0x18000000,0x000005a8, +at 0x000001a0 : */ 0x18000000,0x000005a8, /* MOVE FROM dsa_dataout+0x0188, WHEN DATA_OUT -at 0x000001a4 : */ 0x18000000,0x000005b0, +at 0x000001a2 : */ 0x18000000,0x000005b0, /* MOVE FROM dsa_dataout+0x0190, WHEN DATA_OUT -at 0x000001a6 : */ 0x18000000,0x000005b8, +at 0x000001a4 : */ 0x18000000,0x000005b8, /* MOVE FROM dsa_dataout+0x0198, WHEN DATA_OUT -at 0x000001a8 : */ 0x18000000,0x000005c0, +at 0x000001a6 : */ 0x18000000,0x000005c0, /* MOVE FROM dsa_dataout+0x01a0, WHEN DATA_OUT -at 0x000001aa : */ 0x18000000,0x000005c8, +at 0x000001a8 : */ 0x18000000,0x000005c8, /* MOVE FROM dsa_dataout+0x01a8, WHEN DATA_OUT -at 0x000001ac : */ 0x18000000,0x000005d0, +at 0x000001aa : */ 0x18000000,0x000005d0, /* MOVE FROM dsa_dataout+0x01b0, WHEN DATA_OUT -at 0x000001ae : */ 0x18000000,0x000005d8, +at 0x000001ac : */ 0x18000000,0x000005d8, /* MOVE FROM dsa_dataout+0x01b8, WHEN DATA_OUT -at 0x000001b0 : */ 0x18000000,0x000005e0, +at 0x000001ae : */ 0x18000000,0x000005e0, /* MOVE FROM dsa_dataout+0x01c0, WHEN DATA_OUT -at 0x000001b2 : */ 0x18000000,0x000005e8, +at 0x000001b0 : */ 0x18000000,0x000005e8, /* MOVE FROM dsa_dataout+0x01c8, WHEN DATA_OUT -at 0x000001b4 : */ 0x18000000,0x000005f0, +at 0x000001b2 : */ 0x18000000,0x000005f0, /* MOVE FROM dsa_dataout+0x01d0, WHEN DATA_OUT -at 0x000001b6 : */ 0x18000000,0x000005f8, +at 0x000001b4 : */ 0x18000000,0x000005f8, /* MOVE FROM dsa_dataout+0x01d8, WHEN DATA_OUT -at 0x000001b8 : */ 0x18000000,0x00000600, +at 0x000001b6 : */ 0x18000000,0x00000600, /* MOVE FROM dsa_dataout+0x01e0, WHEN DATA_OUT -at 0x000001ba : */ 0x18000000,0x00000608, +at 0x000001b8 : */ 0x18000000,0x00000608, /* MOVE FROM dsa_dataout+0x01e8, WHEN DATA_OUT -at 0x000001bc : */ 0x18000000,0x00000610, +at 0x000001ba : */ 0x18000000,0x00000610, /* MOVE FROM dsa_dataout+0x01f0, WHEN DATA_OUT -at 0x000001be : */ 0x18000000,0x00000618, +at 0x000001bc : */ 0x18000000,0x00000618, /* MOVE FROM dsa_dataout+0x01f8, WHEN DATA_OUT -at 0x000001c0 : */ 0x18000000,0x00000620, +at 0x000001be : */ 0x18000000,0x00000620, /* MOVE FROM dsa_dataout+0x0200, WHEN DATA_OUT -at 0x000001c2 : */ 0x18000000,0x00000628, +at 0x000001c0 : */ 0x18000000,0x00000628, /* MOVE FROM dsa_dataout+0x0208, WHEN DATA_OUT -at 0x000001c4 : */ 0x18000000,0x00000630, +at 0x000001c2 : */ 0x18000000,0x00000630, /* MOVE FROM dsa_dataout+0x0210, WHEN DATA_OUT -at 0x000001c6 : */ 0x18000000,0x00000638, +at 0x000001c4 : */ 0x18000000,0x00000638, /* MOVE FROM dsa_dataout+0x0218, WHEN DATA_OUT -at 0x000001c8 : */ 0x18000000,0x00000640, +at 0x000001c6 : */ 0x18000000,0x00000640, /* MOVE FROM dsa_dataout+0x0220, WHEN DATA_OUT -at 0x000001ca : */ 0x18000000,0x00000648, +at 0x000001c8 : */ 0x18000000,0x00000648, /* MOVE FROM dsa_dataout+0x0228, WHEN DATA_OUT -at 0x000001cc : */ 0x18000000,0x00000650, +at 0x000001ca : */ 0x18000000,0x00000650, /* MOVE FROM dsa_dataout+0x0230, WHEN DATA_OUT -at 0x000001ce : */ 0x18000000,0x00000658, +at 0x000001cc : */ 0x18000000,0x00000658, /* MOVE FROM dsa_dataout+0x0238, WHEN DATA_OUT -at 0x000001d0 : */ 0x18000000,0x00000660, +at 0x000001ce : */ 0x18000000,0x00000660, /* MOVE FROM dsa_dataout+0x0240, WHEN DATA_OUT -at 0x000001d2 : */ 0x18000000,0x00000668, +at 0x000001d0 : */ 0x18000000,0x00000668, /* MOVE FROM dsa_dataout+0x0248, WHEN DATA_OUT -at 0x000001d4 : */ 0x18000000,0x00000670, +at 0x000001d2 : */ 0x18000000,0x00000670, /* MOVE FROM dsa_dataout+0x0250, WHEN DATA_OUT -at 0x000001d6 : */ 0x18000000,0x00000678, +at 0x000001d4 : */ 0x18000000,0x00000678, /* MOVE FROM dsa_dataout+0x0258, WHEN DATA_OUT -at 0x000001d8 : */ 0x18000000,0x00000680, +at 0x000001d6 : */ 0x18000000,0x00000680, /* MOVE FROM dsa_dataout+0x0260, WHEN DATA_OUT -at 0x000001da : */ 0x18000000,0x00000688, +at 0x000001d8 : */ 0x18000000,0x00000688, /* MOVE FROM dsa_dataout+0x0268, WHEN DATA_OUT -at 0x000001dc : */ 0x18000000,0x00000690, +at 0x000001da : */ 0x18000000,0x00000690, /* MOVE FROM dsa_dataout+0x0270, WHEN DATA_OUT -at 0x000001de : */ 0x18000000,0x00000698, +at 0x000001dc : */ 0x18000000,0x00000698, /* MOVE FROM dsa_dataout+0x0278, WHEN DATA_OUT -at 0x000001e0 : */ 0x18000000,0x000006a0, +at 0x000001de : */ 0x18000000,0x000006a0, /* MOVE FROM dsa_dataout+0x0280, WHEN DATA_OUT -at 0x000001e2 : */ 0x18000000,0x000006a8, +at 0x000001e0 : */ 0x18000000,0x000006a8, /* MOVE FROM dsa_dataout+0x0288, WHEN DATA_OUT -at 0x000001e4 : */ 0x18000000,0x000006b0, +at 0x000001e2 : */ 0x18000000,0x000006b0, /* MOVE FROM dsa_dataout+0x0290, WHEN DATA_OUT -at 0x000001e6 : */ 0x18000000,0x000006b8, +at 0x000001e4 : */ 0x18000000,0x000006b8, /* MOVE FROM dsa_dataout+0x0298, WHEN DATA_OUT -at 0x000001e8 : */ 0x18000000,0x000006c0, +at 0x000001e6 : */ 0x18000000,0x000006c0, /* MOVE FROM dsa_dataout+0x02a0, WHEN DATA_OUT -at 0x000001ea : */ 0x18000000,0x000006c8, +at 0x000001e8 : */ 0x18000000,0x000006c8, /* MOVE FROM dsa_dataout+0x02a8, WHEN DATA_OUT -at 0x000001ec : */ 0x18000000,0x000006d0, +at 0x000001ea : */ 0x18000000,0x000006d0, /* MOVE FROM dsa_dataout+0x02b0, WHEN DATA_OUT -at 0x000001ee : */ 0x18000000,0x000006d8, +at 0x000001ec : */ 0x18000000,0x000006d8, /* MOVE FROM dsa_dataout+0x02b8, WHEN DATA_OUT -at 0x000001f0 : */ 0x18000000,0x000006e0, +at 0x000001ee : */ 0x18000000,0x000006e0, /* MOVE FROM dsa_dataout+0x02c0, WHEN DATA_OUT -at 0x000001f2 : */ 0x18000000,0x000006e8, +at 0x000001f0 : */ 0x18000000,0x000006e8, /* MOVE FROM dsa_dataout+0x02c8, WHEN DATA_OUT -at 0x000001f4 : */ 0x18000000,0x000006f0, +at 0x000001f2 : */ 0x18000000,0x000006f0, /* MOVE FROM dsa_dataout+0x02d0, WHEN DATA_OUT -at 0x000001f6 : */ 0x18000000,0x000006f8, +at 0x000001f4 : */ 0x18000000,0x000006f8, /* MOVE FROM dsa_dataout+0x02d8, WHEN DATA_OUT -at 0x000001f8 : */ 0x18000000,0x00000700, +at 0x000001f6 : */ 0x18000000,0x00000700, /* MOVE FROM dsa_dataout+0x02e0, WHEN DATA_OUT -at 0x000001fa : */ 0x18000000,0x00000708, +at 0x000001f8 : */ 0x18000000,0x00000708, /* MOVE FROM dsa_dataout+0x02e8, WHEN DATA_OUT -at 0x000001fc : */ 0x18000000,0x00000710, +at 0x000001fa : */ 0x18000000,0x00000710, /* MOVE FROM dsa_dataout+0x02f0, WHEN DATA_OUT -at 0x000001fe : */ 0x18000000,0x00000718, +at 0x000001fc : */ 0x18000000,0x00000718, /* MOVE FROM dsa_dataout+0x02f8, WHEN DATA_OUT -at 0x00000200 : */ 0x18000000,0x00000720, +at 0x000001fe : */ 0x18000000,0x00000720, /* MOVE FROM dsa_dataout+0x0300, WHEN DATA_OUT -at 0x00000202 : */ 0x18000000,0x00000728, +at 0x00000200 : */ 0x18000000,0x00000728, /* MOVE FROM dsa_dataout+0x0308, WHEN DATA_OUT -at 0x00000204 : */ 0x18000000,0x00000730, +at 0x00000202 : */ 0x18000000,0x00000730, /* MOVE FROM dsa_dataout+0x0310, WHEN DATA_OUT -at 0x00000206 : */ 0x18000000,0x00000738, +at 0x00000204 : */ 0x18000000,0x00000738, /* MOVE FROM dsa_dataout+0x0318, WHEN DATA_OUT -at 0x00000208 : */ 0x18000000,0x00000740, +at 0x00000206 : */ 0x18000000,0x00000740, /* MOVE FROM dsa_dataout+0x0320, WHEN DATA_OUT -at 0x0000020a : */ 0x18000000,0x00000748, +at 0x00000208 : */ 0x18000000,0x00000748, /* MOVE FROM dsa_dataout+0x0328, WHEN DATA_OUT -at 0x0000020c : */ 0x18000000,0x00000750, +at 0x0000020a : */ 0x18000000,0x00000750, /* MOVE FROM dsa_dataout+0x0330, WHEN DATA_OUT -at 0x0000020e : */ 0x18000000,0x00000758, +at 0x0000020c : */ 0x18000000,0x00000758, /* MOVE FROM dsa_dataout+0x0338, WHEN DATA_OUT -at 0x00000210 : */ 0x18000000,0x00000760, +at 0x0000020e : */ 0x18000000,0x00000760, /* MOVE FROM dsa_dataout+0x0340, WHEN DATA_OUT -at 0x00000212 : */ 0x18000000,0x00000768, +at 0x00000210 : */ 0x18000000,0x00000768, /* MOVE FROM dsa_dataout+0x0348, WHEN DATA_OUT -at 0x00000214 : */ 0x18000000,0x00000770, +at 0x00000212 : */ 0x18000000,0x00000770, /* MOVE FROM dsa_dataout+0x0350, WHEN DATA_OUT -at 0x00000216 : */ 0x18000000,0x00000778, +at 0x00000214 : */ 0x18000000,0x00000778, /* MOVE FROM dsa_dataout+0x0358, WHEN DATA_OUT -at 0x00000218 : */ 0x18000000,0x00000780, +at 0x00000216 : */ 0x18000000,0x00000780, /* MOVE FROM dsa_dataout+0x0360, WHEN DATA_OUT -at 0x0000021a : */ 0x18000000,0x00000788, +at 0x00000218 : */ 0x18000000,0x00000788, /* MOVE FROM dsa_dataout+0x0368, WHEN DATA_OUT -at 0x0000021c : */ 0x18000000,0x00000790, +at 0x0000021a : */ 0x18000000,0x00000790, /* MOVE FROM dsa_dataout+0x0370, WHEN DATA_OUT -at 0x0000021e : */ 0x18000000,0x00000798, +at 0x0000021c : */ 0x18000000,0x00000798, /* MOVE FROM dsa_dataout+0x0378, WHEN DATA_OUT -at 0x00000220 : */ 0x18000000,0x000007a0, +at 0x0000021e : */ 0x18000000,0x000007a0, /* MOVE FROM dsa_dataout+0x0380, WHEN DATA_OUT -at 0x00000222 : */ 0x18000000,0x000007a8, +at 0x00000220 : */ 0x18000000,0x000007a8, /* MOVE FROM dsa_dataout+0x0388, WHEN DATA_OUT -at 0x00000224 : */ 0x18000000,0x000007b0, +at 0x00000222 : */ 0x18000000,0x000007b0, /* MOVE FROM dsa_dataout+0x0390, WHEN DATA_OUT -at 0x00000226 : */ 0x18000000,0x000007b8, +at 0x00000224 : */ 0x18000000,0x000007b8, /* MOVE FROM dsa_dataout+0x0398, WHEN DATA_OUT -at 0x00000228 : */ 0x18000000,0x000007c0, +at 0x00000226 : */ 0x18000000,0x000007c0, /* MOVE FROM dsa_dataout+0x03a0, WHEN DATA_OUT -at 0x0000022a : */ 0x18000000,0x000007c8, +at 0x00000228 : */ 0x18000000,0x000007c8, /* MOVE FROM dsa_dataout+0x03a8, WHEN DATA_OUT -at 0x0000022c : */ 0x18000000,0x000007d0, +at 0x0000022a : */ 0x18000000,0x000007d0, /* MOVE FROM dsa_dataout+0x03b0, WHEN DATA_OUT -at 0x0000022e : */ 0x18000000,0x000007d8, +at 0x0000022c : */ 0x18000000,0x000007d8, /* MOVE FROM dsa_dataout+0x03b8, WHEN DATA_OUT -at 0x00000230 : */ 0x18000000,0x000007e0, +at 0x0000022e : */ 0x18000000,0x000007e0, /* MOVE FROM dsa_dataout+0x03c0, WHEN DATA_OUT -at 0x00000232 : */ 0x18000000,0x000007e8, +at 0x00000230 : */ 0x18000000,0x000007e8, /* MOVE FROM dsa_dataout+0x03c8, WHEN DATA_OUT -at 0x00000234 : */ 0x18000000,0x000007f0, +at 0x00000232 : */ 0x18000000,0x000007f0, /* MOVE FROM dsa_dataout+0x03d0, WHEN DATA_OUT -at 0x00000236 : */ 0x18000000,0x000007f8, +at 0x00000234 : */ 0x18000000,0x000007f8, /* MOVE FROM dsa_dataout+0x03d8, WHEN DATA_OUT -at 0x00000238 : */ 0x18000000,0x00000800, +at 0x00000236 : */ 0x18000000,0x00000800, /* MOVE FROM dsa_dataout+0x03e0, WHEN DATA_OUT -at 0x0000023a : */ 0x18000000,0x00000808, +at 0x00000238 : */ 0x18000000,0x00000808, /* MOVE FROM dsa_dataout+0x03e8, WHEN DATA_OUT -at 0x0000023c : */ 0x18000000,0x00000810, +at 0x0000023a : */ 0x18000000,0x00000810, /* MOVE FROM dsa_dataout+0x03f0, WHEN DATA_OUT -at 0x0000023e : */ 0x18000000,0x00000818, +at 0x0000023c : */ 0x18000000,0x00000818, /* MOVE FROM dsa_dataout+0x03f8, WHEN DATA_OUT -at 0x00000240 : */ 0x18000000,0x00000820, +at 0x0000023e : */ 0x18000000,0x00000820, /* ENTRY end_data_trans end_data_trans: redo_msgin3: JUMP get_status, WHEN STATUS -at 0x00000242 : */ 0x830b0000,0x000000a0, +at 0x00000240 : */ 0x830b0000,0x00000098, /* JUMP get_msgin3, WHEN MSG_IN -at 0x00000244 : */ 0x870b0000,0x00000b20, +at 0x00000242 : */ 0x870b0000,0x00000b78, /* INT int_data_bad_phase -at 0x00000246 : */ 0x98080000,0xab93000b, +at 0x00000244 : */ 0x98080000,0xab93000b, /* get_msgin1: MOVE SCRATCH0 | had_msgin TO SCRATCH0 -at 0x00000248 : */ 0x7a344000,0x00000000, +at 0x00000246 : */ 0x7a344000,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x0000024a : */ 0x0f000001,0x00000000, +at 0x00000248 : */ 0x0f000001,0x00000000, /* JUMP ext_msg1, IF 0x01 ; Extended Message -at 0x0000024c : */ 0x800c0001,0x00000968, +at 0x0000024a : */ 0x800c0001,0x00000960, /* JUMP ignore_msg1, IF 0x02 ; Save Data Pointers -at 0x0000024e : */ 0x800c0002,0x00000958, +at 0x0000024c : */ 0x800c0002,0x00000950, /* JUMP ignore_msg1, IF 0x03 ; Save Restore Pointers -at 0x00000250 : */ 0x800c0003,0x00000958, +at 0x0000024e : */ 0x800c0003,0x00000950, /* JUMP disc1, IF 0x04 ; Disconnect -at 0x00000252 : */ 0x800c0004,0x000009c8, +at 0x00000250 : */ 0x800c0004,0x000009f0, /* INT int_bad_msg1 -at 0x00000254 : */ 0x98080000,0xab930006, +at 0x00000252 : */ 0x98080000,0xab930006, /* ignore_msg1: CLEAR ACK -at 0x00000256 : */ 0x60000040,0x00000000, +at 0x00000254 : */ 0x60000040,0x00000000, /* JUMP redo_msgin1 -at 0x00000258 : */ 0x80080000,0x00000058, +at 0x00000256 : */ 0x80080000,0x00000050, /* ext_msg1: MOVE SCRATCH0 | had_extmsg TO SCRATCH0 -at 0x0000025a : */ 0x7a348000,0x00000000, +at 0x00000258 : */ 0x7a348000,0x00000000, /* CLEAR ACK -at 0x0000025c : */ 0x60000040,0x00000000, +at 0x0000025a : */ 0x60000040,0x00000000, /* MOVE 1, msgin_buf + 1, WHEN MSG_IN -at 0x0000025e : */ 0x0f000001,0x00000001, +at 0x0000025c : */ 0x0f000001,0x00000001, /* - JUMP ext_msg1a, IF 0x03 + JUMP reject_msg1, IF NOT 0x03 ; Only handle SDTR -at 0x00000260 : */ 0x800c0003,0x00000990, +at 0x0000025e : */ 0x80040003,0x000009b0, /* - INT int_bad_extmsg1a + CLEAR ACK -at 0x00000262 : */ 0x98080000,0xab930000, +at 0x00000260 : */ 0x60000040,0x00000000, +/* + MOVE 1, msgin_buf + 2, WHEN MSG_IN + +at 0x00000262 : */ 0x0f000001,0x00000002, +/* + JUMP reject_msg1, IF NOT 0x01 ; Only handle SDTR + +at 0x00000264 : */ 0x80040001,0x000009b0, /* -ext_msg1a: CLEAR ACK -at 0x00000264 : */ 0x60000040,0x00000000, +at 0x00000266 : */ 0x60000040,0x00000000, /* - MOVE 1, msgin_buf + 2, WHEN MSG_IN + MOVE 2, msgin_buf + 3, WHEN MSG_IN -at 0x00000266 : */ 0x0f000001,0x00000002, +at 0x00000268 : */ 0x0f000002,0x00000003, /* - JUMP ext_msg1b, IF 0x01 ; Must be SDTR + INT int_msg_sdtr1 + +at 0x0000026a : */ 0x98080000,0xab93000c, +/* +reject_msg1: + MOVE SCRATCH1 | did_reject TO SCRATCH1 -at 0x00000268 : */ 0x800c0001,0x000009b0, +at 0x0000026c : */ 0x7a350100,0x00000000, /* - INT int_bad_extmsg1b + SET ATN -at 0x0000026a : */ 0x98080000,0xab930001, +at 0x0000026e : */ 0x58000008,0x00000000, /* -ext_msg1b: CLEAR ACK -at 0x0000026c : */ 0x60000040,0x00000000, +at 0x00000270 : */ 0x60000040,0x00000000, /* - MOVE 2, msgin_buf + 3, WHEN MSG_IN + JUMP reject_msg1a, WHEN NOT MSG_IN -at 0x0000026e : */ 0x0f000002,0x00000003, +at 0x00000272 : */ 0x87030000,0x000009e0, /* - INT int_msg_sdtr1 + MOVE 1, msgin_buf + 7, WHEN MSG_IN -at 0x00000270 : */ 0x98080000,0xab93000c, +at 0x00000274 : */ 0x0f000001,0x00000007, +/* + JUMP reject_msg1 + +at 0x00000276 : */ 0x80080000,0x000009b0, +/* +reject_msg1a: + MOVE 1, msg_reject, WHEN MSG_OUT + +at 0x00000278 : */ 0x0e000001,0x00000000, +/* + JUMP redo_msgin1 + +at 0x0000027a : */ 0x80080000,0x00000050, /* disc1: CLEAR ACK -at 0x00000272 : */ 0x60000040,0x00000000, +at 0x0000027c : */ 0x60000040,0x00000000, /* ENTRY wait_disc1 wait_disc1: WAIT DISCONNECT -at 0x00000274 : */ 0x48000000,0x00000000, +at 0x0000027e : */ 0x48000000,0x00000000, /* INT int_disc1 -at 0x00000276 : */ 0x98080000,0xab930019, +at 0x00000280 : */ 0x98080000,0xab930019, /* ENTRY resume_msgin1a resume_msgin1a: CLEAR ACK -at 0x00000278 : */ 0x60000040,0x00000000, +at 0x00000282 : */ 0x60000040,0x00000000, /* JUMP redo_msgin1 -at 0x0000027a : */ 0x80080000,0x00000058, +at 0x00000284 : */ 0x80080000,0x00000050, /* ENTRY resume_msgin1b resume_msgin1b: SET ATN -at 0x0000027c : */ 0x58000008,0x00000000, +at 0x00000286 : */ 0x58000008,0x00000000, /* CLEAR ACK -at 0x0000027e : */ 0x60000040,0x00000000, +at 0x00000288 : */ 0x60000040,0x00000000, /* INT int_no_msgout1, WHEN NOT MSG_OUT -at 0x00000280 : */ 0x9e030000,0xab93000f, +at 0x0000028a : */ 0x9e030000,0xab93000f, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x00000282 : */ 0x7a340200,0x00000000, +at 0x0000028c : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x00000284 : */ 0x1e000000,0x00000008, +at 0x0000028e : */ 0x1e000000,0x00000008, /* JUMP redo_msgin1 -at 0x00000286 : */ 0x80080000,0x00000058, +at 0x00000290 : */ 0x80080000,0x00000050, /* get_msgin2: MOVE SCRATCH0 | had_msgin TO SCRATCH0 -at 0x00000288 : */ 0x7a344000,0x00000000, +at 0x00000292 : */ 0x7a344000,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x0000028a : */ 0x0f000001,0x00000000, +at 0x00000294 : */ 0x0f000001,0x00000000, /* JUMP ext_msg2, IF 0x01 ; Extended Message -at 0x0000028c : */ 0x800c0001,0x00000a68, +at 0x00000296 : */ 0x800c0001,0x00000a90, /* JUMP ignore_msg2, IF 0x02 ; Save Data Pointers -at 0x0000028e : */ 0x800c0002,0x00000a58, +at 0x00000298 : */ 0x800c0002,0x00000a80, /* JUMP ignore_msg2, IF 0x03 ; Save Restore Pointers -at 0x00000290 : */ 0x800c0003,0x00000a58, +at 0x0000029a : */ 0x800c0003,0x00000a80, /* JUMP disc2, IF 0x04 ; Disconnect -at 0x00000292 : */ 0x800c0004,0x00000ac8, +at 0x0000029c : */ 0x800c0004,0x00000b20, /* INT int_bad_msg2 -at 0x00000294 : */ 0x98080000,0xab930007, +at 0x0000029e : */ 0x98080000,0xab930007, /* ignore_msg2: CLEAR ACK -at 0x00000296 : */ 0x60000040,0x00000000, +at 0x000002a0 : */ 0x60000040,0x00000000, /* JUMP redo_msgin2 -at 0x00000298 : */ 0x80080000,0x00000078, +at 0x000002a2 : */ 0x80080000,0x00000070, /* ext_msg2: MOVE SCRATCH0 | had_extmsg TO SCRATCH0 -at 0x0000029a : */ 0x7a348000,0x00000000, +at 0x000002a4 : */ 0x7a348000,0x00000000, /* CLEAR ACK -at 0x0000029c : */ 0x60000040,0x00000000, +at 0x000002a6 : */ 0x60000040,0x00000000, /* MOVE 1, msgin_buf + 1, WHEN MSG_IN -at 0x0000029e : */ 0x0f000001,0x00000001, +at 0x000002a8 : */ 0x0f000001,0x00000001, +/* + JUMP reject_msg2, IF NOT 0x03 ; Only handle SDTR + +at 0x000002aa : */ 0x80040003,0x00000ae0, +/* + CLEAR ACK + +at 0x000002ac : */ 0x60000040,0x00000000, /* - JUMP ext_msg2a, IF 0x03 + MOVE 1, msgin_buf + 2, WHEN MSG_IN -at 0x000002a0 : */ 0x800c0003,0x00000a90, +at 0x000002ae : */ 0x0f000001,0x00000002, /* - INT int_bad_extmsg2a + JUMP reject_msg2, IF NOT 0x01 ; Only handle SDTR -at 0x000002a2 : */ 0x98080000,0xab930002, +at 0x000002b0 : */ 0x80040001,0x00000ae0, /* -ext_msg2a: CLEAR ACK -at 0x000002a4 : */ 0x60000040,0x00000000, +at 0x000002b2 : */ 0x60000040,0x00000000, /* - MOVE 1, msgin_buf + 2, WHEN MSG_IN + MOVE 2, msgin_buf + 3, WHEN MSG_IN + +at 0x000002b4 : */ 0x0f000002,0x00000003, +/* + INT int_msg_sdtr2 -at 0x000002a6 : */ 0x0f000001,0x00000002, +at 0x000002b6 : */ 0x98080000,0xab93000d, /* - JUMP ext_msg2b, IF 0x01 ; Must be SDTR +reject_msg2: + MOVE SCRATCH1 | did_reject TO SCRATCH1 -at 0x000002a8 : */ 0x800c0001,0x00000ab0, +at 0x000002b8 : */ 0x7a350100,0x00000000, /* - INT int_bad_extmsg2b + SET ATN -at 0x000002aa : */ 0x98080000,0xab930003, +at 0x000002ba : */ 0x58000008,0x00000000, /* -ext_msg2b: CLEAR ACK -at 0x000002ac : */ 0x60000040,0x00000000, +at 0x000002bc : */ 0x60000040,0x00000000, /* - MOVE 2, msgin_buf + 3, WHEN MSG_IN + JUMP reject_msg2a, WHEN NOT MSG_IN -at 0x000002ae : */ 0x0f000002,0x00000003, +at 0x000002be : */ 0x87030000,0x00000b10, /* - INT int_msg_sdtr2 + MOVE 1, msgin_buf + 7, WHEN MSG_IN + +at 0x000002c0 : */ 0x0f000001,0x00000007, +/* + JUMP reject_msg2 + +at 0x000002c2 : */ 0x80080000,0x00000ae0, +/* +reject_msg2a: + MOVE 1, msg_reject, WHEN MSG_OUT + +at 0x000002c4 : */ 0x0e000001,0x00000000, +/* + JUMP redo_msgin2 -at 0x000002b0 : */ 0x98080000,0xab93000d, +at 0x000002c6 : */ 0x80080000,0x00000070, /* disc2: CLEAR ACK -at 0x000002b2 : */ 0x60000040,0x00000000, +at 0x000002c8 : */ 0x60000040,0x00000000, /* ENTRY wait_disc2 wait_disc2: WAIT DISCONNECT -at 0x000002b4 : */ 0x48000000,0x00000000, +at 0x000002ca : */ 0x48000000,0x00000000, /* INT int_disc2 -at 0x000002b6 : */ 0x98080000,0xab93001a, +at 0x000002cc : */ 0x98080000,0xab93001a, /* ENTRY resume_msgin2a resume_msgin2a: CLEAR ACK -at 0x000002b8 : */ 0x60000040,0x00000000, +at 0x000002ce : */ 0x60000040,0x00000000, /* JUMP redo_msgin2 -at 0x000002ba : */ 0x80080000,0x00000078, +at 0x000002d0 : */ 0x80080000,0x00000070, /* ENTRY resume_msgin2b resume_msgin2b: SET ATN -at 0x000002bc : */ 0x58000008,0x00000000, +at 0x000002d2 : */ 0x58000008,0x00000000, /* CLEAR ACK -at 0x000002be : */ 0x60000040,0x00000000, +at 0x000002d4 : */ 0x60000040,0x00000000, /* INT int_no_msgout2, WHEN NOT MSG_OUT -at 0x000002c0 : */ 0x9e030000,0xab930010, +at 0x000002d6 : */ 0x9e030000,0xab930010, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x000002c2 : */ 0x7a340200,0x00000000, +at 0x000002d8 : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x000002c4 : */ 0x1e000000,0x00000008, +at 0x000002da : */ 0x1e000000,0x00000008, /* JUMP redo_msgin2 -at 0x000002c6 : */ 0x80080000,0x00000078, +at 0x000002dc : */ 0x80080000,0x00000070, /* get_msgin3: MOVE SCRATCH0 | had_msgin TO SCRATCH0 -at 0x000002c8 : */ 0x7a344000,0x00000000, +at 0x000002de : */ 0x7a344000,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x000002ca : */ 0x0f000001,0x00000000, +at 0x000002e0 : */ 0x0f000001,0x00000000, /* JUMP ext_msg3, IF 0x01 ; Extended Message -at 0x000002cc : */ 0x800c0001,0x00000b68, +at 0x000002e2 : */ 0x800c0001,0x00000bc0, /* JUMP ignore_msg3, IF 0x02 ; Save Data Pointers -at 0x000002ce : */ 0x800c0002,0x00000b58, +at 0x000002e4 : */ 0x800c0002,0x00000bb0, /* JUMP ignore_msg3, IF 0x03 ; Save Restore Pointers -at 0x000002d0 : */ 0x800c0003,0x00000b58, +at 0x000002e6 : */ 0x800c0003,0x00000bb0, /* JUMP disc3, IF 0x04 ; Disconnect -at 0x000002d2 : */ 0x800c0004,0x00000bc8, +at 0x000002e8 : */ 0x800c0004,0x00000c50, /* INT int_bad_msg3 -at 0x000002d4 : */ 0x98080000,0xab930008, +at 0x000002ea : */ 0x98080000,0xab930008, /* ignore_msg3: CLEAR ACK -at 0x000002d6 : */ 0x60000040,0x00000000, +at 0x000002ec : */ 0x60000040,0x00000000, /* JUMP redo_msgin3 -at 0x000002d8 : */ 0x80080000,0x00000908, +at 0x000002ee : */ 0x80080000,0x00000900, /* ext_msg3: MOVE SCRATCH0 | had_extmsg TO SCRATCH0 -at 0x000002da : */ 0x7a348000,0x00000000, +at 0x000002f0 : */ 0x7a348000,0x00000000, /* CLEAR ACK -at 0x000002dc : */ 0x60000040,0x00000000, +at 0x000002f2 : */ 0x60000040,0x00000000, /* MOVE 1, msgin_buf + 1, WHEN MSG_IN -at 0x000002de : */ 0x0f000001,0x00000001, +at 0x000002f4 : */ 0x0f000001,0x00000001, /* - JUMP ext_msg3a, IF 0x03 + JUMP reject_msg3, IF NOT 0x03 ; Only handle SDTR -at 0x000002e0 : */ 0x800c0003,0x00000b90, +at 0x000002f6 : */ 0x80040003,0x00000c10, /* - INT int_bad_extmsg3a + CLEAR ACK -at 0x000002e2 : */ 0x98080000,0xab930004, +at 0x000002f8 : */ 0x60000040,0x00000000, +/* + MOVE 1, msgin_buf + 2, WHEN MSG_IN + +at 0x000002fa : */ 0x0f000001,0x00000002, +/* + JUMP reject_msg3, IF NOT 0x01 ; Only handle SDTR + +at 0x000002fc : */ 0x80040001,0x00000c10, /* -ext_msg3a: CLEAR ACK -at 0x000002e4 : */ 0x60000040,0x00000000, +at 0x000002fe : */ 0x60000040,0x00000000, /* - MOVE 1, msgin_buf + 2, WHEN MSG_IN + MOVE 2, msgin_buf + 3, WHEN MSG_IN + +at 0x00000300 : */ 0x0f000002,0x00000003, +/* + INT int_msg_sdtr3 -at 0x000002e6 : */ 0x0f000001,0x00000002, +at 0x00000302 : */ 0x98080000,0xab93000e, /* - JUMP ext_msg3b, IF 0x01 ; Must be SDTR +reject_msg3: + MOVE SCRATCH1 | did_reject TO SCRATCH1 -at 0x000002e8 : */ 0x800c0001,0x00000bb0, +at 0x00000304 : */ 0x7a350100,0x00000000, /* - INT int_bad_extmsg3b + SET ATN -at 0x000002ea : */ 0x98080000,0xab930005, +at 0x00000306 : */ 0x58000008,0x00000000, /* -ext_msg3b: CLEAR ACK -at 0x000002ec : */ 0x60000040,0x00000000, +at 0x00000308 : */ 0x60000040,0x00000000, /* - MOVE 2, msgin_buf + 3, WHEN MSG_IN + JUMP reject_msg3a, WHEN NOT MSG_IN -at 0x000002ee : */ 0x0f000002,0x00000003, +at 0x0000030a : */ 0x87030000,0x00000c40, /* - INT int_msg_sdtr3 + MOVE 1, msgin_buf + 7, WHEN MSG_IN + +at 0x0000030c : */ 0x0f000001,0x00000007, +/* + JUMP reject_msg3 + +at 0x0000030e : */ 0x80080000,0x00000c10, +/* +reject_msg3a: + MOVE 1, msg_reject, WHEN MSG_OUT -at 0x000002f0 : */ 0x98080000,0xab93000e, +at 0x00000310 : */ 0x0e000001,0x00000000, +/* + JUMP redo_msgin3 + +at 0x00000312 : */ 0x80080000,0x00000900, /* disc3: CLEAR ACK -at 0x000002f2 : */ 0x60000040,0x00000000, +at 0x00000314 : */ 0x60000040,0x00000000, /* ENTRY wait_disc3 wait_disc3: WAIT DISCONNECT -at 0x000002f4 : */ 0x48000000,0x00000000, +at 0x00000316 : */ 0x48000000,0x00000000, /* INT int_disc3 -at 0x000002f6 : */ 0x98080000,0xab93001b, +at 0x00000318 : */ 0x98080000,0xab93001b, /* ENTRY resume_msgin3a resume_msgin3a: CLEAR ACK -at 0x000002f8 : */ 0x60000040,0x00000000, +at 0x0000031a : */ 0x60000040,0x00000000, /* JUMP redo_msgin3 -at 0x000002fa : */ 0x80080000,0x00000908, +at 0x0000031c : */ 0x80080000,0x00000900, /* ENTRY resume_msgin3b resume_msgin3b: SET ATN -at 0x000002fc : */ 0x58000008,0x00000000, +at 0x0000031e : */ 0x58000008,0x00000000, /* CLEAR ACK -at 0x000002fe : */ 0x60000040,0x00000000, +at 0x00000320 : */ 0x60000040,0x00000000, /* INT int_no_msgout3, WHEN NOT MSG_OUT -at 0x00000300 : */ 0x9e030000,0xab930011, +at 0x00000322 : */ 0x9e030000,0xab930011, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x00000302 : */ 0x7a340200,0x00000000, +at 0x00000324 : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x00000304 : */ 0x1e000000,0x00000008, +at 0x00000326 : */ 0x1e000000,0x00000008, /* JUMP redo_msgin3 -at 0x00000306 : */ 0x80080000,0x00000908, +at 0x00000328 : */ 0x80080000,0x00000900, /* ENTRY resume_rej_ident resume_rej_ident: CLEAR ATN -at 0x00000308 : */ 0x60000008,0x00000000, +at 0x0000032a : */ 0x60000008,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x0000030a : */ 0x0f000001,0x00000000, +at 0x0000032c : */ 0x0f000001,0x00000000, /* INT int_not_rej, IF NOT 0x07 ; Reject -at 0x0000030c : */ 0x98040007,0xab93001c, +at 0x0000032e : */ 0x98040007,0xab93001c, /* CLEAR ACK -at 0x0000030e : */ 0x60000040,0x00000000, +at 0x00000330 : */ 0x60000040,0x00000000, /* JUMP done_ident -at 0x00000310 : */ 0x80080000,0x00000050, +at 0x00000332 : */ 0x80080000,0x00000048, /* ENTRY reselect @@ -1716,73 +1784,92 @@ ; Disable selection timer MOVE CTEST7 | 0x10 TO CTEST7 -at 0x00000312 : */ 0x7a1b1000,0x00000000, +at 0x00000334 : */ 0x7a1b1000,0x00000000, /* WAIT RESELECT resel_err -at 0x00000314 : */ 0x50000000,0x00000c70, +at 0x00000336 : */ 0x50000000,0x00000cf8, /* INT int_resel_not_msgin, WHEN NOT MSG_IN -at 0x00000316 : */ 0x9f030000,0xab930016, +at 0x00000338 : */ 0x9f030000,0xab930016, /* MOVE 1, reselected_identify, WHEN MSG_IN -at 0x00000318 : */ 0x0f000001,0x00000000, +at 0x0000033a : */ 0x0f000001,0x00000000, /* INT int_reselected -at 0x0000031a : */ 0x98080000,0xab930017, +at 0x0000033c : */ 0x98080000,0xab930017, /* resel_err: MOVE CTEST2 & 0x40 TO SFBR -at 0x0000031c : */ 0x74164000,0x00000000, +at 0x0000033e : */ 0x74164000,0x00000000, /* JUMP selected, IF 0x00 -at 0x0000031e : */ 0x800c0000,0x00000cb0, +at 0x00000340 : */ 0x800c0000,0x00000d38, /* MOVE SFBR & 0 TO SFBR -at 0x00000320 : */ 0x7c080000,0x00000000, +at 0x00000342 : */ 0x7c080000,0x00000000, /* ENTRY patch_new_dsa patch_new_dsa: MOVE SFBR | 0x11 TO DSA0 -at 0x00000322 : */ 0x6a101100,0x00000000, +at 0x00000344 : */ 0x6a101100,0x00000000, /* MOVE SFBR | 0x22 TO DSA1 -at 0x00000324 : */ 0x6a112200,0x00000000, +at 0x00000346 : */ 0x6a112200,0x00000000, /* MOVE SFBR | 0x33 TO DSA2 -at 0x00000326 : */ 0x6a123300,0x00000000, +at 0x00000348 : */ 0x6a123300,0x00000000, /* MOVE SFBR | 0x44 TO DSA3 -at 0x00000328 : */ 0x6a134400,0x00000000, +at 0x0000034a : */ 0x6a134400,0x00000000, /* JUMP do_select -at 0x0000032a : */ 0x80080000,0x00000000, +at 0x0000034c : */ 0x80080000,0x00000000, /* selected: INT int_selected -at 0x0000032c : */ 0x98080000,0xab930018, +at 0x0000034e : */ 0x98080000,0xab930018, +/* + +ENTRY test1 +test1: + MOVE MEMORY 4, test1_src, test1_dst + +at 0x00000350 : */ 0xc0000004,0x00000000,0x00000000, +/* + INT int_test1 + +at 0x00000353 : */ 0x98080000,0xab93001d, +}; + +#define A_did_reject 0x00000001 +static u32 A_did_reject_used[] __attribute((unused)) = { + 0x0000026c, + 0x000002b8, + 0x00000304, }; #define A_dsa_cmnd 0x00000010 static u32 A_dsa_cmnd_used[] __attribute((unused)) = { - 0x0000001d, + 0x0000001b, }; #define A_dsa_datain 0x00000028 static u32 A_dsa_datain_used[] __attribute((unused)) = { + 0x0000003b, 0x0000003d, 0x0000003f, 0x00000041, @@ -1910,11 +1997,11 @@ 0x00000135, 0x00000137, 0x00000139, - 0x0000013b, }; #define A_dsa_dataout 0x00000428 static u32 A_dsa_dataout_used[] __attribute((unused)) = { + 0x00000141, 0x00000143, 0x00000145, 0x00000147, @@ -2042,25 +2129,24 @@ 0x0000023b, 0x0000023d, 0x0000023f, - 0x00000241, }; #define A_dsa_msgin 0x00000020 static u32 A_dsa_msgin_used[] __attribute((unused)) = { - 0x0000002f, + 0x0000002d, }; #define A_dsa_msgout 0x00000008 static u32 A_dsa_msgout_used[] __attribute((unused)) = { - 0x00000013, - 0x00000285, - 0x000002c5, - 0x00000305, + 0x00000011, + 0x0000028f, + 0x000002db, + 0x00000327, }; #define A_dsa_select 0x00000000 static u32 A_dsa_select_used[] __attribute((unused)) = { - 0x00000006, + 0x00000004, }; #define A_dsa_size 0x00000828 @@ -2069,285 +2155,290 @@ #define A_dsa_status 0x00000018 static u32 A_dsa_status_used[] __attribute((unused)) = { - 0x0000002b, + 0x00000029, }; #define A_had_cmdout 0x00000004 static u32 A_had_cmdout_used[] __attribute((unused)) = { - 0x0000001a, + 0x00000018, }; #define A_had_datain 0x00000008 static u32 A_had_datain_used[] __attribute((unused)) = { - 0x00000038, + 0x00000036, }; #define A_had_dataout 0x00000010 static u32 A_had_dataout_used[] __attribute((unused)) = { - 0x0000013e, + 0x0000013c, }; #define A_had_extmsg 0x00000080 static u32 A_had_extmsg_used[] __attribute((unused)) = { - 0x0000025a, - 0x0000029a, - 0x000002da, + 0x00000258, + 0x000002a4, + 0x000002f0, }; #define A_had_msgin 0x00000040 static u32 A_had_msgin_used[] __attribute((unused)) = { - 0x00000248, - 0x00000288, - 0x000002c8, + 0x00000246, + 0x00000292, + 0x000002de, }; #define A_had_msgout 0x00000002 static u32 A_had_msgout_used[] __attribute((unused)) = { - 0x00000010, - 0x00000282, - 0x000002c2, - 0x00000302, + 0x0000000e, + 0x0000028c, + 0x000002d8, + 0x00000324, }; #define A_had_select 0x00000001 static u32 A_had_select_used[] __attribute((unused)) = { - 0x0000000c, + 0x0000000a, }; #define A_had_status 0x00000020 static u32 A_had_status_used[] __attribute((unused)) = { }; -#define A_int_bad_extmsg1a 0xab930000 -static u32 A_int_bad_extmsg1a_used[] __attribute((unused)) = { - 0x00000263, -}; - -#define A_int_bad_extmsg1b 0xab930001 -static u32 A_int_bad_extmsg1b_used[] __attribute((unused)) = { - 0x0000026b, -}; - -#define A_int_bad_extmsg2a 0xab930002 -static u32 A_int_bad_extmsg2a_used[] __attribute((unused)) = { - 0x000002a3, -}; - -#define A_int_bad_extmsg2b 0xab930003 -static u32 A_int_bad_extmsg2b_used[] __attribute((unused)) = { - 0x000002ab, -}; - -#define A_int_bad_extmsg3a 0xab930004 -static u32 A_int_bad_extmsg3a_used[] __attribute((unused)) = { - 0x000002e3, -}; - -#define A_int_bad_extmsg3b 0xab930005 -static u32 A_int_bad_extmsg3b_used[] __attribute((unused)) = { - 0x000002eb, -}; - #define A_int_bad_msg1 0xab930006 static u32 A_int_bad_msg1_used[] __attribute((unused)) = { - 0x00000255, + 0x00000253, }; #define A_int_bad_msg2 0xab930007 static u32 A_int_bad_msg2_used[] __attribute((unused)) = { - 0x00000295, + 0x0000029f, }; #define A_int_bad_msg3 0xab930008 static u32 A_int_bad_msg3_used[] __attribute((unused)) = { - 0x000002d5, + 0x000002eb, }; #define A_int_cmd_bad_phase 0xab930009 static u32 A_int_cmd_bad_phase_used[] __attribute((unused)) = { - 0x00000027, + 0x00000025, }; #define A_int_cmd_complete 0xab93000a static u32 A_int_cmd_complete_used[] __attribute((unused)) = { - 0x00000037, + 0x00000035, }; #define A_int_data_bad_phase 0xab93000b static u32 A_int_data_bad_phase_used[] __attribute((unused)) = { - 0x00000247, + 0x00000245, }; #define A_int_disc1 0xab930019 static u32 A_int_disc1_used[] __attribute((unused)) = { - 0x00000277, + 0x00000281, }; #define A_int_disc2 0xab93001a static u32 A_int_disc2_used[] __attribute((unused)) = { - 0x000002b7, + 0x000002cd, }; #define A_int_disc3 0xab93001b static u32 A_int_disc3_used[] __attribute((unused)) = { - 0x000002f7, + 0x00000319, }; #define A_int_msg_sdtr1 0xab93000c static u32 A_int_msg_sdtr1_used[] __attribute((unused)) = { - 0x00000271, + 0x0000026b, }; #define A_int_msg_sdtr2 0xab93000d static u32 A_int_msg_sdtr2_used[] __attribute((unused)) = { - 0x000002b1, + 0x000002b7, }; #define A_int_msg_sdtr3 0xab93000e static u32 A_int_msg_sdtr3_used[] __attribute((unused)) = { - 0x000002f1, + 0x00000303, }; #define A_int_no_msgout1 0xab93000f static u32 A_int_no_msgout1_used[] __attribute((unused)) = { - 0x00000281, + 0x0000028b, }; #define A_int_no_msgout2 0xab930010 static u32 A_int_no_msgout2_used[] __attribute((unused)) = { - 0x000002c1, + 0x000002d7, }; #define A_int_no_msgout3 0xab930011 static u32 A_int_no_msgout3_used[] __attribute((unused)) = { - 0x00000301, + 0x00000323, }; #define A_int_not_cmd_complete 0xab930012 static u32 A_int_not_cmd_complete_used[] __attribute((unused)) = { - 0x00000031, + 0x0000002f, }; #define A_int_not_rej 0xab93001c static u32 A_int_not_rej_used[] __attribute((unused)) = { - 0x0000030d, + 0x0000032f, }; #define A_int_resel_not_msgin 0xab930016 static u32 A_int_resel_not_msgin_used[] __attribute((unused)) = { - 0x00000317, + 0x00000339, }; #define A_int_reselected 0xab930017 static u32 A_int_reselected_used[] __attribute((unused)) = { - 0x0000031b, + 0x0000033d, }; #define A_int_sel_no_ident 0xab930013 static u32 A_int_sel_no_ident_used[] __attribute((unused)) = { - 0x0000000f, + 0x0000000d, }; #define A_int_sel_not_cmd 0xab930014 static u32 A_int_sel_not_cmd_used[] __attribute((unused)) = { - 0x00000019, + 0x00000017, }; #define A_int_selected 0xab930018 static u32 A_int_selected_used[] __attribute((unused)) = { - 0x0000032d, + 0x0000034f, }; #define A_int_status_not_msgin 0xab930015 static u32 A_int_status_not_msgin_used[] __attribute((unused)) = { - 0x0000002d, + 0x0000002b, +}; + +#define A_int_test1 0xab93001d +static u32 A_int_test1_used[] __attribute((unused)) = { + 0x00000354, +}; + +#define A_msg_reject 0x00000000 +static u32 A_msg_reject_used[] __attribute((unused)) = { + 0x00000279, + 0x000002c5, + 0x00000311, }; #define A_msgin_buf 0x00000000 static u32 A_msgin_buf_used[] __attribute((unused)) = { - 0x0000024b, - 0x0000025f, - 0x00000267, - 0x0000026f, - 0x0000028b, - 0x0000029f, - 0x000002a7, + 0x00000249, + 0x0000025d, + 0x00000263, + 0x00000269, + 0x00000275, + 0x00000295, + 0x000002a9, 0x000002af, - 0x000002cb, - 0x000002df, - 0x000002e7, - 0x000002ef, - 0x0000030b, + 0x000002b5, + 0x000002c1, + 0x000002e1, + 0x000002f5, + 0x000002fb, + 0x00000301, + 0x0000030d, + 0x0000032d, }; #define A_reselected_identify 0x00000000 static u32 A_reselected_identify_used[] __attribute((unused)) = { - 0x00000319, + 0x0000033b, +}; + +#define A_test1_dst 0x00000000 +static u32 A_test1_dst_used[] __attribute((unused)) = { + 0x00000352, +}; + +#define A_test1_src 0x00000000 +static u32 A_test1_src_used[] __attribute((unused)) = { + 0x00000351, }; #define Ent_do_select 0x00000000 -#define Ent_done_ident 0x00000050 -#define Ent_end_data_trans 0x00000908 -#define Ent_patch_input_data 0x000000e8 -#define Ent_patch_new_dsa 0x00000c88 -#define Ent_patch_output_data 0x00000500 -#define Ent_reselect 0x00000c48 -#define Ent_resume_cmd 0x00000068 -#define Ent_resume_msgin1a 0x000009e0 -#define Ent_resume_msgin1b 0x000009f0 -#define Ent_resume_msgin2a 0x00000ae0 -#define Ent_resume_msgin2b 0x00000af0 -#define Ent_resume_msgin3a 0x00000be0 -#define Ent_resume_msgin3b 0x00000bf0 -#define Ent_resume_pmm 0x00000078 -#define Ent_resume_rej_ident 0x00000c20 -#define Ent_wait_disc1 0x000009d0 -#define Ent_wait_disc2 0x00000ad0 -#define Ent_wait_disc3 0x00000bd0 -#define Ent_wait_disc_complete 0x000000d0 +#define Ent_done_ident 0x00000048 +#define Ent_end_data_trans 0x00000900 +#define Ent_patch_input_data 0x000000e0 +#define Ent_patch_new_dsa 0x00000d10 +#define Ent_patch_output_data 0x000004f8 +#define Ent_reselect 0x00000cd0 +#define Ent_resume_cmd 0x00000060 +#define Ent_resume_msgin1a 0x00000a08 +#define Ent_resume_msgin1b 0x00000a18 +#define Ent_resume_msgin2a 0x00000b38 +#define Ent_resume_msgin2b 0x00000b48 +#define Ent_resume_msgin3a 0x00000c68 +#define Ent_resume_msgin3b 0x00000c78 +#define Ent_resume_pmm 0x00000070 +#define Ent_resume_rej_ident 0x00000ca8 +#define Ent_test1 0x00000d40 +#define Ent_wait_disc1 0x000009f8 +#define Ent_wait_disc2 0x00000b28 +#define Ent_wait_disc3 0x00000c58 +#define Ent_wait_disc_complete 0x000000c8 static u32 LABELPATCHES[] __attribute((unused)) = { + 0x00000005, 0x00000007, - 0x00000009, + 0x00000013, 0x00000015, - 0x00000017, + 0x0000001d, 0x0000001f, 0x00000021, 0x00000023, - 0x00000025, - 0x0000013d, + 0x0000013b, + 0x00000241, 0x00000243, - 0x00000245, + 0x0000024b, 0x0000024d, 0x0000024f, 0x00000251, - 0x00000253, - 0x00000259, - 0x00000261, - 0x00000269, + 0x00000257, + 0x0000025f, + 0x00000265, + 0x00000273, + 0x00000277, 0x0000027b, - 0x00000287, - 0x0000028d, - 0x0000028f, + 0x00000285, 0x00000291, - 0x00000293, + 0x00000297, 0x00000299, - 0x000002a1, - 0x000002a9, - 0x000002bb, + 0x0000029b, + 0x0000029d, + 0x000002a3, + 0x000002ab, + 0x000002b1, + 0x000002bf, + 0x000002c3, 0x000002c7, - 0x000002cd, - 0x000002cf, 0x000002d1, - 0x000002d3, - 0x000002d9, - 0x000002e1, + 0x000002dd, + 0x000002e3, + 0x000002e5, + 0x000002e7, 0x000002e9, - 0x000002fb, - 0x00000307, - 0x00000311, - 0x00000315, - 0x0000031f, - 0x0000032b, + 0x000002ef, + 0x000002f7, + 0x000002fd, + 0x0000030b, + 0x0000030f, + 0x00000313, + 0x0000031d, + 0x00000329, + 0x00000333, + 0x00000337, + 0x00000341, + 0x0000034d, }; static struct { @@ -2356,6 +2447,6 @@ } EXTERNAL_PATCHES[] __attribute((unused)) = { }; -static u32 INSTRUCTIONS __attribute((unused)) = 407; -static u32 PATCHES __attribute((unused)) = 42; +static u32 INSTRUCTIONS __attribute((unused)) = 426; +static u32 PATCHES __attribute((unused)) = 51; static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/sym53c8xx_2/sym_hipd.c linux.21pre4-ac6/drivers/scsi/sym53c8xx_2/sym_hipd.c --- linux.21pre4/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-02-06 22:36:51.000000000 +0000 @@ -234,7 +234,7 @@ INW (nc_sist); } else if (istat & DIP) { - if (INB (nc_dstat) & ABRT); + if (INB (nc_dstat) & ABRT) break; } UDELAY(5); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/scsi/sym53c8xx.c linux.21pre4-ac6/drivers/scsi/sym53c8xx.c --- linux.21pre4/drivers/scsi/sym53c8xx.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/scsi/sym53c8xx.c 2003-02-06 22:37:33.000000000 +0000 @@ -7005,7 +7005,7 @@ INW (nc_sist); } else if (istat & DIP) { - if (INB (nc_dstat) & ABRT); + if (INB (nc_dstat) & ABRT) break; } UDELAY(5); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/ac97_codec.c linux.21pre4-ac6/drivers/sound/ac97_codec.c --- linux.21pre4/drivers/sound/ac97_codec.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/ac97_codec.c 2003-01-31 11:02:32.000000000 +0000 @@ -133,6 +133,7 @@ {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops}, {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops}, {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops}, + {0x44543031, "Diamond Technology DT0893", &default_ops}, {0x45838308, "ESS Allegro ES1988", &null_ops}, {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */ {0x4e534331, "National Semiconductor LM4549", &null_ops}, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/Config.in linux.21pre4-ac6/drivers/sound/Config.in --- linux.21pre4/drivers/sound/Config.in 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/Config.in 2003-02-01 16:30:27.000000000 +0000 @@ -175,6 +175,7 @@ dep_tristate ' 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS dep_tristate ' AWE32 synth' CONFIG_SOUND_AWE32_SYNTH $CONFIG_SOUND_OSS + dep_tristate ' XpressAudio Sound Blaster emulation' CONFIG_SOUND_KAHLUA $CONFIG_SOUND_SB $CONFIG_SOUND_OSS dep_tristate ' Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m dep_tristate ' Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS if [ "$CONFIG_SOUND_MAUI" = "y" ]; then diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/cs46xx.c linux.21pre4-ac6/drivers/sound/cs46xx.c --- linux.21pre4/drivers/sound/cs46xx.c 2003-01-29 16:26:51.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/cs46xx.c 2003-02-06 22:40:28.000000000 +0000 @@ -4304,7 +4304,7 @@ { offset = ClrStat[i].BA1__DestByteOffset; count = ClrStat[i].BA1__SourceSize; - for( temp1 = offset; temp1<(offset+count); temp1+=4 ); + for( temp1 = offset; temp1<(offset+count); temp1+=4 ) writel(0, pBA1+temp1); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/es1371.c linux.21pre4-ac6/drivers/sound/es1371.c --- linux.21pre4/drivers/sound/es1371.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/es1371.c 2003-02-06 22:48:49.000000000 +0000 @@ -2852,13 +2852,13 @@ printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n" KERN_INFO PFX "features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[devindex]); /* register devices */ - if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1))<0)) + if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0) goto err_dev1; if ((res=(s->codec.dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0)) goto err_dev2; - if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1)) < 0)) + if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0) goto err_dev3; - if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1))<0 )) + if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)))<0 ) goto err_dev4; #ifdef ES1371_DEBUG /* intialize the debug proc device */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/forte.c linux.21pre4-ac6/drivers/sound/forte.c --- linux.21pre4/drivers/sound/forte.c 2003-01-29 16:26:51.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/forte.c 2003-02-11 17:45:53.000000000 +0000 @@ -53,6 +53,7 @@ #include #include +#include #define DRIVER_NAME "forte" #define DRIVER_VERSION "$Id: forte.c,v 1.55 2002/10/02 00:01:42 mkp Exp $" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/i810_audio.c linux.21pre4-ac6/drivers/sound/i810_audio.c --- linux.21pre4/drivers/sound/i810_audio.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/i810_audio.c 2003-01-11 17:27:22.000000000 +0000 @@ -66,6 +66,9 @@ * * This driver is cursed. (Ben LaHaise) * + * ICH 3 caveats + * Intel errata #7 for ICH3 IO. We need to disable SMI stuff + * when codec probing. [Not Yet Done] * * ICH 4 caveats * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/kahlua.c linux.21pre4-ac6/drivers/sound/kahlua.c --- linux.21pre4/drivers/sound/kahlua.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/sound/kahlua.c 2003-02-04 17:12:42.000000000 +0000 @@ -0,0 +1,230 @@ +/* + * Initialisation code for Cyrix/NatSemi VSA1 softaudio + * + * (C) Copyright 2003 Red Hat Inc + * + * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems. + * The older version (VSA1) provides fairly good soundblaster emulation + * although there are a couple of bugs: large DMA buffers break record, + * and the MPU event handling seems suspect. VSA2 allows the native driver + * to control the AC97 audio engine directly and requires a different driver. + * + * Thanks to National Semiconductor for providing the needed information + * on the XpressAudio(tm) internals. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open non patent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + * + * TO DO: + * Investigate whether we can portably support Cognac (5520) in the + * same manner. + */ + +#include +#include +#include +#include + +#include "sound_config.h" + +#include "sb.h" + +/* + * Read a soundblaster compatible mixer register. + * In this case we are actually reading an SMI trap + * not real hardware. + */ + +static u8 __devinit mixer_read(unsigned long io, u8 reg) +{ + outb(reg, io + 4); + udelay(20); + reg = inb(io + 5); + udelay(20); + return reg; +} + +static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct address_info *hw_config; + unsigned long base; + void *mem; + unsigned long io; + u16 map; + u8 irq, dma8, dma16; + int oldquiet; + extern int sb_be_quiet; + + base = pci_resource_start(pdev, 0); + if(base == 0UL) + return 1; + + mem = ioremap(base, 128); + if(mem == 0UL) + return 1; + map = readw(mem + 0x18); /* Read the SMI enables */ + iounmap(mem); + + /* Map bits + 0:1 * 0x20 + 0x200 = sb base + 2 sb enable + 3 adlib enable + 5 MPU enable 0x330 + 6 MPU enable 0x300 + + The other bits may be used internally so must be masked */ + + io = 0x220 + 0x20 * (map & 3); + + if(map & (1<<2)) + printk(KERN_INFO "kahlua: XpressAudio at 0x%lx\n", io); + else + return 1; + + if(map & (1<<5)) + printk(KERN_INFO "kahlua: MPU at 0x300\n"); + else if(map & (1<<6)) + printk(KERN_INFO "kahlua: MPU at 0x330\n"); + + irq = mixer_read(io, 0x80) & 0x0F; + dma8 = mixer_read(io, 0x81); + + // printk("IRQ=%x MAP=%x DMA=%x\n", irq, map, dma8); + + if(dma8 & 0x20) + dma16 = 5; + else if(dma8 & 0x40) + dma16 = 6; + else if(dma8 & 0x80) + dma16 = 7; + else + { + printk(KERN_ERR "kahlua: No 16bit DMA enabled.\n"); + return 1; + } + + if(dma8 & 0x01) + dma8 = 0; + else if(dma8 & 0x02) + dma8 = 1; + else if(dma8 & 0x08) + dma8 = 3; + else + { + printk(KERN_ERR "kahlua: No 8bit DMA enabled.\n"); + return 1; + } + + if(irq & 1) + irq = 9; + else if(irq & 2) + irq = 5; + else if(irq & 4) + irq = 7; + else if(irq & 8) + irq = 10; + else + { + printk(KERN_ERR "kahlua: SB IRQ not set.\n"); + return 1; + } + + printk(KERN_INFO "kahlua: XpressAudio on IRQ %d, DMA %d, %d\n", + irq, dma8, dma16); + + hw_config = kmalloc(sizeof(struct address_info), GFP_KERNEL); + if(hw_config == NULL) + { + printk(KERN_ERR "kahlua: out of memory.\n"); + return 1; + } + memset(hw_config, 0, sizeof(*hw_config)); + + pci_set_drvdata(pdev, hw_config); + + hw_config->io_base = io; + hw_config->irq = irq; + hw_config->dma = dma8; + hw_config->dma2 = dma16; + hw_config->name = "Cyrix XpressAudio"; + hw_config->driver_use_1 = SB_NO_MIDI | SB_PCI_IRQ; + + if(sb_dsp_detect(hw_config, 0, 0, NULL)==0) + { + printk(KERN_ERR "kahlua: audio not responding.\n"); + return 1; + } + + oldquiet = sb_be_quiet; + sb_be_quiet = 1; + if(sb_dsp_init(hw_config, THIS_MODULE)) + { + sb_be_quiet = oldquiet; + pci_set_drvdata(pdev, NULL); + kfree(hw_config); + return 1; + } + sb_be_quiet = oldquiet; + + return 0; +} + +static void __exit remove_one(struct pci_dev *pdev) +{ + struct address_info *hw_config = pci_get_drvdata(pdev); + sb_dsp_unload(hw_config, 0); + pci_set_drvdata(pdev, NULL); + kfree(hw_config); +} + +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("Kahlua VSA1 PCI Audio"); +MODULE_LICENSE("GPL"); + +/* + * 5530 only. The 5510/5520 decode is different. + */ + +static struct pci_device_id id_tbl[] __devinitdata = { + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { } +}; + +MODULE_DEVICE_TABLE(pci, id_tbl); + +static struct pci_driver kahlua_driver = { + name: "kahlua", + id_table: id_tbl, + probe: probe_one, + remove: __devexit_p(remove_one), +}; + + +static int __init kahlua_init_module(void) +{ + printk(KERN_INFO "Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc\n"); + return pci_module_init(&kahlua_driver); +} + +static void __exit kahlua_cleanup_module(void) +{ + return pci_unregister_driver(&kahlua_driver); +} + + +module_init(kahlua_init_module); +module_exit(kahlua_cleanup_module); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/Makefile linux.21pre4-ac6/drivers/sound/Makefile --- linux.21pre4/drivers/sound/Makefile 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/Makefile 2003-02-01 16:31:20.000000000 +0000 @@ -33,6 +33,7 @@ obj-$(CONFIG_SOUND_MSS) += ad1848.o obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o +obj-$(CONFIG_SOUND_KAHLUA) += kahlua.o obj-$(CONFIG_SOUND_WAVEFRONT) += wavefront.o obj-$(CONFIG_SOUND_MAUI) += maui.o mpu401.o obj-$(CONFIG_SOUND_MPU401) += mpu401.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/nec_vrc5477.c linux.21pre4-ac6/drivers/sound/nec_vrc5477.c --- linux.21pre4/drivers/sound/nec_vrc5477.c 2003-01-29 16:26:51.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/nec_vrc5477.c 2003-02-06 22:50:29.000000000 +0000 @@ -1187,7 +1187,7 @@ #endif count -= copyCount; - totalCopyCount =+ copyCount; + totalCopyCount += copyCount; avail -= copyFragCount; totalCopyFragCount += copyFragCount; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/sb_mixer.c linux.21pre4-ac6/drivers/sound/sb_mixer.c --- linux.21pre4/drivers/sound/sb_mixer.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/sb_mixer.c 2003-01-12 00:32:36.000000000 +0000 @@ -479,9 +479,9 @@ regimageL |= sb16_recmasks_L[i]; regimageR |= sb16_recmasks_R[i]; } - sb_setmixer (devc, SB16_IMASK_L, regimageL); - sb_setmixer (devc, SB16_IMASK_R, regimageR); } + sb_setmixer (devc, SB16_IMASK_L, regimageL); + sb_setmixer (devc, SB16_IMASK_R, regimageR); } break; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/sscape.c linux.21pre4-ac6/drivers/sound/sscape.c --- linux.21pre4/drivers/sound/sscape.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/sscape.c 2003-02-06 22:49:40.000000000 +0000 @@ -668,7 +668,7 @@ break; } } - if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff)) + if (hw_config->irq > 15 || ((regs[4] = irq_bits) == 0xff)) { printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq); return; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/trident.c linux.21pre4-ac6/drivers/sound/trident.c --- linux.21pre4/drivers/sound/trident.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/trident.c 2003-02-04 14:58:24.000000000 +0000 @@ -223,7 +223,7 @@ #define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */ #define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */ -#define ALI_DMA_MASK 0xffffffff /* ALI Tridents lack the 30-bit limitation */ +#define ALI_DMA_MASK 0x7fffffff /* ALI Tridents have 31-bit DMA. Wow. */ #define NR_HW_CH 32 @@ -3942,9 +3942,8 @@ return 0; udelay(5000); } - - printk(KERN_ERR "ALi 5451 did not come out of reset.\n"); - return 1; + /* This is non fatal if you have a non PM capable codec.. */ + return 0; } /* AC97 codec initialisation. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/via82cxxx_audio.c linux.21pre4-ac6/drivers/sound/via82cxxx_audio.c --- linux.21pre4/drivers/sound/via82cxxx_audio.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/via82cxxx_audio.c 2003-02-19 16:08:08.000000000 +0000 @@ -146,6 +146,12 @@ #define VIA_INTR_FM ((1<<2) | (1<<6) | (1<<10)) #define VIA_INTR_MASK (VIA_INTR_OUT | VIA_INTR_IN | VIA_INTR_FM) +/* Newer VIA we need to monitor the low 3 bits of each channel. This + mask covers the channels we don't yet use as well + */ + +#define VIA_NEW_INTR_MASK 0x77077777UL + /* VIA_BASE0_AUDIO_xxx_CHAN_TYPE bits */ #define VIA_IRQ_ON_FLAG (1<<0) /* int on each flagged scatter block */ #define VIA_IRQ_ON_EOL (1<<1) /* int at end of scatter list */ @@ -300,12 +306,20 @@ unsigned legacy: 1; /* Has legacy ports */ unsigned intmask: 1; /* Needs int bits */ unsigned sixchannel: 1; /* 8233/35 with 6 channel support */ + unsigned volume: 1; int locked_rate : 1; + + int mixer_vol; /* 8233/35 volume - not yet implemented */ struct semaphore syscall_sem; struct semaphore open_sem; + /* The 8233/8235 have 4 DX audio channels, two record and + one six channel out. We bind ch_in to DX 1, ch_out to multichannel + and ch_fm to DX 2. DX 3 and REC0/REC1 are unused at the + moment */ + struct via_channel ch_in; struct via_channel ch_out; struct via_channel ch_fm; @@ -605,6 +619,9 @@ { struct via_info *card = ac97->private_data; int rate_reg; + u32 dacp; + u32 mast_vol, phone_vol, mono_vol, pcm_vol; + u32 mute_vol = 0x8000; /* The mute volume? -- Seems to work! */ DPRINTK ("ENTER, rate = %d\n", rate); @@ -621,16 +638,32 @@ rate_reg = chan->is_record ? AC97_PCM_LR_ADC_RATE : AC97_PCM_FRONT_DAC_RATE; - via_ac97_write_reg (ac97, AC97_POWER_CONTROL, - (via_ac97_read_reg (ac97, AC97_POWER_CONTROL) & ~0x0200) | - 0x0200); + /* Save current state */ + dacp=via_ac97_read_reg(ac97, AC97_POWER_CONTROL); + mast_vol = via_ac97_read_reg(ac97, AC97_MASTER_VOL_STEREO); + mono_vol = via_ac97_read_reg(ac97, AC97_MASTER_VOL_MONO); + phone_vol = via_ac97_read_reg(ac97, AC97_HEADPHONE_VOL); + pcm_vol = via_ac97_read_reg(ac97, AC97_PCMOUT_VOL); + /* Mute - largely reduces popping */ + via_ac97_write_reg(ac97, AC97_MASTER_VOL_STEREO, mute_vol); + via_ac97_write_reg(ac97, AC97_MASTER_VOL_MONO, mute_vol); + via_ac97_write_reg(ac97, AC97_HEADPHONE_VOL, mute_vol); + via_ac97_write_reg(ac97, AC97_PCMOUT_VOL, mute_vol); + /* Power down the DAC */ + via_ac97_write_reg(ac97, AC97_POWER_CONTROL, dacp|0x0200); + /* Set new rate */ via_ac97_write_reg (ac97, rate_reg, rate); - via_ac97_write_reg (ac97, AC97_POWER_CONTROL, - via_ac97_read_reg (ac97, AC97_POWER_CONTROL) & ~0x0200); - - udelay (10); + /* Power DAC back up */ + via_ac97_write_reg(ac97, AC97_POWER_CONTROL, dacp); + udelay (200); /* reduces popping */ + + /* Restore volumes */ + via_ac97_write_reg(ac97, AC97_MASTER_VOL_STEREO, mast_vol); + via_ac97_write_reg(ac97, AC97_MASTER_VOL_MONO, mono_vol); + via_ac97_write_reg(ac97, AC97_HEADPHONE_VOL, phone_vol); + via_ac97_write_reg(ac97, AC97_PCMOUT_VOL, pcm_vol); /* the hardware might return a value different than what we * passed to it, so read the rate value back from hardware @@ -1555,7 +1588,30 @@ rc = via_syscall_down (card, nonblock); if (rc) goto out; - + +#if 0 + /* + * Intercept volume control on 8233 and 8235 + */ + if(card->volume) + { + switch(cmd) + { + case SOUND_MIXER_READ_VOLUME: + return card->mixer_vol; + case SOUND_MIXER_WRITE_VOLUME: + { + int v; + if(get_user(v, (int *)arg)) + { + rc = -EFAULT; + goto out; + } + card->mixer_vol = v; + } + } + } +#endif rc = codec->mixer_ioctl(codec, cmd, arg); up (&card->syscall_sem); @@ -1893,7 +1949,16 @@ static void via_new_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via_info *card = dev_id; + u32 status32; + /* to minimize interrupt sharing costs, we use the SGD status + * shadow register to check the status of all inputs and + * outputs with a single 32-bit bus read. If no interrupt + * conditions are flagged, we exit immediately + */ + status32 = inl (card->baseaddr + VIA_BASE0_SGD_STATUS_SHADOW); + if (!(status32 & VIA_NEW_INTR_MASK)) + return; /* * goes away completely on UP */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/sound/vidc.c linux.21pre4-ac6/drivers/sound/vidc.c --- linux.21pre4/drivers/sound/vidc.c 2003-01-29 16:26:50.000000000 +0000 +++ linux.21pre4-ac6/drivers/sound/vidc.c 2003-02-07 15:23:22.000000000 +0000 @@ -224,9 +224,11 @@ newsize = 208; if (newsize > 4096) newsize = 4096; - for (new2size = 128; new2size < newsize; new2size <<= 1); - if (new2size - newsize > newsize - (new2size >> 1)) - new2size >>= 1; + for (new2size = 128; new2size < newsize; new2size <<= 1) + /* loop */; + + if (new2size - newsize > newsize - (new2size >> 1)) + new2size >>= 1; if (new2size > 4096) { printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n", newsize, new2size); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerbuf.c linux.21pre4-ac6/drivers/usb/auerbuf.c --- linux.21pre4/drivers/usb/auerbuf.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerbuf.c 2003-02-21 15:46:07.000000000 +0000 @@ -0,0 +1,148 @@ +/*****************************************************************************/ +/* + * auerbuf.c -- Auerswald PBX/System Telephone urb list storage. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#undef DEBUG /* include debug macros until it's done */ +#include +#include "auerbuf.h" +#include + +/* free a single auerbuf */ +void auerbuf_free(struct auerbuf *bp) +{ + kfree(bp->bufp); + kfree(bp->dr); + if (bp->urbp) { + usb_free_urb(bp->urbp); + } + kfree(bp); +} + +/* free the buffers from an auerbuf list */ +void auerbuf_free_list(struct list_head *q) +{ + struct list_head *tmp; + struct list_head *p; + struct auerbuf *bp; + + dbg("auerbuf_free_list"); + for (p = q->next; p != q;) { + bp = list_entry(p, struct auerbuf, buff_list); + tmp = p->next; + list_del(p); + p = tmp; + auerbuf_free(bp); + } +} + +/* free all buffers from an auerbuf chain */ +void auerbuf_free_buffers(struct auerbufctl *bcp) +{ + unsigned long flags; + dbg("auerbuf_free_buffers"); + + spin_lock_irqsave(&bcp->lock, flags); + + auerbuf_free_list(&bcp->free_buff_list); + auerbuf_free_list(&bcp->rec_buff_list); + + spin_unlock_irqrestore(&bcp->lock, flags); +} + +/* init the members of a list control block */ +void auerbuf_init(struct auerbufctl *bcp) +{ + dbg("auerbuf_init"); + spin_lock_init(&bcp->lock); + INIT_LIST_HEAD(&bcp->free_buff_list); + INIT_LIST_HEAD(&bcp->rec_buff_list); +} + +/* setup a list of buffers */ +/* requirement: auerbuf_init() */ +int auerbuf_setup(struct auerbufctl *bcp, unsigned int numElements, + unsigned int bufsize) +{ + struct auerbuf *bep; + + dbg("auerbuf_setup called with %d elements of %d bytes", + numElements, bufsize); + + /* fill the list of free elements */ + for (; numElements; numElements--) { + bep = + (struct auerbuf *) kmalloc(sizeof(struct auerbuf), + GFP_KERNEL); + if (!bep) + goto bl_fail; + memset(bep, 0, sizeof(struct auerbuf)); + bep->list = bcp; + INIT_LIST_HEAD(&bep->buff_list); + bep->bufp = (char *) kmalloc(bufsize, GFP_KERNEL); + if (!bep->bufp) + goto bl_fail; + bep->dr = + (struct usb_ctrlrequest *) + kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!bep->dr) + goto bl_fail; + bep->urbp = usb_alloc_urb(0); + if (!bep->urbp) + goto bl_fail; + list_add_tail(&bep->buff_list, &bcp->free_buff_list); + } + return 0; + + bl_fail: /* not enought memory. Free allocated elements */ + dbg("auerbuf_setup: no more memory"); + auerbuf_free_buffers(bcp); + return -ENOMEM; +} + +/* alloc a free buffer from the list. Returns NULL if no buffer available */ +struct auerbuf *auerbuf_getbuf(struct auerbufctl *bcp) +{ + unsigned long flags; + struct auerbuf *bp = NULL; + + spin_lock_irqsave(&bcp->lock, flags); + if (!list_empty(&bcp->free_buff_list)) { + /* yes: get the entry */ + struct list_head *tmp = bcp->free_buff_list.next; + list_del(tmp); + bp = list_entry(tmp, struct auerbuf, buff_list); + } + spin_unlock_irqrestore(&bcp->lock, flags); + return bp; +} + +/* insert a used buffer into the free list */ +void auerbuf_releasebuf(struct auerbuf *bp) +{ + unsigned long flags; + struct auerbufctl *bcp = bp->list; + bp->retries = 0; + + dbg("auerbuf_releasebuf called"); + spin_lock_irqsave(&bcp->lock, flags); + list_add_tail(&bp->buff_list, &bcp->free_buff_list); + spin_unlock_irqrestore(&bcp->lock, flags); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerbuf.h linux.21pre4-ac6/drivers/usb/auerbuf.h --- linux.21pre4/drivers/usb/auerbuf.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerbuf.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,69 @@ +/*****************************************************************************/ +/* + * auerbuf.h -- Auerswald PBX/System Telephone urb list storage. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +/* This module assembles together an URB, an usb_ctrlrequest struct for sending of + * control messages, and a data buffer. + * These items (auerbuf) are collected in a list (auerbufctl) and are used + * for serialized usb data transfer. + */ + +#ifndef AUERBUF_H +#define AUERBUF_H + +#include + +/* buffer element */ +struct auerbufctl; /* forward */ +struct auerbuf { + unsigned char *bufp; /* reference to allocated data buffer */ + unsigned int len; /* number of characters in data buffer */ + unsigned int retries; /* for urb retries */ + struct usb_ctrlrequest *dr; /* for setup data in control messages */ + struct urb *urbp; /* USB urb */ + struct auerbufctl *list; /* pointer to list */ + struct list_head buff_list; /* reference to next buffer in list */ +}; + +/* buffer list control block */ +struct auerbufctl { + spinlock_t lock; /* protection in interrupt */ + struct list_head free_buff_list;/* free buffers */ + struct list_head rec_buff_list; /* buffers with received data */ +}; + +/* Function prototypes */ +void auerbuf_free(struct auerbuf *bp); + +void auerbuf_free_list(struct list_head *q); + +void auerbuf_init(struct auerbufctl *bcp); + +void auerbuf_free_buffers(struct auerbufctl *bcp); + +int auerbuf_setup(struct auerbufctl *bcp, unsigned int numElements, + unsigned int bufsize); + +struct auerbuf *auerbuf_getbuf(struct auerbufctl *bcp); + +void auerbuf_releasebuf(struct auerbuf *bp); + +#endif /* AUERBUF_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerchain.c linux.21pre4-ac6/drivers/usb/auerchain.c --- linux.21pre4/drivers/usb/auerchain.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerchain.c 2003-02-21 15:46:07.000000000 +0000 @@ -0,0 +1,468 @@ +/*****************************************************************************/ +/* + * auerchain.c -- Auerswald PBX/System Telephone chained urb support. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#undef DEBUG /* include debug macros until it's done */ +#include +#include "auerchain.h" +#include + +/* completion function for chained urbs */ +static void auerchain_complete(struct urb *urb) +{ + unsigned long flags; + int result; + + /* get pointer to element and to chain */ + struct auerchainelement *acep = + (struct auerchainelement *) urb->context; + struct auerchain *acp = acep->chain; + + /* restore original entries in urb */ + urb->context = acep->context; + urb->complete = acep->complete; + + dbg("auerchain_complete called"); + + /* call original completion function + NOTE: this function may lead to more urbs submitted into the chain. + (no chain lock at calling complete()!) + acp->active != NULL is protecting us against recursion. */ + urb->complete(urb); + + /* detach element from chain data structure */ + spin_lock_irqsave(&acp->lock, flags); + if (acp->active != acep) /* paranoia debug check */ + dbg("auerchain_complete: completion on non-active element called!"); + else + acp->active = NULL; + + /* add the used chain element to the list of free elements */ + list_add_tail(&acep->list, &acp->free_list); + acep = NULL; + + /* is there a new element waiting in the chain? */ + if (!acp->active && !list_empty(&acp->waiting_list)) { + /* yes: get the entry */ + struct list_head *tmp = acp->waiting_list.next; + list_del(tmp); + acep = list_entry(tmp, struct auerchainelement, list); + acp->active = acep; + } + spin_unlock_irqrestore(&acp->lock, flags); + + /* submit the new urb */ + if (acep) { + urb = acep->urbp; + dbg("auerchain_complete: submitting next urb from chain"); + urb->status = 0; /* needed! */ + result = usb_submit_urb(urb); + + /* check for submit errors */ + if (result) { + urb->status = result; + dbg("auerchain_complete: usb_submit_urb with error code %d", result); + /* and do error handling via *this* completion function (recursive) */ + auerchain_complete(urb); + } + } else { + /* simple return without submitting a new urb. + The empty chain is detected with acp->active == NULL. */ + }; +} + +/* submit function for chained urbs + this function may be called from completion context or from user space! + early = 1 -> submit in front of chain +*/ +int auerchain_submit_urb_list(struct auerchain *acp, struct urb *urb, + int early) +{ + int result; + unsigned long flags; + struct auerchainelement *acep = NULL; + + dbg("auerchain_submit_urb called"); + + /* try to get a chain element */ + spin_lock_irqsave(&acp->lock, flags); + if (!list_empty(&acp->free_list)) { + /* yes: get the entry */ + struct list_head *tmp = acp->free_list.next; + list_del(tmp); + acep = list_entry(tmp, struct auerchainelement, list); + } + spin_unlock_irqrestore(&acp->lock, flags); + + /* if no chain element available: return with error */ + if (!acep) { + return -ENOMEM; + } + + /* fill in the new chain element values */ + acep->chain = acp; + acep->context = urb->context; + acep->complete = urb->complete; + acep->urbp = urb; + INIT_LIST_HEAD(&acep->list); + + /* modify urb */ + urb->context = acep; + urb->complete = auerchain_complete; + urb->status = -EINPROGRESS; /* usb_submit_urb does this, too */ + + /* add element to chain - or start it immediately */ + spin_lock_irqsave(&acp->lock, flags); + if (acp->active) { + /* there is traffic in the chain, simple add element to chain */ + if (early) { + dbg("adding new urb to head of chain"); + list_add(&acep->list, &acp->waiting_list); + } else { + dbg("adding new urb to end of chain"); + list_add_tail(&acep->list, &acp->waiting_list); + } + acep = NULL; + } else { + /* the chain is empty. Prepare restart */ + acp->active = acep; + } + /* Spin has to be removed before usb_submit_urb! */ + spin_unlock_irqrestore(&acp->lock, flags); + + /* Submit urb if immediate restart */ + if (acep) { + dbg("submitting urb immediate"); + urb->status = 0; /* needed! */ + result = usb_submit_urb(urb); + /* check for submit errors */ + if (result) { + urb->status = result; + dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result); + /* and do error handling via completion function */ + auerchain_complete(urb); + } + } + + return 0; +} + +/* submit function for chained urbs + this function may be called from completion context or from user space! +*/ +int auerchain_submit_urb(struct auerchain *acp, struct urb *urb) +{ + return auerchain_submit_urb_list(acp, urb, 0); +} + +/* cancel an urb which is submitted to the chain + the result is 0 if the urb is cancelled, or -EINPROGRESS if + USB_ASYNC_UNLINK is set and the function is successfully started. +*/ +int auerchain_unlink_urb(struct auerchain *acp, struct urb *urb) +{ + unsigned long flags; + struct urb *urbp; + struct auerchainelement *acep; + struct list_head *tmp; + + dbg("auerchain_unlink_urb called"); + + /* search the chain of waiting elements */ + spin_lock_irqsave(&acp->lock, flags); + list_for_each(tmp, &acp->waiting_list) { + acep = list_entry(tmp, struct auerchainelement, list); + if (acep->urbp == urb) { + list_del(tmp); + urb->context = acep->context; + urb->complete = acep->complete; + list_add_tail(&acep->list, &acp->free_list); + spin_unlock_irqrestore(&acp->lock, flags); + dbg("unlink waiting urb"); + urb->status = -ENOENT; + urb->complete(urb); + return 0; + } + } + /* not found. */ + spin_unlock_irqrestore(&acp->lock, flags); + + /* get the active urb */ + acep = acp->active; + if (acep) { + urbp = acep->urbp; + + /* check if we have to cancel the active urb */ + if (urbp == urb) { + /* note that there is a race condition between the check above + and the unlink() call because of no lock. This race is harmless, + because the usb module will detect the unlink() after completion. + We can't use the acp->lock here because the completion function + wants to grab it. + */ + dbg("unlink active urb"); + return usb_unlink_urb(urbp); + } + } + + /* not found anyway + ... is some kind of success + */ + dbg("urb to unlink not found in chain"); + return 0; +} + +/* cancel all urbs which are in the chain. + this function must not be called from interrupt or completion handler. +*/ +void auerchain_unlink_all(struct auerchain *acp) +{ + unsigned long flags; + struct urb *urbp; + struct auerchainelement *acep; + + dbg("auerchain_unlink_all called"); + + /* clear the chain of waiting elements */ + spin_lock_irqsave(&acp->lock, flags); + while (!list_empty(&acp->waiting_list)) { + /* get the next entry */ + struct list_head *tmp = acp->waiting_list.next; + list_del(tmp); + acep = list_entry(tmp, struct auerchainelement, list); + urbp = acep->urbp; + urbp->context = acep->context; + urbp->complete = acep->complete; + list_add_tail(&acep->list, &acp->free_list); + spin_unlock_irqrestore(&acp->lock, flags); + dbg("unlink waiting urb"); + urbp->status = -ENOENT; + urbp->complete(urbp); + spin_lock_irqsave(&acp->lock, flags); + } + spin_unlock_irqrestore(&acp->lock, flags); + + /* clear the active urb */ + acep = acp->active; + if (acep) { + urbp = acep->urbp; + urbp->transfer_flags &= ~USB_ASYNC_UNLINK; + dbg("unlink active urb"); + usb_unlink_urb(urbp); + } +} + + +/* free the chain. + this function must not be called from interrupt or completion handler. +*/ +void auerchain_free(struct auerchain *acp) +{ + unsigned long flags; + struct auerchainelement *acep; + + dbg("auerchain_free called"); + + /* first, cancel all pending urbs */ + auerchain_unlink_all(acp); + + /* free the elements */ + spin_lock_irqsave(&acp->lock, flags); + while (!list_empty(&acp->free_list)) { + /* get the next entry */ + struct list_head *tmp = acp->free_list.next; + list_del(tmp); + spin_unlock_irqrestore(&acp->lock, flags); + acep = list_entry(tmp, struct auerchainelement, list); + kfree(acep); + spin_lock_irqsave(&acp->lock, flags); + } + spin_unlock_irqrestore(&acp->lock, flags); +} + + +/* Init the chain control structure */ +void auerchain_init(struct auerchain *acp) +{ + /* init the chain data structure */ + acp->active = NULL; + spin_lock_init(&acp->lock); + INIT_LIST_HEAD(&acp->waiting_list); + INIT_LIST_HEAD(&acp->free_list); +} + +/* setup a chain. + It is assumed that there is no concurrency while setting up the chain + requirement: auerchain_init() +*/ +int auerchain_setup(struct auerchain *acp, unsigned int numElements) +{ + struct auerchainelement *acep; + + dbg("auerchain_setup called with %d elements", numElements); + + /* fill the list of free elements */ + for (; numElements; numElements--) { + acep = + (struct auerchainelement *) + kmalloc(sizeof(struct auerchainelement), GFP_KERNEL); + if (!acep) + goto ac_fail; + memset(acep, 0, sizeof(struct auerchainelement)); + INIT_LIST_HEAD(&acep->list); + list_add_tail(&acep->list, &acp->free_list); + } + return 0; + + ac_fail: /* free the elements */ + while (!list_empty(&acp->free_list)) { + /* get the next entry */ + struct list_head *tmp = acp->free_list.next; + list_del(tmp); + acep = list_entry(tmp, struct auerchainelement, list); + kfree(acep); + } + return -ENOMEM; +} + + +/* completion handler for synchronous chained URBs */ +static void auerchain_blocking_completion(struct urb *urb) +{ + struct auerchain_chs *pchs = (struct auerchain_chs *) urb->context; + pchs->done = 1; + wmb(); + wake_up(&pchs->wqh); +} + + +/* Starts chained urb and waits for completion or timeout */ +static int auerchain_start_wait_urb(struct auerchain *acp, struct urb *urb, + int timeout, int *actual_length) +{ + DECLARE_WAITQUEUE(wait, current); + struct auerchain_chs chs; + int status; + + dbg("auerchain_start_wait_urb called"); + init_waitqueue_head(&chs.wqh); + chs.done = 0; + + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chs.wqh, &wait); + urb->context = &chs; + status = auerchain_submit_urb(acp, urb); + if (status) { + /* something went wrong */ + set_current_state(TASK_RUNNING); + remove_wait_queue(&chs.wqh, &wait); + return status; + } + + while (timeout && !chs.done) { + timeout = schedule_timeout(timeout); + set_current_state(TASK_UNINTERRUPTIBLE); + rmb(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&chs.wqh, &wait); + + if (!timeout && !chs.done) { + if (urb->status != -EINPROGRESS) { /* No callback?!! */ + dbg("auerchain_start_wait_urb: raced timeout"); + status = urb->status; + } else { + dbg("auerchain_start_wait_urb: timeout"); + auerchain_unlink_urb(acp, urb); /* remove urb safely */ + status = -ETIMEDOUT; + } + } else + status = urb->status; + + if (actual_length) + *actual_length = urb->actual_length; + + return status; +} + + +/* auerchain_control_msg - Builds a control urb, sends it off and waits for completion + acp: pointer to the auerchain + dev: pointer to the usb device to send the message to + pipe: endpoint "pipe" to send the message to + request: USB message request value + requesttype: USB message request type value + value: USB message value + index: USB message index value + data: pointer to the data to send + size: length in bytes of the data to send + timeout: time to wait for the message to complete before timing out (if 0 the wait is forever) + + This function sends a simple control message to a specified endpoint + and waits for the message to complete, or timeout. + + If successful, it returns the transfered length, othwise a negative error number. + + Don't use this function from within an interrupt context, like a + bottom half handler. If you need a asyncronous message, or need to send + a message from within interrupt context, use auerchain_submit_urb() +*/ +int auerchain_control_msg(struct auerchain *acp, struct usb_device *dev, + unsigned int pipe, __u8 request, + __u8 requesttype, __u16 value, __u16 index, + void *data, __u16 size, int timeout) +{ + int ret; + struct usb_ctrlrequest *dr; + struct urb *urb; + int length; + + dbg("auerchain_control_msg"); + dr = (struct usb_ctrlrequest *) + kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!dr) + return -ENOMEM; + urb = usb_alloc_urb(0); + if (!urb) { + kfree(dr); + return -ENOMEM; + } + + dr->bRequestType = requesttype; + dr->bRequest = request; + dr->wValue = cpu_to_le16(value); + dr->wIndex = cpu_to_le16(index); + dr->wLength = cpu_to_le16(size); + + FILL_CONTROL_URB(urb, dev, pipe, (unsigned char *) dr, data, size, /* build urb */ + (usb_complete_t) auerchain_blocking_completion, + 0); + ret = auerchain_start_wait_urb(acp, urb, timeout, &length); + + usb_free_urb(urb); + kfree(dr); + + if (ret < 0) + return ret; + else + return length; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerchain.h linux.21pre4-ac6/drivers/usb/auerchain.h --- linux.21pre4/drivers/usb/auerchain.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerchain.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,79 @@ +/*****************************************************************************/ +/* + * auerchain.h -- Auerswald PBX/System Telephone chained urb support. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +/* This module is used to make a FIFO of URBs, to serialize the submit. + * This may be used to serialize control messages, which is not supported + * by the Linux USB subsystem. + */ + +#ifndef AUERCHAIN_H +#define AUERCHAIN_H + +#include + +/* urb chain element */ +struct auerchain; /* forward for circular reference */ +struct auerchainelement { + struct auerchain *chain; /* pointer to the chain to which this element belongs */ + struct urb *urbp; /* pointer to attached urb */ + void *context; /* saved URB context */ + usb_complete_t complete; /* saved URB completion function */ + struct list_head list; /* to include element into a list */ +}; + +/* urb chain */ +struct auerchain { + struct auerchainelement *active;/* element which is submitted to urb */ + spinlock_t lock; /* protection agains interrupts */ + struct list_head waiting_list; /* list of waiting elements */ + struct list_head free_list; /* list of available elements */ +}; + +/* urb blocking completion helper struct */ +struct auerchain_chs { + wait_queue_head_t wqh; /* wait for completion */ + unsigned int done; /* completion flag */ +}; + + +/* Function prototypes */ +int auerchain_submit_urb_list(struct auerchain *acp, struct urb *urb, + int early); + +int auerchain_submit_urb(struct auerchain *acp, struct urb *urb); + +int auerchain_unlink_urb(struct auerchain *acp, struct urb *urb); + +void auerchain_unlink_all(struct auerchain *acp); + +void auerchain_free(struct auerchain *acp); + +void auerchain_init(struct auerchain *acp); + +int auerchain_setup(struct auerchain *acp, unsigned int numElements); + +int auerchain_control_msg(struct auerchain *acp, struct usb_device *dev, + unsigned int pipe, __u8 request, + __u8 requesttype, __u16 value, __u16 index, + void *data, __u16 size, int timeout); + +#endif /* AUERCHAIN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerchar.c linux.21pre4-ac6/drivers/usb/auerchar.c --- linux.21pre4/drivers/usb/auerchar.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerchar.c 2003-02-21 15:46:07.000000000 +0000 @@ -0,0 +1,615 @@ +/*****************************************************************************/ +/* + * auerchar.c -- Auerswald PBX/System Telephone character interface. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl) + * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#undef DEBUG /* include debug macros until it's done */ +#include +#include "auerchar.h" +#include "auermain.h" +#include +#include /* user area access functions */ + +/*-------------------------------------------------------------------*/ + +/* wake up waiting readers */ +static void auerchar_disconnect(struct auerscon *scp) +{ + struct auerchar *ccp =((struct auerchar *) ((char *) (scp) - (unsigned long) (&((struct auerchar *) 0)->scontext))); + dbg("auerchar_disconnect called"); + ccp->removed = 1; + wake_up(&ccp->readwait); +} + + +/* dispatch a read paket to a waiting character device */ +static void auerchar_ctrlread_dispatch(struct auerscon *scp, + struct auerbuf *bp) +{ + unsigned long flags; + struct auerchar *ccp; + struct auerbuf *newbp = NULL; + char *charp; + dbg("auerchar_ctrlread_dispatch called"); + ccp =((struct auerchar *) ((char *) (scp) - (unsigned long)(&((struct auerchar *) 0)->scontext))); + + /* get a read buffer from character device context */ + newbp = auerbuf_getbuf(&ccp->bufctl); + if (!newbp) { + dbg("No read buffer available, discard paket!"); + return; /* no buffer, no dispatch */ + } + + /* copy information to new buffer element + (all buffers have the same length) */ + charp = newbp->bufp; + newbp->bufp = bp->bufp; + bp->bufp = charp; + newbp->len = bp->len; + + /* insert new buffer in read list */ + spin_lock_irqsave(&ccp->bufctl.lock, flags); + list_add_tail(&newbp->buff_list, &ccp->bufctl.rec_buff_list); + spin_unlock_irqrestore(&ccp->bufctl.lock, flags); + dbg("read buffer appended to rec_list"); + + /* wake up pending synchronous reads */ + wake_up(&ccp->readwait); +} + + +/* Delete an auerswald character context */ +void auerchar_delete(struct auerchar *ccp) +{ + dbg("auerchar_delete"); + if (ccp == NULL) + return; + + /* wake up pending synchronous reads */ + ccp->removed = 1; + wake_up(&ccp->readwait); + + /* remove the read buffer */ + if (ccp->readbuf) { + auerbuf_releasebuf(ccp->readbuf); + ccp->readbuf = NULL; + } + + /* remove the character buffers */ + auerbuf_free_buffers(&ccp->bufctl); + + /* release the memory */ + kfree(ccp); +} + + +/* --------------------------------------------------------------------- */ +/* Char device functions */ + +/* Open a new character device */ +int auerchar_open(struct inode *inode, struct file *file) +{ + int dtindex = MINOR(inode->i_rdev) - AUER_MINOR_BASE; + struct auerswald *cp = NULL; + struct auerchar *ccp = NULL; + int ret; + + /* minor number in range? */ + if ((dtindex < 0) || (dtindex >= AUER_MAX_DEVICES)) { + return -ENODEV; + } + /* usb device available? */ + if (down_interruptible(&auerdev_table_mutex)) { + return -ERESTARTSYS; + } + cp = auerdev_table[dtindex]; + if (cp == NULL) { + up(&auerdev_table_mutex); + return -ENODEV; + } + if (down_interruptible(&cp->mutex)) { + up(&auerdev_table_mutex); + return -ERESTARTSYS; + } + up(&auerdev_table_mutex); + + /* we have access to the device. Now lets allocate memory */ + ccp = (struct auerchar *) kmalloc(sizeof(struct auerchar), GFP_KERNEL); + if (ccp == NULL) { + err("out of memory"); + ret = -ENOMEM; + goto ofail; + } + + /* Initialize device descriptor */ + memset(ccp, 0, sizeof(struct auerchar)); + init_MUTEX(&ccp->mutex); + init_MUTEX(&ccp->readmutex); + auerbuf_init(&ccp->bufctl); + ccp->scontext.id = AUH_UNASSIGNED; + ccp->scontext.dispatch = auerchar_ctrlread_dispatch; + ccp->scontext.disconnect = auerchar_disconnect; + init_waitqueue_head(&ccp->readwait); + + ret = + auerbuf_setup(&ccp->bufctl, AU_RBUFFERS, + cp->maxControlLength + AUH_SIZE); + if (ret) { + goto ofail; + } + + cp->open_count++; + ccp->auerdev = cp; + dbg("open %s as /dev/usb/%s", cp->dev_desc, cp->name); + up(&cp->mutex); + + /* file IO stuff */ + file->f_pos = 0; + file->private_data = ccp; + return 0; + + /* Error exit */ + ofail:up(&cp->mutex); + auerchar_delete(ccp); + return ret; +} + + +/* IOCTL functions */ +int auerchar_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct auerchar *ccp = (struct auerchar *) file->private_data; + int ret = 0; + struct audevinfo devinfo; + struct auerswald *cp = NULL; + unsigned int u; + dbg("ioctl"); + + /* get the mutexes */ + if (down_interruptible(&ccp->mutex)) { + return -ERESTARTSYS; + } + cp = ccp->auerdev; + if (!cp) { + up(&ccp->mutex); + return -ENODEV; + } + if (down_interruptible(&cp->mutex)) { + up(&ccp->mutex); + return -ERESTARTSYS; + } + + /* Check for removal */ + if (!cp->usbdev) { + up(&cp->mutex); + up(&ccp->mutex); + return -ENODEV; + } + + switch (cmd) { + + /* return != 0 if Transmitt channel ready to send */ + case IOCTL_AU_TXREADY: + dbg("IOCTL_AU_TXREADY"); + u = ccp->auerdev && (ccp->scontext.id != AUH_UNASSIGNED) + && !list_empty(&cp->bufctl.free_buff_list); + ret = put_user(u, (unsigned int *) arg); + break; + + /* return != 0 if connected to a service channel */ + case IOCTL_AU_CONNECT: + dbg("IOCTL_AU_CONNECT"); + u = (ccp->scontext.id != AUH_UNASSIGNED); + ret = put_user(u, (unsigned int *) arg); + break; + + /* return != 0 if Receive Data available */ + case IOCTL_AU_RXAVAIL: + dbg("IOCTL_AU_RXAVAIL"); + if (ccp->scontext.id == AUH_UNASSIGNED) { + ret = -EIO; + break; + } + u = 0; /* no data */ + if (ccp->readbuf) { + int restlen = ccp->readbuf->len - ccp->readoffset; + if (restlen > 0) + u = 1; + } + if (!u) { + if (!list_empty(&ccp->bufctl.rec_buff_list)) { + u = 1; + } + } + ret = put_user(u, (unsigned int *) arg); + break; + + /* return the max. buffer length for the device */ + case IOCTL_AU_BUFLEN: + dbg("IOCTL_AU_BUFLEN"); + u = cp->maxControlLength; + ret = put_user(u, (unsigned int *) arg); + break; + + /* requesting a service channel */ + case IOCTL_AU_SERVREQ: + dbg("IOCTL_AU_SERVREQ"); + /* requesting a service means: release the previous one first */ + auerswald_removeservice(cp, &ccp->scontext); + /* get the channel number */ + ret = get_user(u, (unsigned int *) arg); + if (ret) { + break; + } + if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) { + ret = -EIO; + break; + } + dbg("auerchar service request parameters are ok"); + ccp->scontext.id = u; + + /* request the service now */ + ret = auerswald_addservice(cp, &ccp->scontext); + if (ret) { + /* no: revert service entry */ + ccp->scontext.id = AUH_UNASSIGNED; + } + break; + + /* get a string descriptor for the device */ + case IOCTL_AU_DEVINFO: + dbg("IOCTL_AU_DEVINFO"); + if (copy_from_user + (&devinfo, (void *) arg, sizeof(struct audevinfo))) { + ret = -EFAULT; + break; + } + u = strlen(cp->dev_desc) + 1; + if (u > devinfo.bsize) { + u = devinfo.bsize; + } + ret = copy_to_user(devinfo.buf, cp->dev_desc, u); + break; + + /* get the max. string descriptor length */ + case IOCTL_AU_SLEN: + dbg("IOCTL_AU_SLEN"); + u = AUSI_DLEN; + ret = put_user(u, (unsigned int *) arg); + break; + + default: + dbg("IOCTL_AU_UNKNOWN"); + ret = -ENOIOCTLCMD; + break; + } + /* release the mutexes */ + up(&cp->mutex); + up(&ccp->mutex); + return ret; +} + + +/* Seek is not supported */ +loff_t auerchar_llseek(struct file * file, loff_t offset, int origin) +{ + dbg("auerchar_seek"); + return -ESPIPE; +} + + +/* Read data from the device */ +ssize_t auerchar_read(struct file * file, char *buf, size_t count, + loff_t * ppos) +{ + unsigned long flags; + struct auerchar *ccp = (struct auerchar *) file->private_data; + struct auerbuf *bp = NULL; + wait_queue_t wait; + + dbg("auerchar_read"); + + /* Error checking */ + if (!ccp) + return -EIO; + if (*ppos) + return -ESPIPE; + if (count == 0) + return 0; + + /* get the mutex */ + if (down_interruptible(&ccp->mutex)) + return -ERESTARTSYS; + + /* Can we expect to read something? */ + if (ccp->scontext.id == AUH_UNASSIGNED) { + up(&ccp->mutex); + return -EIO; + } + + /* only one reader per device allowed */ + if (down_interruptible(&ccp->readmutex)) { + up(&ccp->mutex); + return -ERESTARTSYS; + } + + /* read data from readbuf, if available */ + doreadbuf: + bp = ccp->readbuf; + if (bp) { + /* read the maximum bytes */ + int restlen = bp->len - ccp->readoffset; + if (restlen < 0) + restlen = 0; + if (count > restlen) + count = restlen; + if (count) { + if (copy_to_user + (buf, bp->bufp + ccp->readoffset, count)) { + dbg("auerswald_read: copy_to_user failed"); + up(&ccp->readmutex); + up(&ccp->mutex); + return -EFAULT; + } + } + /* advance the read offset */ + ccp->readoffset += count; + restlen -= count; + // reuse the read buffer + if (restlen <= 0) { + auerbuf_releasebuf(bp); + ccp->readbuf = NULL; + } + /* return with number of bytes read */ + if (count) { + up(&ccp->readmutex); + up(&ccp->mutex); + return count; + } + } + + /* a read buffer is not available. Try to get the next data block. */ + doreadlist: + /* Preparing for sleep */ + init_waitqueue_entry(&wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&ccp->readwait, &wait); + + bp = NULL; + spin_lock_irqsave(&ccp->bufctl.lock, flags); + if (!list_empty(&ccp->bufctl.rec_buff_list)) { + /* yes: get the entry */ + struct list_head *tmp = ccp->bufctl.rec_buff_list.next; + list_del(tmp); + bp = list_entry(tmp, struct auerbuf, buff_list); + } + spin_unlock_irqrestore(&ccp->bufctl.lock, flags); + + /* have we got data? */ + if (bp) { + ccp->readbuf = bp; + ccp->readoffset = AUH_SIZE; /* for headerbyte */ + set_current_state(TASK_RUNNING); + remove_wait_queue(&ccp->readwait, &wait); + goto doreadbuf; /* now we can read! */ + } + + /* no data available. Should we wait? */ + if (file->f_flags & O_NONBLOCK) { + dbg("No read buffer available, returning -EAGAIN"); + set_current_state(TASK_RUNNING); + remove_wait_queue(&ccp->readwait, &wait); + up(&ccp->readmutex); + up(&ccp->mutex); + return -EAGAIN; /* nonblocking, no data available */ + } + + /* yes, we should wait! */ + up(&ccp->mutex); /* allow other operations while we wait */ + schedule(); + remove_wait_queue(&ccp->readwait, &wait); + if (signal_pending(current)) { + /* waked up by a signal */ + up(&ccp->readmutex); + return -ERESTARTSYS; + } + + /* Anything left to read? */ + if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) { + up(&ccp->readmutex); + return -EIO; + } + + if (down_interruptible(&ccp->mutex)) { + up(&ccp->readmutex); + return -ERESTARTSYS; + } + + /* try to read the incomming data again */ + goto doreadlist; +} + + +/* Write a data block into the right service channel of the device */ +ssize_t auerchar_write(struct file *file, const char *buf, size_t len, + loff_t * ppos) +{ + struct auerchar *ccp = (struct auerchar *) file->private_data; + struct auerswald *cp = NULL; + struct auerbuf *bp; + int ret; + wait_queue_t wait; + + dbg("auerchar_write %d bytes", len); + + /* Error checking */ + if (!ccp) + return -EIO; + if (*ppos) + return -ESPIPE; + if (len == 0) + return 0; + + write_again: + /* get the mutex */ + if (down_interruptible(&ccp->mutex)) + return -ERESTARTSYS; + + /* Can we expect to write something? */ + if (ccp->scontext.id == AUH_UNASSIGNED) { + up(&ccp->mutex); + return -EIO; + } + + cp = ccp->auerdev; + if (!cp) { + up(&ccp->mutex); + return -ERESTARTSYS; + } + if (down_interruptible(&cp->mutex)) { + up(&ccp->mutex); + return -ERESTARTSYS; + } + if (!cp->usbdev) { + up(&cp->mutex); + up(&ccp->mutex); + return -EIO; + } + /* Prepare for sleep */ + init_waitqueue_entry(&wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&cp->bufferwait, &wait); + + /* Try to get a buffer from the device pool. + We can't use a buffer from ccp->bufctl because the write + command will last beond a release() */ + bp = auerbuf_getbuf(&cp->bufctl); + /* are there any buffers left? */ + if (!bp) { + up(&cp->mutex); + up(&ccp->mutex); + + /* NONBLOCK: don't wait */ + if (file->f_flags & O_NONBLOCK) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&cp->bufferwait, &wait); + return -EAGAIN; + } + + /* BLOCKING: wait */ + schedule(); + remove_wait_queue(&cp->bufferwait, &wait); + if (signal_pending(current)) { + /* waked up by a signal */ + return -ERESTARTSYS; + } + goto write_again; + } else { + set_current_state(TASK_RUNNING); + remove_wait_queue(&cp->bufferwait, &wait); + } + + /* protect against too big write requests */ + if (len > cp->maxControlLength) + len = cp->maxControlLength; + + /* Fill the buffer */ + if (copy_from_user(bp->bufp + AUH_SIZE, buf, len)) { + dbg("copy_from_user failed"); + auerbuf_releasebuf(bp); + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); + up(&cp->mutex); + up(&ccp->mutex); + return -EIO; + } + + /* set the header byte */ + *(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT; + + /* Set the transfer Parameters */ + bp->len = len + AUH_SIZE; + bp->dr->bRequestType = AUT_WREQ; + bp->dr->bRequest = AUV_WBLOCK; + bp->dr->wValue = cpu_to_le16(0); + bp->dr->wIndex = + cpu_to_le16(ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT); + bp->dr->wLength = cpu_to_le16(len + AUH_SIZE); + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_sndctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, bp->bufp, + len + AUH_SIZE, auerchar_ctrlwrite_complete, bp); + /* up we go */ + ret = auerchain_submit_urb(&cp->controlchain, bp->urbp); + up(&cp->mutex); + if (ret) { + dbg("auerchar_write: nonzero result of auerchain_submit_urb %d", ret); + auerbuf_releasebuf(bp); + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); + up(&ccp->mutex); + return -EIO; + } else { + dbg("auerchar_write: Write OK"); + up(&ccp->mutex); + return len; + } +} + + +/* Close a character device */ +int auerchar_release(struct inode *inode, struct file *file) +{ + struct auerchar *ccp = (struct auerchar *) file->private_data; + struct auerswald *cp; + dbg("release"); + + /* get the mutexes */ + if (down_interruptible(&ccp->mutex)) { + return -ERESTARTSYS; + } + cp = ccp->auerdev; + if (cp) { + if (down_interruptible(&cp->mutex)) { + up(&ccp->mutex); + return -ERESTARTSYS; + } + /* remove an open service */ + auerswald_removeservice(cp, &ccp->scontext); + /* detach from device */ + if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) { + /* usb device waits for removal */ + up(&cp->mutex); + auerswald_delete(cp); + } else { + up(&cp->mutex); + } + cp = NULL; + ccp->auerdev = NULL; + } + up(&ccp->mutex); + auerchar_delete(ccp); + + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerchar.h linux.21pre4-ac6/drivers/usb/auerchar.h --- linux.21pre4/drivers/usb/auerchar.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerchar.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,79 @@ +/*****************************************************************************/ +/* + * auerchar.h -- Auerswald PBX/System Telephone character interface. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#ifndef AUERCHAR_H +#define AUERCHAR_H + +#include "auerchain.h" +#include "auerbuf.h" +#include "auerserv.h" + +/* External data structures / Interface */ +struct audevinfo { + char *buf; /* return buffer for string contents */ + unsigned int bsize; /* size of return buffer */ +}; + +/* IO controls */ +#define IOCTL_AU_SLEN _IOR( 'U', 0xF0, int) /* return the max. string descriptor length */ +#define IOCTL_AU_DEVINFO _IOWR('U', 0xF1, struct audevinfo) /* get name of a specific device */ +#define IOCTL_AU_SERVREQ _IOW( 'U', 0xF2, int) /* request a service channel */ +#define IOCTL_AU_BUFLEN _IOR( 'U', 0xF3, int) /* return the max. buffer length for the device */ +#define IOCTL_AU_RXAVAIL _IOR( 'U', 0xF4, int) /* return != 0 if Receive Data available */ +#define IOCTL_AU_CONNECT _IOR( 'U', 0xF5, int) /* return != 0 if connected to a service channel */ +#define IOCTL_AU_TXREADY _IOR( 'U', 0xF6, int) /* return != 0 if Transmitt channel ready to send */ +/* 'U' 0xF7..0xFF reserved */ + +/* character device context */ +struct auerswald; +struct auerchar { + struct semaphore mutex; /* protection in user context */ + struct auerswald *auerdev; /* context pointer of assigned device */ + struct auerbufctl bufctl; /* controls the buffer chain */ + struct auerscon scontext; /* service context */ + wait_queue_head_t readwait; /* for synchronous reading */ + struct semaphore readmutex; /* protection against multiple reads */ + struct auerbuf *readbuf; /* buffer held for partial reading */ + unsigned int readoffset; /* current offset in readbuf */ + unsigned int removed; /* is != 0 if device is removed */ +}; + +/* Function prototypes */ +void auerchar_delete(struct auerchar *ccp); + +int auerchar_open(struct inode *inode, struct file *file); + +int auerchar_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +loff_t auerchar_llseek(struct file *file, loff_t offset, int origin); + +ssize_t auerchar_read(struct file *file, char *buf, size_t count, + loff_t * ppos); + +ssize_t auerchar_write(struct file *file, const char *buf, size_t len, + loff_t * ppos); + +int auerchar_release(struct inode *inode, struct file *file); + + +#endif /* AUERCHAR_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerisdn_b.c linux.21pre4-ac6/drivers/usb/auerisdn_b.c --- linux.21pre4/drivers/usb/auerisdn_b.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerisdn_b.c 2003-02-21 15:46:07.000000000 +0000 @@ -0,0 +1,689 @@ +/*****************************************************************************/ +/* + * auerisdn_b.c -- Auerswald PBX/System Telephone ISDN B-channel interface. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#include /* ISDN constants */ +#include /* skb functions */ + +#undef DEBUG /* include debug macros until it's done */ +#include /* standard usb header */ + +#include "auerisdn.h" +#include "auermain.h" + +/*-------------------------------------------------------------------*/ +/* ISDN B channel support defines */ +#define AUISDN_BC_1MS 8 /* Bytes per channel and ms */ +#define AUISDN_BC_INC 4 /* change INT OUT size increment */ +#define AUISDN_BCDATATHRESHOLD 48 /* for unsymmetric 2-B-channels */ +#define AUISDN_TOGGLETIME 6 /* Timeout for unsymmetric serve */ + +/*-------------------------------------------------------------------*/ +/* Debug support */ +#ifdef DEBUG +#define dump( desc, adr, len) \ +do { \ + unsigned int u; \ + printk (KERN_DEBUG); \ + printk (desc); \ + for (u = 0; u < len; u++) \ + printk (" %02X", adr[u] & 0xFF); \ + printk ("\n"); \ +} while (0) +#else +#define dump( desc, adr, len) +#endif + +/*-------------------------------------------------------------------*/ + +/* Callback to L2 for HISAX */ +/* This callback can be called from 3 sources: + a) from hisax context (answer from a l2l1 function) + b) from interrupt context (a B channel paket arrived, a B channel paket was sent) + c) from kernel daemon context (probe/disconnecting) +*/ +void auerisdn_b_l1l2(struct auerisdnbc *bc, int pr, void *arg) +{ + struct auerhisax *ahp; + struct sk_buff *skb; + + /* do the callback */ + ahp = bc->cp->isdn.ahp; + if (ahp) { + ahp->hisax_b_if[bc->channel].ifc.l1l2(&ahp-> + hisax_b_if[bc-> + channel]. + ifc, pr, arg); + } else { + dbg("auerisdn_b_l1l2 called without ahp"); + if (pr == (PH_DATA | INDICATION)) { + skb = (struct sk_buff *) arg; + if (skb) { + skb_pull(skb, skb->len); + dev_kfree_skb_any(skb); + } + } + } +} + +/* fill the INT OUT data buffer with new data */ +/* Transfer buffer size to fill is in urbp->transfer_buffer_length */ +static void auerisdn_bintbo_newdata(struct auerisdn *ip) +{ + unsigned long flags; + struct urb *urbp = ip->intbo_urbp; + struct auerisdnbc *bc = &ip->bc[0]; /* start with B-channel 0 */ + struct sk_buff *skb; + unsigned char *ucp; + int buf_size; + int len; + int bytes_sent; + int i; + + /* FIXME: this algorithm is fixed to 2 B-channels */ + /* Which B channel should we serve? */ + if (ip->bc[1].mode != L1_MODE_NULL) { + /* B channel 1 is used */ + if (bc->mode != L1_MODE_NULL) { + /* both B-channels are used */ + if (ip->intbo_toggletimer) { + /* simply toggling */ + ip->intbo_toggletimer--; + i = ip->intbo_index ^ 1; /* serve both channels equal */ + } else { + /* search the B channel with the most demand of data */ + i = bc->txfree - ip->bc[1].txfree; + if (i < -AUISDN_BCDATATHRESHOLD) + i = 1; /* B channel 1 needs more data */ + else if (i > AUISDN_BCDATATHRESHOLD) + i = 0; /* B channel 0 needs more data */ + else + i = ip->intbo_index ^ 1; /* serve both channels equal */ + if (i == ip->intbo_index) + ip->intbo_toggletimer = + AUISDN_TOGGLETIME; + } + bc = &ip->bc[i]; + ip->intbo_index = i; + } else { + bc = &ip->bc[1]; + } + } + dbg("INTBO: Fill B%d with %d Bytes, %d Bytes free", + bc->channel + 1, urbp->transfer_buffer_length - AUH_SIZE, + bc->txfree); + + /* Fill the buffer with data */ + ucp = ip->intbo_bufp; + *ucp++ = AUH_B1CHANNEL + bc->channel; /* First byte is channel nr. */ + buf_size = urbp->transfer_buffer_length - AUH_SIZE; + len = 0; + while (len < buf_size) { + spin_lock_irqsave(&bc->txskb_lock, flags); + if ((skb = bc->txskb)) { + /* dump ("raw tx data:", skb->data, skb->len); */ + if (bc->mode == L1_MODE_TRANS) { + bytes_sent = buf_size - len; + if (skb->len < bytes_sent) + bytes_sent = skb->len; + { /* swap tx bytes */ + register unsigned char *src = + skb->data; + unsigned int count; + for (count = 0; count < bytes_sent; + count++) + *ucp++ = + isdnhdlc_bit_rev_tab + [*src++]; + } + len += bytes_sent; + bc->lastbyte = skb->data[bytes_sent - 1]; + } else { + int bs = + isdnhdlc_encode(&bc->outp_hdlc_state, + skb->data, skb->len, + &bytes_sent, + ucp, buf_size - len); + /* dump ("hdlc data:", ucp, bs); */ + len += bs; + ucp += bs; + } + skb_pull(skb, bytes_sent); + + if (!skb->len) { + // Frame sent + bc->txskb = NULL; + spin_unlock_irqrestore(&bc->txskb_lock, + flags); + auerisdn_b_l1l2(bc, PH_DATA | CONFIRM, + (void *) skb->truesize); + dev_kfree_skb_any(skb); + continue; //while + } + } else { + if (bc->mode == L1_MODE_TRANS) { + memset(ucp, bc->lastbyte, buf_size - len); + ucp += buf_size - len; + len = buf_size; + /* dbg ("fill = 0xFF"); */ + } else { + // Send flags + int bs = + isdnhdlc_encode(&bc->outp_hdlc_state, + NULL, 0, &bytes_sent, + ucp, buf_size - len); + /* dbg ("fill = 0x%02X", (int)*ucp); */ + len += bs; + ucp += bs; + } + } + spin_unlock_irqrestore(&bc->txskb_lock, flags); + } + /* dbg ("%d Bytes to TX buffer", len); */ +} + + +/* INT OUT completion handler */ +static void auerisdn_bintbo_complete(struct urb *urbp) +{ + struct auerisdn *ip = urbp->context; + + /* unlink completion? */ + if ((urbp->status == -ENOENT) || (urbp->status == -ECONNRESET)) { + /* should we restart with another size? */ + if (ip->intbo_state == INTBOS_CHANGE) { + dbg("state => RESTART"); + ip->intbo_state = INTBOS_RESTART; + } else { + /* set up variables for later restart */ + dbg("INTBO stopped"); + ip->intbo_state = INTBOS_IDLE; + } + /* nothing more to do */ + return; + } + + /* other state != 0? */ + if (urbp->status) { + warn("auerisdn_bintbo_complete: status = %d", + urbp->status); + return; + } + + /* Should we fill in new data? */ + if (ip->intbo_state == INTBOS_CHANGE) { + dbg("state == INTBOS_CHANGE, no new data"); + return; + } + + /* fill in new data */ + auerisdn_bintbo_newdata(ip); +} + +/* set up the INT OUT URB the first time */ +/* Don't start the URB */ +static void auerisdn_bintbo_setup(struct auerisdn *ip, unsigned int len) +{ + ip->intbo_state = INTBOS_IDLE; + FILL_INT_URB(ip->intbo_urbp, ip->usbdev, + usb_sndintpipe(ip->usbdev, ip->intbo_endp), + ip->intbo_bufp, len, auerisdn_bintbo_complete, ip, + ip->outInterval); + ip->intbo_urbp->transfer_flags |= USB_ASYNC_UNLINK; + ip->intbo_urbp->status = 0; +} + +/* restart the INT OUT endpoint */ +static void auerisdn_bintbo_restart(struct auerisdn *ip) +{ + struct urb *urbp = ip->intbo_urbp; + int status; + + /* dbg ("auerisdn_intbo_restart"); */ + + /* fresh restart */ + auerisdn_bintbo_setup(ip, ip->paketsize + AUH_SIZE); + + /* Fill in new data */ + auerisdn_bintbo_newdata(ip); + + /* restart the urb */ + ip->intbo_state = INTBOS_RUNNING; + status = usb_submit_urb(urbp); + if (status < 0) { + err("can't submit INT OUT urb, status = %d", status); + urbp->status = status; + urbp->complete(urbp); + } +} + +/* change the size of the INT OUT endpoint */ +static void auerisdn_bchange(struct auerisdn *ip, unsigned int paketsize) +{ + /* changing... */ + dbg("txfree[0] = %d, txfree[1] = %d, old size = %d, new size = %d", + ip->bc[0].txfree, ip->bc[1].txfree, ip->paketsize, paketsize); + ip->paketsize = paketsize; + + if (paketsize == 0) { + /* stop the INT OUT endpoint */ + dbg("stop unlinking INT out urb"); + ip->intbo_state = INTBOS_IDLE; + usb_unlink_urb(ip->intbo_urbp); + return; + } + if (ip->intbo_state != INTBOS_IDLE) { + /* dbg ("unlinking INT out urb"); */ + ip->intbo_state = INTBOS_CHANGE; + usb_unlink_urb(ip->intbo_urbp); + } else { + /* dbg ("restart immediately"); */ + auerisdn_bintbo_restart(ip); + } +} + +/* serve the outgoing B channel interrupt */ +/* Called from the INT IN completion handler */ +static void auerisdn_bserv(struct auerisdn *ip) +{ + struct auerisdnbc *bc; + unsigned int u; + unsigned int paketsize; + + /* should we start the INT OUT endpoint again? */ + if (ip->intbo_state == INTBOS_RESTART) { + /* dbg ("Restart INT OUT from INT IN"); */ + auerisdn_bintbo_restart(ip); + return; + } + /* no new calculation if change already in progress */ + if (ip->intbo_state == INTBOS_CHANGE) + return; + + /* calculation of transfer parameters for INT OUT endpoint */ + paketsize = 0; + for (u = 0; u < AUISDN_BCHANNELS; u++) { + bc = &ip->bc[u]; + if (bc->mode != L1_MODE_NULL) { /* B channel is active */ + unsigned int bpp = AUISDN_BC_1MS * ip->outInterval; + if (bc->txfree < bpp) { /* buffer is full, throttle */ + bc->txsize = bpp - AUISDN_BC_INC; + paketsize += bpp - AUISDN_BC_INC; + } else if (bc->txfree < bpp * 2) { + paketsize += bc->txsize; /* schmidt-trigger, continue */ + } else if (bc->txfree < bpp * 4) { /* we are in synch */ + bc->txsize = bpp; + paketsize += bpp; + } else if (bc->txfree > bc->ofsize / 2) {/* we have to fill the buffer */ + bc->txsize = bpp + AUISDN_BC_INC; + paketsize += bpp + AUISDN_BC_INC; + } else { + paketsize += bc->txsize; /* schmidt-trigger, continue */ + } + } + } + + /* check if we have to change the paket size */ + if (paketsize != ip->paketsize) + auerisdn_bchange(ip, paketsize); +} + +/* Send activation/deactivation state to L2 */ +static void auerisdn_bconf(struct auerisdnbc *bc) +{ + unsigned long flags; + struct sk_buff *skb; + + if (bc->mode == L1_MODE_NULL) { + auerisdn_b_l1l2(bc, PH_DEACTIVATE | INDICATION, NULL); + /* recycle old txskb */ + spin_lock_irqsave(&bc->txskb_lock, flags); + skb = bc->txskb; + bc->txskb = NULL; + spin_unlock_irqrestore(&bc->txskb_lock, flags); + if (skb) { + skb_pull(skb, skb->len); + auerisdn_b_l1l2(bc, PH_DATA | CONFIRM, + (void *) skb->truesize); + dev_kfree_skb_any(skb); + } + } else { + auerisdn_b_l1l2(bc, PH_ACTIVATE | INDICATION, NULL); + } +} + +/* B channel setup completion handler */ +static void auerisdn_bmode_complete(struct urb *urb) +{ + struct auerswald *cp; + struct auerbuf *bp = (struct auerbuf *) urb->context; + struct auerisdnbc *bc; + int channel; + + dbg("auerisdn_bmode_complete called"); + cp = ((struct auerswald *) ((char *) (bp->list) - + (unsigned + long) (&((struct auerswald *) 0)-> + bufctl))); + + /* select the B-channel */ + channel = le16_to_cpu(bp->dr->wIndex); + channel -= AUH_B1CHANNEL; + if (channel < 0) + goto rel; + if (channel >= AUISDN_BCHANNELS) + goto rel; + bc = &cp->isdn.bc[channel]; + + /* Check for success */ + if (urb->status) { + err("complete with non-zero status: %d", urb->status); + } else { + bc->mode = *bp->bufp; + } + /* Signal current mode to L2 */ + auerisdn_bconf(bc); + + /* reuse the buffer */ + rel:auerbuf_releasebuf(bp); + + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); +} + +/* Setup a B channel transfer mode */ +static void auerisdn_bmode(struct auerisdnbc *bc, unsigned int mode) +{ + struct auerswald *cp = bc->cp; + struct auerbuf *bp; + int ret; + + /* don't allow activation on disconnect */ + if (cp->disconnecting) { + mode = L1_MODE_NULL; + + /* Else check if something changed */ + } else if (bc->mode != mode) { + if ((mode != L1_MODE_NULL) && (mode != L1_MODE_TRANS)) { + /* init RX hdlc decoder */ + dbg("rcv init"); + isdnhdlc_rcv_init(&bc->inp_hdlc_state, 0); + /* init TX hdlc decoder */ + dbg("out init"); + isdnhdlc_out_init(&bc->outp_hdlc_state, 0, 0); + } + /* stop ASAP */ + if (mode == L1_MODE_NULL) + bc->mode = mode; + if ((bc->mode == L1_MODE_NULL) || (mode == L1_MODE_NULL)) { + /* Activation or deactivation required */ + + /* get a buffer for the command */ + bp = auerbuf_getbuf(&cp->bufctl); + /* if no buffer available: can't change the mode */ + if (!bp) { + err("auerisdn_bmode: no data buffer available"); + return; + } + + /* fill the control message */ + bp->dr->bRequestType = AUT_WREQ; + bp->dr->bRequest = AUV_CHANNELCTL; + if (mode != L1_MODE_NULL) + bp->dr->wValue = cpu_to_le16(1); + else + bp->dr->wValue = cpu_to_le16(0); + bp->dr->wIndex = + cpu_to_le16(AUH_B1CHANNEL + bc->channel); + bp->dr->wLength = cpu_to_le16(0); + *bp->bufp = mode; + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_sndctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, + bp->bufp, 0, + (usb_complete_t) + auerisdn_bmode_complete, bp); + + /* submit the control msg */ + ret = + auerchain_submit_urb(&cp->controlchain, + bp->urbp); + if (ret) { + bp->urbp->status = ret; + auerisdn_bmode_complete(bp->urbp); + } + return; + } + } + /* new mode is set */ + bc->mode = mode; + + /* send confirmation to L2 */ + auerisdn_bconf(bc); +} + +/* B-channel transfer function L2->L1 */ +void auerisdn_b_l2l1(struct hisax_if *ifc, int pr, void *arg, + unsigned int channel) +{ + struct auerhisax *ahp; + struct auerisdnbc *bc; + struct auerswald *cp; + struct sk_buff *skb; + unsigned long flags; + int mode; + + cp = NULL; + ahp = (struct auerhisax *) ifc->priv; + if (ahp) + cp = ahp->cp; + if (cp && !cp->disconnecting) { + /* normal execution */ + bc = &cp->isdn.bc[channel]; + switch (pr) { + case PH_ACTIVATE | REQUEST: /* activation request */ + mode = (int) arg; /* one of the L1_MODE constants */ + dbg("B%d, PH_ACTIVATE_REQUEST Mode = %d", + bc->channel + 1, mode); + auerisdn_bmode(bc, mode); + break; + case PH_DEACTIVATE | REQUEST: /* deactivation request */ + dbg("B%d, PH_DEACTIVATE_REQUEST", bc->channel + 1); + auerisdn_bmode(bc, L1_MODE_NULL); + break; + case PH_DATA | REQUEST: /* Transmit data request */ + skb = (struct sk_buff *) arg; + spin_lock_irqsave(&bc->txskb_lock, flags); + if (bc->txskb) { + err("Overflow in B channel TX"); + skb_pull(skb, skb->len); + dev_kfree_skb_any(skb); + } else { + if (cp->disconnecting + || (bc->mode == L1_MODE_NULL)) { + skb_pull(skb, skb->len); + spin_unlock_irqrestore(&bc-> + txskb_lock, + flags); + auerisdn_b_l1l2(bc, + PH_DATA | CONFIRM, + (void *) skb-> + truesize); + dev_kfree_skb_any(skb); + goto next; + } else + bc->txskb = skb; + } + spin_unlock_irqrestore(&bc->txskb_lock, flags); + next:break; + default: + warn("pr %#x\n", pr); + break; + } + } else { + /* hisax interface is down */ + switch (pr) { + case PH_ACTIVATE | REQUEST: /* activation request */ + dbg("B channel: PH_ACTIVATE | REQUEST with interface down"); + /* don't answer this request! Endless... */ + break; + case PH_DEACTIVATE | REQUEST: /* deactivation request */ + dbg("B channel: PH_DEACTIVATE | REQUEST with interface down"); + ifc->l1l2(ifc, PH_DEACTIVATE | INDICATION, NULL); + break; + case PH_DATA | REQUEST: /* Transmit data request */ + dbg("B channel: PH_DATA | REQUEST with interface down"); + skb = (struct sk_buff *) arg; + /* free data buffer */ + if (skb) { + skb_pull(skb, skb->len); + dev_kfree_skb_any(skb); + } + /* send confirmation back to layer 2 */ + ifc->l1l2(ifc, PH_DATA | CONFIRM, NULL); + break; + default: + warn("pr %#x\n", pr); + break; + } + } +} + +/* Completion handler for B channel input endpoint */ +void auerisdn_intbi_complete(struct urb *urb) +{ + unsigned int bytecount; + unsigned char *ucp; + int channel; + unsigned int syncbit; + unsigned int syncdata; + struct auerisdnbc *bc; + struct sk_buff *skb; + int count; + int status; + struct auerswald *cp = (struct auerswald *) urb->context; + /* do not respond to an error condition */ + if (urb->status != 0) { + dbg("nonzero URB status = %d", urb->status); + return; + } + if (cp->disconnecting) + return; + + /* Parse and extract the header information */ + bytecount = urb->actual_length; + ucp = cp->isdn.intbi_bufp; + if (!bytecount) + return; /* no data */ + channel = *ucp & AUH_TYPEMASK; + syncbit = *ucp & AUH_SYNC; + ucp++; + bytecount--; + channel -= AUH_B1CHANNEL; + if (channel < 0) + return; /* unknown data channel, no B1,B2 */ + if (channel >= AUISDN_BCHANNELS) + return; /* unknown data channel, no B1,B2 */ + bc = &cp->isdn.bc[channel]; + if (!bytecount) + return; + /* Calculate amount of bytes which are free in tx device buffer */ + bc->txfree = ((255 - *ucp++) * bc->ofsize) / 256; + /* dbg ("%d Bytes free in TX buffer", bc->txfree); */ + bytecount--; + + /* Next Byte: TX sync information */ + if (syncbit) { + if (!bytecount) + goto int_tx; + syncdata = *ucp++; + dbg("Sync data = %d", syncdata); + bytecount--; + } + /* The rest of the paket is plain data */ + if (!bytecount) + goto int_tx; + /* dump ("RX Data is:", ucp, bytecount); */ + + /* Send B channel data to upper layers */ + while (bytecount > 0) { + if (bc->mode == L1_MODE_NULL) { + /* skip the data. Nobody needs them */ + status = 0; + bytecount = 0; + } else if (bc->mode == L1_MODE_TRANS) { + { /* swap rx bytes */ + register unsigned char *dest = bc->rxbuf; + status = bytecount; + for (; bytecount; bytecount--) + *dest++ = + isdnhdlc_bit_rev_tab[*ucp++]; + } + + } else { + status = isdnhdlc_decode(&bc->inp_hdlc_state, ucp, + bytecount, &count, + bc->rxbuf, AUISDN_RXSIZE); + ucp += count; + bytecount -= count; + } + if (status > 0) { + /* Good frame received */ + if (!(skb = dev_alloc_skb(status))) { + warn("receive out of memory"); + break; + } + memcpy(skb_put(skb, status), bc->rxbuf, status); + /* dump ("HDLC Paket", bc->rxbuf, status); */ + auerisdn_b_l1l2(bc, PH_DATA | INDICATION, skb); + /* these errors may actually happen at the start of a connection! */ + } else if (status == -HDLC_CRC_ERROR) { + dbg("CRC error"); + } else if (status == -HDLC_FRAMING_ERROR) { + dbg("framing error"); + } else if (status == -HDLC_LENGTH_ERROR) { + dbg("length error"); + } + } + + int_tx: /* serve the outgoing B channel */ + auerisdn_bserv(&cp->isdn); +} + +/* Stop the B channel activity. The device is disconnecting */ +/* This function is called after cp->disconnecting is true */ +unsigned int auerisdn_b_disconnect(struct auerswald *cp) +{ + unsigned int u; + struct auerisdnbc *bc; + unsigned int result = 0; + + /* Close the B channels */ + for (u = 0; u < AUISDN_BCHANNELS; u++) { + bc = &cp->isdn.bc[u]; + if (bc->mode != L1_MODE_NULL) { /* B channel is active */ + auerisdn_bmode(bc, L1_MODE_NULL); + result = 1; + } + } + /* return 1 if there is B channel traffic */ + return result; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerisdn_b.h linux.21pre4-ac6/drivers/usb/auerisdn_b.h --- linux.21pre4/drivers/usb/auerisdn_b.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerisdn_b.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,66 @@ +/*****************************************************************************/ +/* + * auerisdn_b.h -- Auerswald PBX/System Telephone ISDN B channel interface. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#ifndef AUERISDN_B_H +#define AUERISDN_B_H + +#include <../drivers/isdn/hisax/hisax_if.h> +#include +#include "auerbuf.h" +#include <../drivers/isdn/hisax/isdnhdlc.h> + +#define AUISDN_RXSIZE 4096 /* RX buffer size */ +#define AUISDN_BCHANNELS 2 /* Number of supported B channels */ + +/* states for intbo_state */ +#define INTBOS_IDLE 0 +#define INTBOS_RUNNING 1 +#define INTBOS_CHANGE 2 +#define INTBOS_RESTART 3 + +/* ...................................................................*/ +/* B channel state data */ +struct auerswald; +struct auerisdnbc { + struct auerswald *cp; /* Context to usb device */ + struct sk_buff *txskb; /* sk buff to transmitt */ + spinlock_t txskb_lock; /* protect against races */ + unsigned int mode; /* B-channel mode */ + unsigned int channel; /* Number of this B-channel */ + unsigned int ofsize; /* Size of device OUT fifo in Bytes */ + int txfree; /* free bytes in tx buffer of device */ + unsigned int txsize; /* size of data paket for this channel */ + unsigned char *rxbuf; /* Receiver input buffer */ + struct isdnhdlc_vars inp_hdlc_state; /* state for RX software HDLC */ + struct isdnhdlc_vars outp_hdlc_state; /* state for TX software HDLC */ + unsigned int lastbyte; /* last byte sent out to trans. B channel */ +}; + +/* Function Prototypes */ +void auerisdn_b_l2l1(struct hisax_if *ifc, int pr, void *arg, + unsigned int channel); +void auerisdn_b_l1l2(struct auerisdnbc *bc, int pr, void *arg); + +void auerisdn_intbi_complete(struct urb *urb); +unsigned int auerisdn_b_disconnect(struct auerswald *cp); + +#endif /* AUERISDN_B_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerisdn.c linux.21pre4-ac6/drivers/usb/auerisdn.c --- linux.21pre4/drivers/usb/auerisdn.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerisdn.c 2003-02-21 15:46:07.000000000 +0000 @@ -0,0 +1,1076 @@ +/*****************************************************************************/ +/* + * auerisdn.c -- Auerswald PBX/System Telephone ISDN interface. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#include +#include +#include + +#undef DEBUG /* include debug macros until it's done */ +#include + +#include "auerisdn.h" +#include "auermain.h" + +/*-------------------------------------------------------------------*/ +/* ISDN support defines */ +#define AUISDN_TEI 64 /* use a constant TEI */ + +/*-------------------------------------------------------------------*/ +/* Debug support */ +#ifdef DEBUG +#define dump( desc, adr, len) \ +do { \ + unsigned int u; \ + printk (KERN_DEBUG); \ + printk (desc); \ + for (u = 0; u < len; u++) \ + printk (" %02X", adr[u] & 0xFF); \ + printk ("\n"); \ +} while (0) +#else +#define dump( desc, adr, len) +#endif + +/*-------------------------------------------------------------------*/ +/* Hisax Interface. */ + +/* The interface to hisax is long-lasting because hisax_unregister() + don't work well in Linux 2.4.x. So we have to hold each registered + hisax interface until driver removal. */ +static struct auerhisax auerhisax_table[AUER_MAX_DEVICES]; + + +/*-------------------------------------------------------------------*/ + +/* Callback to L2 for HISAX */ +/* This callback can be called from 3 sources: + a) from hisax context (answer from a l2l1 function) + b) from interrupt context (a D channel paket arrived) + c) from kernel daemon context (probe/disconnecting) +*/ +static void auerisdn_d_l1l2(struct auerisdn *ip, int pr, void *arg) +{ + struct sk_buff *skb; + struct auerhisax *ahp; + + /* do the callback */ + ahp = ip->ahp; + if (ahp) { + ahp->hisax_d_if.ifc.l1l2(&ahp->hisax_d_if.ifc, pr, arg); + } else { + dbg("auerisdn_d_l1l2 with ahp == NULL"); + if (pr == (PH_DATA | INDICATION)) { + skb = (struct sk_buff *) arg; + if (skb) { + skb_pull(skb, skb->len); + dev_kfree_skb_any(skb); + } + } + } +} + + +/* D-Channel sending completion function */ +static void auerisdn_dcw_complete(struct urb *urb) +{ + struct auerbuf *bp = (struct auerbuf *) urb->context; + struct auerswald *cp = + ((struct auerswald *) ((char *) (bp->list) - + (unsigned + long) (&((struct auerswald *) 0)-> + bufctl))); + + dbg("auerisdn_dcw_complete with status %d", urb->status); + + /* reuse the buffer */ + auerbuf_releasebuf(bp); + + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); +} + + +/* Translate non-ETSI ISDN messages from the device */ +static void auerisdn_translate_incoming(struct auerswald *cp, + unsigned char *msg, + unsigned int len) +{ + struct auerbuf *bp; + int ret; + + /* Translate incomming CONNECT -> CONNECT_ACK */ + /* Format: 0 1 2 3 4 5 6 7 */ + /* SAPI TEI TXSEQ RXSEQ PID=08 CREFLEN=01 CREF MSG=7 ...*/ + /* CREF.7 == 0 -> Incoming Call */ + + /* Check for minimum length */ + if (len < 8) + return; + + /* Check for a CONNECT, call originated from device */ + if (((msg[6] & 0x80) == 0) && (msg[7] == 0x07)) { + dbg("false CONNECT from device found"); + /* change into CONNECT_ACK */ + msg[7] = 0x0F; + + /* Send a CONNECT_ACK back to the device */ + + /* get a new data buffer */ + bp = auerbuf_getbuf(&cp->bufctl); + if (!bp) { + warn("no auerbuf free"); + return; + } + + /* Form a CONNECT ACK */ + bp->bufp[0] = + cp->isdn.dchannelservice.id | AUH_DIRECT | AUH_UNSPLIT; + bp->bufp[1] = 0x08; + bp->bufp[2] = 0x01; + bp->bufp[3] = msg[6] | 0x80; + bp->bufp[4] = 0x0F; + + /* Set the transfer Parameters */ + bp->len = 5; + bp->dr->bRequestType = AUT_WREQ; + bp->dr->bRequest = AUV_WBLOCK; + bp->dr->wValue = cpu_to_le16(0); + bp->dr->wIndex = + cpu_to_le16(cp->isdn.dchannelservice. + id | AUH_DIRECT | AUH_UNSPLIT); + bp->dr->wLength = cpu_to_le16(5); + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_sndctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, bp->bufp, 5, + auerisdn_dcw_complete, bp); + /* up we go */ + ret = auerchain_submit_urb(&cp->controlchain, bp->urbp); + if (ret) + auerisdn_dcw_complete(bp->urbp); + else + dbg("auerisdn_translate: Write OK"); + } + /* Check for a DISCONNECT and change to RELEASE */ + if (msg[7] == 0x45) { + dbg("DISCONNECT changed to RELEASE"); + msg[7] = 0x4D; + return; + } +} + + +/* a D-channel paket arrived from the device */ +static void auerisdn_dispatch_dc(struct auerscon *scp, struct auerbuf *bp) +{ + struct sk_buff *skb; + struct auerhisax *ahp; + struct auerswald *cp = + ((struct auerswald *) ((char *) (scp) - + (unsigned + long) (&((struct auerswald *) 0)->isdn. + dchannelservice))); + unsigned char *sp; + unsigned int l2_index; + unsigned char c; + unsigned char l2_header[10]; + unsigned long flags; + + dump("D-Channel paket arrived:", bp->bufp, bp->len); + if (cp->disconnecting) + return; + + /* add a self-generated L2 message header */ + l2_index = 0; + l2_header[l2_index++] = 0x02; /* SAPI 0, C/R = 1 */ + + /* Parse the L3 message */ + sp = bp->bufp + AUH_SIZE; + + c = *sp++; /* Protocol discriminator */ + if (c != 0x08) { + warn("D channel paket is not ETSI"); + return; + } + c = *sp++; /* Call Reference length byte */ + sp += c; /* Skip Call Reference */ + + /* translate charge IEs */ + /* Format of Auerswald Header: + 0x32 len=0x0B 0xFF 0xFF 0x73 len=0x07 0x27 */ + /* Format of IE2_UNIT: + 0x49 len=0x04 uu1 uu2 uu3 uu4 */ + /* Translate into: (?? Bytes) + 0x1C Facility + 0x?? restlen + 0x91 Sup. Services + 0xA1 Invoke + 0x?? restlen + 0x02 Invoke ID Tag + 0x02 Invoke ID len + 0x12 Invoke ID = 0x1234 + 0x34 + 0x02 OP Value Tag + 0x01 Length of OPvalue + 0x24 OpValue = AOCE + 0x30 Universal Constructor Sequence + 0x?? restlen + 0x30 Universal Constructor Sequence + 0x?? restlen + 0xA1 Context Specific Constructor Recorded Units List + 0x?? restlen + 0x30 Universal Constructor Sequence + 0x?? restlen + 0x02 Universal Primitive Integer + 0x?? len from IE2_UNIT + uu1 Recorded Units List + uu2 + uu3 + uu4 + */ + { + unsigned char *ucp = sp; // pointer to start of msg + int l = bp->len; // length until EOP + unsigned char alen; // length of auerswald msg + l -= (int) (ucp - bp->bufp); + // scan for Auerswald Header + for (; l >= 9; l--, ucp++) { // 9 = minimal length of auerswald msg + if (ucp[0] != 0x32) + continue; + if (ucp[2] != 0xFF) + continue; + if (ucp[3] != 0xFF) + continue; + if (ucp[4] != 0x73) + continue; + if (ucp[6] != 0x27) + continue; + // Auerswald Header found. Is it units? + dbg("Auerswald msg header found"); + alen = ucp[1] + 2; + if (ucp[7] == 0x49) { + // yes + unsigned char ul = ucp[8] + 1; // length of charge integer + unsigned char charge[32]; + // Copy charge info into new buffer + unsigned char *xp = &ucp[8]; + int count; + for (count = 0; count < ul; count++) + charge[count] = *xp++; + // Erase auerswald msg + count = l - alen; + xp = ucp; + for (; count; count--, xp++) + xp[0] = xp[alen]; + l -= alen; + bp->len -= alen; + // make room for new message + count = l; + xp = &ucp[l - 1]; + for (; count; count--, xp--); + xp[21 + ul] = xp[0]; + l += (21 + ul); + bp->len += (21 + ul); + // insert IE header + ucp[0] = 0x1C; + ucp[1] = 19 + ul; + ucp[2] = 0x91; + ucp[3] = 0xA1; + ucp[4] = 16 + ul; + ucp[5] = 0x02; + ucp[6] = 0x02; + ucp[7] = 0x12; + ucp[8] = 0x34; + ucp[9] = 0x02; + ucp[10] = 0x01; + ucp[11] = 0x24; + ucp[12] = 0x30; + ucp[13] = 7 + ul; + ucp[14] = 0x30; + ucp[15] = 5 + ul; + ucp[16] = 0xA1; + ucp[17] = 3 + ul; + ucp[18] = 0x30; + ucp[19] = 1 + ul; + ucp[20] = 0x02; + // Insert charge units + xp = &ucp[21]; + for (count = 0; count < ul; count++) + *xp++ = charge[count]; + dump("Rearranged message:", bp->bufp, + bp->len); + break; + } else { + // we can't handle something else, erase it + int count = l - alen; + unsigned char *xp = ucp; + for (; count; count--, xp++) + xp[0] = xp[alen]; + l -= alen; + bp->len -= alen; + dump("Shortened message:", bp->bufp, + bp->len); + } + } + } + + + c = *sp; /* Message type */ + if (c == 0x05) { + /* SETUP. Use an UI frame */ + dbg("SETUP"); + l2_header[l2_index++] = 0xFF; /* TEI 127 */ + l2_header[l2_index++] = 0x03; /* UI control field */ + skb = dev_alloc_skb(bp->len - AUH_SIZE + l2_index); + } else { + /* use an I frame */ + dbg("I Frame"); + l2_header[l2_index++] = (AUISDN_TEI << 1) | 0x01; /* TEI byte */ + skb = dev_alloc_skb(bp->len - AUH_SIZE + l2_index + 2); + if (skb) { + ahp = cp->isdn.ahp; + if (!ahp) { + err("ahp == NULL"); + return; + } + spin_lock_irqsave(&ahp->seq_lock, flags); + l2_header[l2_index++] = ahp->txseq; /* transmitt sequence number */ + l2_header[l2_index++] = ahp->rxseq; /* receive sequence number */ + ahp->txseq += 2; /* next paket gets next number */ + spin_unlock_irqrestore(&ahp->seq_lock, flags); + } + } + if (!skb) { + err("no memory - skipped"); + return; + } + sp = skb_put(skb, bp->len - AUH_SIZE + l2_index); + /* Add L2 header */ + memcpy(sp, l2_header, l2_index); + memcpy(sp + l2_index, bp->bufp + AUH_SIZE, bp->len - AUH_SIZE); + /* Translate false messages */ + auerisdn_translate_incoming(cp, sp, bp->len - AUH_SIZE + l2_index); + /* Send message to L2 */ + auerisdn_d_l1l2(&cp->isdn, PH_DATA | INDICATION, skb); +} + +/* D-channel is closed because the device is removed */ +/* This is a no-op because ISDN close is handled different */ +static void auerisdn_disconnect_dc(struct auerscon *scp) +{ +} + + +/* confirmation helper function. */ +static void auerisdn_d_confirmskb(struct auerswald *cp, + struct sk_buff *skb) +{ + /* free the skb */ + if (skb) { + skb_pull(skb, skb->len); + dev_kfree_skb_any(skb); + } + + /* confirm the sending of data */ + dbg("Confirm PH_DATA"); + auerisdn_d_l1l2(&cp->isdn, PH_DATA | CONFIRM, NULL); +} + +/* D-channel transfer function L2->L1 */ +static void auerisdn_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) +{ + struct auerhisax *ahp; + struct sk_buff *skb; + unsigned int len; + int ret; + struct auerbuf *bp; + struct auerswald *cp; + unsigned long flags; + unsigned int l2_index; + unsigned char c; + unsigned char l2_header[32]; + unsigned char *sp; + + dbg("hisax D-Channel l2l1 called"); + + /* Get reference to auerhisax struct */ + cp = NULL; + ahp = hisax_d_if->priv; + if (ahp) + cp = ahp->cp; + if (cp && !cp->disconnecting) { + /* normal usage */ + switch (pr) { + case PH_ACTIVATE | REQUEST: /* activation request */ + dbg("Activation Request"); + cp->isdn.dc_activated = 1; + /* send activation back to layer 2 */ + auerisdn_d_l1l2(&cp->isdn, + PH_ACTIVATE | INDICATION, NULL); + break; + case PH_DEACTIVATE | REQUEST: /* deactivation request */ + dbg("Deactivation Request"); + cp->isdn.dc_activated = 0; + /* send deactivation back to layer 2 */ + auerisdn_d_l1l2(&cp->isdn, + PH_DEACTIVATE | INDICATION, NULL); + break; + case PH_DATA | REQUEST: /* Transmit data request */ + skb = (struct sk_buff *) arg; + len = skb->len; + l2_index = 0; + sp = skb->data; + dump("Data Request:", sp, len); + + /* Parse the L2 header */ + if (!len) + goto phd_free; + c = *sp++; /* SAPI */ + l2_header[l2_index++] = c; + len--; + if (!len) + goto phd_free; + c = *sp++; /* TEI */ + l2_header[l2_index++] = c; + len--; + if (!len) + goto phd_free; + c = *sp++; /* Control Field, Byte 1 */ + len--; + if (!(c & 0x01)) { + /* I FRAME */ + dbg("I Frame"); + if (!len) + goto phd_free; + spin_lock_irqsave(&ahp->seq_lock, flags); + ahp->rxseq = c + 2; /* store new sequence info */ + spin_unlock_irqrestore(&ahp->seq_lock, + flags); + sp++; /* skip Control Field, Byte 2 */ + len--; + /* Check for RELEASE command */ + /* and change to RELEASE_COMPLETE */ + if (sp[3] == 0x4D) + sp[3] = 0x5A; + goto phd_send; + } + /* check the frame type */ + switch (c) { + case 0x03: /* UI frame */ + dbg("UI Frame"); + if (l2_header[0] == 0xFC) { + dbg("TEI Managment"); + l2_header[0] = 0xFE; /* set C/R bit in answer */ + l2_header[l2_index++] = c; /* Answer is UI frame */ + if (!len) + break; + c = *sp++; /* Managment ID */ + len--; + if (c != 0x0F) + break; + l2_header[l2_index++] = c; + /* Read Reference Number */ + if (!len) + break; + l2_header[l2_index++] = *sp++; + len--; + if (!len) + break; + l2_header[l2_index++] = *sp++; + len--; + if (!len) + break; + c = *sp++; /* Message Type */ + len--; + switch (c) { + case 0x01: /* Identity Request */ + dbg("Identity Request"); + l2_header[l2_index++] = 0x02; /* Identity Assign */ + l2_header[l2_index++] = + (AUISDN_TEI << 1) | + 0x01; + goto phd_answer; + default: + dbg("Unhandled TEI Managment %X", (int) c); + break; + } + // throw away + goto phd_free; + } + /* else send UI frame out */ + goto phd_send; + case 0x01: /* RR frame */ + case 0x05: /* RNR frame */ + dbg("RR/RNR Frame"); + if (!len) + break; + c = *sp++; /* Control Field, Byte 2 */ + len--; + if (!(c & 0x01)) + break; /* P/F = 1 in commands */ + if (l2_header[0] & 0x02) + break; /* C/R = 0 from TE */ + dbg("Send RR as answer"); + l2_header[l2_index++] = 0x01; /* send an RR as Answer */ + spin_lock_irqsave(&ahp->seq_lock, flags); + l2_header[l2_index++] = ahp->rxseq | 0x01; + spin_unlock_irqrestore(&ahp->seq_lock, + flags); + goto phd_answer; + case 0x7F: /* SABME */ + dbg("SABME"); + spin_lock_irqsave(&ahp->seq_lock, flags); + ahp->txseq = 0; + ahp->rxseq = 0; + spin_unlock_irqrestore(&ahp->seq_lock, + flags); + l2_header[l2_index++] = 0x73; /* UA */ + goto phd_answer; + case 0x53: /* DISC */ + dbg("DISC"); + /* Send back a UA */ + l2_header[l2_index++] = 0x73; /* UA */ + goto phd_answer; + default: + dbg("Unhandled L2 Message %X", (int) c); + break; + } + /* all done */ + goto phd_free; + + /* we have to generate a local answer */ + /* first, confirm old message, free old skb */ + phd_answer:auerisdn_d_confirmskb(cp, + skb); + + /* allocate a new skbuff */ + skb = dev_alloc_skb(l2_index); + if (!skb) { + err("no memory for new skb"); + break; + } + dump("local answer to L2 is:", l2_header, + l2_index); + memcpy(skb_put(skb, l2_index), l2_header, + l2_index); + auerisdn_d_l1l2(&cp->isdn, PH_DATA | INDICATION, + skb); + break; + + /* we have to send the L3 message out */ + phd_send:if (!len) + goto phd_free; /* no message left */ + + /* get a new data buffer */ + bp = auerbuf_getbuf(&cp->bufctl); + if (!bp) { + warn("no auerbuf free"); + goto phd_free; + } + /* protect against too big write requests */ + /* Should not happen */ + if (len > cp->maxControlLength) { + err("too long D-channel paket truncated"); + len = cp->maxControlLength; + } + + /* Copy the data */ + memcpy(bp->bufp + AUH_SIZE, sp, len); + + /* set the header byte */ + *(bp->bufp) = + cp->isdn.dchannelservice. + id | AUH_DIRECT | AUH_UNSPLIT; + + /* Set the transfer Parameters */ + bp->len = len + AUH_SIZE; + bp->dr->bRequestType = AUT_WREQ; + bp->dr->bRequest = AUV_WBLOCK; + bp->dr->wValue = cpu_to_le16(0); + bp->dr->wIndex = + cpu_to_le16(cp->isdn.dchannelservice. + id | AUH_DIRECT | AUH_UNSPLIT); + bp->dr->wLength = cpu_to_le16(len + AUH_SIZE); + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_sndctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, + bp->bufp, len + AUH_SIZE, + auerisdn_dcw_complete, bp); + /* up we go */ + ret = + auerchain_submit_urb(&cp->controlchain, + bp->urbp); + if (ret) + auerisdn_dcw_complete(bp->urbp); + else + dbg("auerisdn_dwrite: Write OK"); + /* confirm message, free skb */ + phd_free:auerisdn_d_confirmskb(cp, + skb); + break; + + default: + warn("pr %#x\n", pr); + break; + } + } else { + /* hisax interface is down */ + switch (pr) { + case PH_ACTIVATE | REQUEST: /* activation request */ + dbg("D channel PH_ACTIVATE | REQUEST with interface down"); + /* don't answer this request! Endless... */ + break; + case PH_DEACTIVATE | REQUEST: /* deactivation request */ + dbg("D channel PH_DEACTIVATE | REQUEST with interface down"); + hisax_d_if->l1l2(hisax_d_if, + PH_DEACTIVATE | INDICATION, NULL); + break; + case PH_DATA | REQUEST: /* Transmit data request */ + dbg("D channel PH_DATA | REQUEST with interface down"); + skb = (struct sk_buff *) arg; + /* free data buffer */ + if (skb) { + skb_pull(skb, skb->len); + dev_kfree_skb_any(skb); + } + /* send confirmation back to layer 2 */ + hisax_d_if->l1l2(hisax_d_if, PH_DATA | CONFIRM, + NULL); + break; + default: + warn("pr %#x\n", pr); + break; + } + } +} + + +/* Completion function for D channel open */ +static void auerisdn_dcopen_complete(struct urb *urbp) +{ + struct auerbuf *bp = (struct auerbuf *) urbp->context; + struct auerswald *cp = + ((struct auerswald *) ((char *) (bp->list) - + (unsigned + long) (&((struct auerswald *) 0)-> + bufctl))); + dbg("auerisdn_dcopen_complete called"); + + auerbuf_releasebuf(bp); + + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); +} + + +/* Open the D-channel once more */ +static void auerisdn_dcopen(unsigned long data) +{ + struct auerswald *cp = (struct auerswald *) data; + struct auerbuf *bp; + int ret; + + if (cp->disconnecting) + return; + dbg("auerisdn_dcopen running"); + + /* get a buffer for the command */ + bp = auerbuf_getbuf(&cp->bufctl); + /* if no buffer available: can't change the mode */ + if (!bp) { + err("auerisdn_dcopen: no data buffer available"); + return; + } + + /* fill the control message */ + bp->dr->bRequestType = AUT_WREQ; + bp->dr->bRequest = AUV_CHANNELCTL; + bp->dr->wValue = cpu_to_le16(1); + bp->dr->wIndex = cpu_to_le16(0); + bp->dr->wLength = cpu_to_le16(0); + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_sndctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, bp->bufp, 0, + (usb_complete_t) auerisdn_dcopen_complete, bp); + + /* submit the control msg */ + ret = auerchain_submit_urb(&cp->controlchain, bp->urbp); + dbg("dcopen submitted"); + if (ret) { + bp->urbp->status = ret; + auerisdn_dcopen_complete(bp->urbp); + } + return; +} + + +/* Initialize the isdn related items in struct auerswald */ +void auerisdn_init_dev(struct auerswald *cp) +{ + unsigned int u; + cp->isdn.dchannelservice.id = AUH_UNASSIGNED; + cp->isdn.dchannelservice.dispatch = auerisdn_dispatch_dc; + cp->isdn.dchannelservice.disconnect = auerisdn_disconnect_dc; + init_timer(&cp->isdn.dcopen_timer); + cp->isdn.dcopen_timer.data = (unsigned long) cp; + cp->isdn.dcopen_timer.function = auerisdn_dcopen; + for (u = 0; u < AUISDN_BCHANNELS; u++) { + cp->isdn.bc[u].cp = cp; + cp->isdn.bc[u].mode = L1_MODE_NULL; + cp->isdn.bc[u].channel = u; + spin_lock_init(&cp->isdn.bc[u].txskb_lock); + } +} + + +/* Connect to the HISAX interface. Returns 0 if successfull */ +int auerisdn_probe(struct auerswald *cp) +{ + struct hisax_b_if *b_if[AUISDN_BCHANNELS]; + struct usb_endpoint_descriptor *ep; + struct auerhisax *ahp; + DECLARE_WAIT_QUEUE_HEAD(wqh); + unsigned int u; + unsigned char *ucp; + unsigned int first_time; + int ret; + + /* First allocate resources, then register hisax interface */ + + /* Allocate RX buffers */ + for (u = 0; u < AUISDN_BCHANNELS; u++) { + if (!cp->isdn.bc[u].rxbuf) { + cp->isdn.bc[u].rxbuf = + (char *) kmalloc(AUISDN_RXSIZE, GFP_KERNEL); + if (!cp->isdn.bc[u].rxbuf) { + err("can't allocate buffer for B channel RX data"); + return -1; + } + } + } + + /* Read out B-Channel output fifo size */ + ucp = kmalloc(32, GFP_KERNEL); + if (!ucp) { + err("Out of memory"); + return -3; + } + ret = usb_control_msg(cp->usbdev, /* pointer to device */ + usb_rcvctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ + AUV_GETINFO, /* USB message request value */ + AUT_RREQ, /* USB message request type value */ + 0, /* USB message value */ + AUDI_OUTFSIZE, /* USB message index value */ + ucp, /* pointer to the receive buffer */ + 32, /* length of the buffer */ + HZ * 2); /* time to wait for the message to complete before timing out */ + if (ret < 4) { + kfree(ucp); + err("can't read TX Fifo sizes for B1,B2"); + return -4; + } + for (u = 0; u < AUISDN_BCHANNELS; u++) { + ret = le16_to_cpup(ucp + u * 2); + cp->isdn.bc[u].ofsize = ret; + cp->isdn.bc[u].txfree = ret; + } + kfree(ucp); + for (u = 0; u < AUISDN_BCHANNELS; u++) { + dbg("B%d buffer size is %d", u, cp->isdn.bc[u].ofsize); + } + + /* get the B channel output INT size */ + cp->isdn.intbo_endp = AU_IRQENDPBO; + ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_OUT | AU_IRQENDPBO); + if (!ep) { + /* Some devices have another endpoint number here ... */ + cp->isdn.intbo_endp = AU_IRQENDPBO_2; + ep = usb_epnum_to_ep_desc(cp->usbdev, + USB_DIR_OUT | AU_IRQENDPBO_2); + if (!ep) { + err("can't get B channel OUT endpoint"); + return -5; + } + } + cp->isdn.outsize = ep->wMaxPacketSize; + cp->isdn.outInterval = ep->bInterval; + cp->isdn.usbdev = cp->usbdev; + + /* allocate the urb and data buffer */ + if (!cp->isdn.intbo_urbp) { + cp->isdn.intbo_urbp = usb_alloc_urb(0); + if (!cp->isdn.intbo_urbp) { + err("can't allocate urb for B channel output endpoint"); + return -6; + } + } + if (!cp->isdn.intbo_bufp) { + cp->isdn.intbo_bufp = + (char *) kmalloc(cp->isdn.outsize, GFP_KERNEL); + if (!cp->isdn.intbo_bufp) { + err("can't allocate buffer for B channel output endpoint"); + return -7; + } + } + + /* get the B channel input INT size */ + ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_IN | AU_IRQENDPBI); + if (!ep) { + err("can't get B channel IN endpoint"); + return -8; + } + cp->isdn.insize = ep->wMaxPacketSize; + + /* allocate the urb and data buffer */ + if (!cp->isdn.intbi_urbp) { + cp->isdn.intbi_urbp = usb_alloc_urb(0); + if (!cp->isdn.intbi_urbp) { + err("can't allocate urb for B channel input endpoint"); + return -9; + } + } + if (!cp->isdn.intbi_bufp) { + cp->isdn.intbi_bufp = + (char *) kmalloc(cp->isdn.insize, GFP_KERNEL); + if (!cp->isdn.intbi_bufp) { + err("can't allocate buffer for B channel input endpoint"); + return -10; + } + } + + /* setup urb */ + FILL_INT_URB(cp->isdn.intbi_urbp, cp->usbdev, + usb_rcvintpipe(cp->usbdev, AU_IRQENDPBI), + cp->isdn.intbi_bufp, cp->isdn.insize, + auerisdn_intbi_complete, cp, ep->bInterval); + /* start the urb */ + cp->isdn.intbi_urbp->status = 0; /* needed! */ + ret = usb_submit_urb(cp->isdn.intbi_urbp); + if (ret < 0) { + err("activation of B channel input int failed %d", ret); + usb_free_urb(cp->isdn.intbi_urbp); + cp->isdn.intbi_urbp = NULL; + return -11; + } + + /* request the D-channel service now */ + dbg("Requesting D channel now"); + cp->isdn.dchannelservice.id = AUH_DCHANNEL; + if (auerswald_addservice(cp, &cp->isdn.dchannelservice)) { + err("can not open D-channel"); + cp->isdn.dchannelservice.id = AUH_UNASSIGNED; + return -2; + } + + /* Find a free hisax interface */ + for (u = 0; u < AUER_MAX_DEVICES; u++) { + ahp = &auerhisax_table[u]; + if (!ahp->cp) { + first_time = (u == 0); + goto ahp_found; + } + } + /* no free interface found */ + return -12; + + /* we found a free hisax interface */ + ahp_found: + /* Wait until ipppd timeout expired. The reason behind this ugly construct: + If we connect to a hisax device without waiting for ipppd we are not able + to make a new IP connection. */ + if (ahp->last_close) { + unsigned long timeout = jiffies - ahp->last_close; + if (timeout < AUISDN_IPTIMEOUT) { + info("waiting for ipppd to timeout"); + sleep_on_timeout(&wqh, AUISDN_IPTIMEOUT - timeout); + } + } + + cp->isdn.ahp = ahp; + u = ahp->hisax_registered; + ahp->hisax_registered = 1; + ahp->cp = cp; + + /* now do the registration */ + if (!u) { + for (u = 0; u < AUISDN_BCHANNELS; u++) { + b_if[u] = &ahp->hisax_b_if[u]; + } + if (hisax_register + (&ahp->hisax_d_if, b_if, "auerswald_usb", + ISDN_PTYPE_EURO)) { + err("hisax registration failed"); + ahp->cp = NULL; + cp->isdn.ahp = NULL; + ahp->hisax_registered = 0; + return -13; + } + dbg("hisax interface registered"); + } + + /* send a D channel L1 activation indication to hisax */ + auerisdn_d_l1l2(&cp->isdn, PH_ACTIVATE | INDICATION, NULL); + cp->isdn.dc_activated = 1; + + /* do another D channel activation for problematic devices */ + cp->isdn.dcopen_timer.expires = jiffies + HZ; + dbg("add timer"); + add_timer(&cp->isdn.dcopen_timer); + + return 0; +} + +/* The USB device was disconnected */ +void auerisdn_disconnect(struct auerswald *cp) +{ + struct auerhisax *ahp; + DECLARE_WAIT_QUEUE_HEAD(wqh); + unsigned long flags; + unsigned int u; + int ret; + unsigned int stop_bc; + + dbg("auerisdn_disconnect called"); + + /* stop a running timer */ + del_timer_sync(&cp->isdn.dcopen_timer); + + /* first, stop the B channels */ + stop_bc = auerisdn_b_disconnect(cp); + + /* stop the D channels */ + auerisdn_d_l1l2(&cp->isdn, PH_DEACTIVATE | INDICATION, NULL); + cp->isdn.dc_activated = 0; + dbg("D-Channel disconnected"); + + /* Wait a moment */ + sleep_on_timeout(&wqh, HZ / 10); + + /* Shut the connection to the hisax interface */ + ahp = cp->isdn.ahp; + if (ahp) { + dbg("closing connection to hisax interface"); + ahp->cp = NULL; + cp->isdn.ahp = NULL; + /* time of last closure */ + if (stop_bc) + /* if we kill a running connection ... */ + ahp->last_close = jiffies; + else + ahp->last_close = 0; + } + + /* Now free the memory */ + if (cp->isdn.intbi_urbp) { + ret = usb_unlink_urb(cp->isdn.intbi_urbp); + if (ret) + dbg("B in: nonzero int unlink result received: %d", + ret); + usb_free_urb(cp->isdn.intbi_urbp); + cp->isdn.intbi_urbp = NULL; + } + kfree(cp->isdn.intbi_bufp); + cp->isdn.intbi_bufp = NULL; + + if (cp->isdn.intbo_urbp) { + cp->isdn.intbo_urbp->transfer_flags &= ~USB_ASYNC_UNLINK; + ret = usb_unlink_urb(cp->isdn.intbo_urbp); + if (ret) + dbg("B out: nonzero int unlink result received: %d", ret); + usb_free_urb(cp->isdn.intbo_urbp); + cp->isdn.intbo_urbp = NULL; + } + kfree(cp->isdn.intbo_bufp); + cp->isdn.intbo_bufp = NULL; + + /* Remove the rx and tx buffers */ + for (u = 0; u < AUISDN_BCHANNELS; u++) { + kfree(cp->isdn.bc[u].rxbuf); + cp->isdn.bc[u].rxbuf = NULL; + spin_lock_irqsave(&cp->isdn.bc[u].txskb_lock, flags); + if (cp->isdn.bc[u].txskb) { + skb_pull(cp->isdn.bc[u].txskb, + cp->isdn.bc[u].txskb->len); + dev_kfree_skb_any(cp->isdn.bc[u].txskb); + cp->isdn.bc[u].txskb = NULL; + } + spin_unlock_irqrestore(&cp->isdn.bc[u].txskb_lock, flags); + } + + /* Remove the D-channel connection */ + auerswald_removeservice(cp, &cp->isdn.dchannelservice); +} + + +/*-------------------------------------------------------------------*/ +/* Environment for long-lasting hisax interface */ + +/* Wrapper for hisax B0 channel L2L1 */ +static void auerisdn_b0_l2l1_wrapper(struct hisax_if *ifc, int pr, + void *arg) +{ + auerisdn_b_l2l1(ifc, pr, arg, 0); +} + +/* Wrapper for hisax B1 channel L2L1 */ +static void auerisdn_b1_l2l1_wrapper(struct hisax_if *ifc, int pr, + void *arg) +{ + auerisdn_b_l2l1(ifc, pr, arg, 1); +} + +/* Init the global variables */ +void auerisdn_init(void) +{ + struct auerhisax *ahp; + unsigned int u; + + memset(&auerhisax_table, 0, sizeof(auerhisax_table)); + for (u = 0; u < AUER_MAX_DEVICES; u++) { + ahp = &auerhisax_table[u]; + spin_lock_init(&ahp->seq_lock); + ahp->hisax_d_if.ifc.priv = ahp; + ahp->hisax_d_if.ifc.l2l1 = auerisdn_d_l2l1; + ahp->hisax_b_if[0].ifc.priv = ahp; + ahp->hisax_b_if[0].ifc.l2l1 = auerisdn_b0_l2l1_wrapper; + ahp->hisax_b_if[1].ifc.priv = ahp; + ahp->hisax_b_if[1].ifc.l2l1 = auerisdn_b1_l2l1_wrapper; + } +} + +/* Deinit the global variables */ +void auerisdn_cleanup(void) +{ + struct auerhisax *ahp; + int i; + + /* cleanup last allocated device first */ + for (i = AUER_MAX_DEVICES - 1; i >= 0; i--) { + ahp = &auerhisax_table[i]; + if (ahp->cp) { + err("hisax device %d open at cleanup", i); + } + if (ahp->hisax_registered) { + hisax_unregister(&ahp->hisax_d_if); + dbg("hisax interface %d freed", i); + } + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerisdn.h linux.21pre4-ac6/drivers/usb/auerisdn.h --- linux.21pre4/drivers/usb/auerisdn.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerisdn.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,94 @@ +/*****************************************************************************/ +/* + * auerisdn.h -- Auerswald PBX/System Telephone ISDN interface. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#ifndef AUERISDN_H +#define AUERISDN_H + +#if (CONFIG_USB_AUERISDN || CONFIG_USB_AUERISDN_MODULE) + +#include +#include "auerserv.h" +#include "auerisdn_b.h" + +#define AUISDN_IPTIMEOUT (HZ * 60) /* IP Timeout is 40s */ + +struct auerswald; +struct auerhisax; + +struct auerisdn { + struct auerscon dchannelservice; /* serving the D channel */ + struct auerhisax *ahp; /* Reference to hisax interface */ + unsigned int dc_activated; /* 1 if D-Channel is activated */ + struct auerisdnbc bc[AUISDN_BCHANNELS]; /* B channel data */ + unsigned int insize; /* Max. Block Size of Input INT */ + unsigned int outsize; /* Max. Block Size of Output INT */ + unsigned int outInterval; /* nr. of ms between INT OUT transfers */ + struct urb *intbi_urbp; /* B channel Input Interrupt urb */ + unsigned char *intbi_bufp; /* B channel Input data buffer */ + unsigned int paketsize; /* Data size of the INT OUT pakets */ + struct usb_device *usbdev; /* USB device handle */ + unsigned int intbo_state; /* Status of INT OUT urb */ + struct urb *intbo_urbp; /* B channel Output Interrupt urb */ + unsigned char *intbo_bufp; /* B channel Output data buffer */ + unsigned int intbo_index; /* Index of last served B channel */ + unsigned int intbo_toggletimer; /* data toggle timer for 2 b channels */ + unsigned int intbo_endp; /* grrr.. different on some devices */ + struct timer_list dcopen_timer; /* Open D-channel once more later... */ +}; + +struct auerhisax { + struct hisax_d_if hisax_d_if; /* Hisax D-Channel interface */ + struct hisax_b_if hisax_b_if[AUISDN_BCHANNELS]; /* Hisax B-channel interfaces */ + struct auerswald *cp; /* Context to usb device */ + unsigned int hisax_registered; /* 1 if registered at hisax interface */ + unsigned char txseq; /* L2 emulation: tx sequence byte */ + unsigned char rxseq; /* L2 emulation: rx sequence byte */ + spinlock_t seq_lock; /* Lock sequence numbers */ + unsigned long last_close; /* Time of last close in jiffies */ +}; + +/* Function Prototypes */ +void auerisdn_init_dev(struct auerswald *cp); + +int auerisdn_probe(struct auerswald *cp); + +void auerisdn_disconnect(struct auerswald *cp); + +void auerisdn_init(void); + +void auerisdn_cleanup(void); + +#else /* no CONFIG_USB_AUERISDN */ + +struct auerisdn { + int dummy; +}; + +/* Dummy ISDN functions */ +#define auerisdn_init_dev( cp) +#define auerisdn_probe( cp) 0 +#define auerisdn_disconnect( cp) +#define auerisdn_init() +#define auerisdn_cleanup() +#endif /* CONFIG_USB_AUERISDN */ + +#endif /* AUERISDN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auermain.c linux.21pre4-ac6/drivers/usb/auermain.c --- linux.21pre4/drivers/usb/auermain.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auermain.c 2003-02-21 15:46:07.000000000 +0000 @@ -0,0 +1,897 @@ +/*****************************************************************************/ +/* + * auermain.c -- Auerswald PBX/System Telephone usb driver. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl) + * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +/* Standard Linux module include files */ +#include +#include +#include +#include +#undef DEBUG /* include debug macros until it's done */ +#include +#include "auerchain.h" +#include "auerbuf.h" +#include "auerchar.h" +#include "auerserv.h" +#include "auermain.h" +#include "auerisdn.h" + +/*-------------------------------------------------------------------*/ +/* Debug support */ +#ifdef DEBUG +#define dump( desc, adr, len) \ +do { \ + unsigned int u; \ + printk (KERN_DEBUG); \ + printk (desc); \ + for (u = 0; u < len; u++) \ + printk (" %02X", adr[u] & 0xFF); \ + printk ("\n"); \ +} while (0) +#else +#define dump( desc, adr, len) +#endif + +/*-------------------------------------------------------------------*/ +/* Version Information */ +#define DRIVER_VERSION "1.2.0" +#define DRIVER_AUTHOR "Wolfgang Mües " +#define DRIVER_DESC "Auerswald PBX/System Telephone usb driver" + +/*-------------------------------------------------------------------*/ +/* Internal data structures */ + +/* the global usb devfs handle */ +extern devfs_handle_t usb_devfs_handle; + +/* array of pointers to our devices that are currently connected */ +static struct auerswald *auerdev_table[AUER_MAX_DEVICES]; + +/* lock to protect the auerdev_table structure */ +static struct semaphore auerdev_table_mutex; + +/*-------------------------------------------------------------------*/ +/* Forwards */ +static void auerswald_ctrlread_complete(struct urb *urb); + +/*-------------------------------------------------------------------*/ +/* Completion handlers */ + +/* Values of urb->status or results of usb_submit_urb(): +0 Initial, OK +-EINPROGRESS during submission until end +-ENOENT if urb is unlinked +-ETIMEDOUT Transfer timed out, NAK +-ENOMEM Memory Overflow +-ENODEV Specified USB-device or bus doesn't exist +-ENXIO URB already queued +-EINVAL a) Invalid transfer type specified (or not supported) + b) Invalid interrupt interval (0n256) +-EAGAIN a) Specified ISO start frame too early + b) (using ISO-ASAP) Too much scheduled for the future wait some time and try again. +-EFBIG Too much ISO frames requested (currently uhci900) +-EPIPE Specified pipe-handle/Endpoint is already stalled +-EMSGSIZE Endpoint message size is zero, do interface/alternate setting +-EPROTO a) Bitstuff error + b) Unknown USB error +-EILSEQ CRC mismatch +-ENOSR Buffer error +-EREMOTEIO Short packet detected +-EXDEV ISO transfer only partially completed look at individual frame status for details +-EINVAL ISO madness, if this happens: Log off and go home +-EOVERFLOW babble +*/ + +/* check if a status code allows a retry */ +static int auerswald_status_retry(int status) +{ + switch (status) { + case 0: + case -ETIMEDOUT: + case -EOVERFLOW: + case -EAGAIN: + case -EPIPE: + case -EPROTO: + case -EILSEQ: + case -ENOSR: + case -EREMOTEIO: + return 1; /* do a retry */ + } + return 0; /* no retry possible */ +} + + +/* Completion of asynchronous write block */ +void auerchar_ctrlwrite_complete(struct urb *urb) +{ + struct auerbuf *bp = (struct auerbuf *) urb->context; + struct auerswald *cp = + ((struct auerswald *) ((char *) (bp->list) - + (unsigned + long) (&((struct auerswald *) 0)-> + bufctl))); + dbg("auerchar_ctrlwrite_complete called"); + + /* reuse the buffer */ + auerbuf_releasebuf(bp); + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); +} + +/* Completion handler for dummy retry packet */ +static void auerswald_ctrlread_wretcomplete(struct urb *urb) +{ + struct auerbuf *bp = (struct auerbuf *) urb->context; + struct auerswald *cp; + int ret; + dbg("auerswald_ctrlread_wretcomplete called"); + dbg("complete with status: %d", urb->status); + cp = ((struct auerswald *) ((char *) (bp->list) - + (unsigned + long) (&((struct auerswald *) 0)-> + bufctl))); + + /* check if it is possible to advance */ + if (!auerswald_status_retry(urb->status) || !cp->usbdev) { + /* reuse the buffer */ + err("control dummy: transmission error %d, can not retry", + urb->status); + auerbuf_releasebuf(bp); + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); + return; + } + + /* fill the control message */ + bp->dr->bRequestType = AUT_RREQ; + bp->dr->bRequest = AUV_RBLOCK; + bp->dr->wLength = bp->dr->wValue; /* temporary stored */ + bp->dr->wValue = cpu_to_le16(1); /* Retry Flag */ + /* bp->dr->wIndex = channel id; remains */ + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_rcvctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, bp->bufp, + le16_to_cpu(bp->dr->wLength), + (usb_complete_t) auerswald_ctrlread_complete, bp); + + /* submit the control msg as next paket */ + ret = auerchain_submit_urb_list(&cp->controlchain, bp->urbp, 1); + if (ret) { + dbg("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); + bp->urbp->status = ret; + auerswald_ctrlread_complete(bp->urbp); + } +} + +/* completion handler for receiving of control messages */ +static void auerswald_ctrlread_complete(struct urb *urb) +{ + unsigned int serviceid; + struct auerswald *cp; + struct auerscon *scp; + struct auerbuf *bp = (struct auerbuf *) urb->context; + int ret; + dbg("auerswald_ctrlread_complete called"); + + cp = ((struct auerswald *) ((char *) (bp->list) - + (unsigned + long) (&((struct auerswald *) 0)-> + bufctl))); + + /* check if there is valid data in this urb */ + if (urb->status) { + dbg("complete with non-zero status: %d", urb->status); + /* should we do a retry? */ + if (!auerswald_status_retry(urb->status) + || !cp->usbdev || (cp->version < AUV_RETRY) + || (bp->retries >= AU_RETRIES)) { + /* reuse the buffer */ + err("control read: transmission error %d, can not retry", urb->status); + auerbuf_releasebuf(bp); + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); + return; + } + bp->retries++; + dbg("Retry count = %d", bp->retries); + /* send a long dummy control-write-message to allow device firmware to react */ + bp->dr->bRequestType = AUT_WREQ; + bp->dr->bRequest = AUV_DUMMY; + bp->dr->wValue = bp->dr->wLength; /* temporary storage */ + // bp->dr->wIndex channel ID remains + bp->dr->wLength = cpu_to_le16(32); /* >= 8 bytes */ + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_sndctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, bp->bufp, 32, + (usb_complete_t) + auerswald_ctrlread_wretcomplete, bp); + + /* submit the control msg as next paket */ + ret = + auerchain_submit_urb_list(&cp->controlchain, bp->urbp, + 1); + if (ret) { + dbg("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); + bp->urbp->status = ret; + auerswald_ctrlread_wretcomplete(bp->urbp); + } + return; + } + + /* get the actual bytecount (incl. headerbyte) */ + bp->len = urb->actual_length; + serviceid = bp->bufp[0] & AUH_TYPEMASK; + dbg("Paket with serviceid %d and %d bytes received", serviceid, + bp->len); + + /* dispatch the paket */ + scp = cp->services[serviceid]; + if (scp) { + /* look, Ma, a listener! */ + scp->dispatch(scp, bp); + } + + /* release the paket */ + auerbuf_releasebuf(bp); + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); +} + +/*-------------------------------------------------------------------*/ +/* Handling of Interrupt Endpoint */ +/* This interrupt Endpoint is used to inform the host about waiting + messages from the USB device. +*/ +/* int completion handler. */ +static void auerswald_int_complete(struct urb *urb) +{ + unsigned int channelid; + unsigned int bytecount; + int ret; + struct auerbuf *bp = NULL; + struct auerswald *cp = (struct auerswald *) urb->context; + + dbg("auerswald_int_complete called"); + + /* do not respond to an error condition */ + if (urb->status != 0) { + dbg("nonzero URB status = %d", urb->status); + return; + } + + /* check if all needed data was received */ + if (urb->actual_length < AU_IRQMINSIZE) { + dbg("invalid data length received: %d bytes", + urb->actual_length); + return; + } + + /* check the command code */ + if (cp->intbufp[0] != AU_IRQCMDID) { + dbg("invalid command received: %d", cp->intbufp[0]); + return; + } + + /* check the command type */ + if (cp->intbufp[1] != AU_BLOCKRDY) { + dbg("invalid command type received: %d", cp->intbufp[1]); + return; + } + + /* now extract the information */ + channelid = cp->intbufp[2]; + bytecount = le16_to_cpup(&cp->intbufp[3]); + + /* check the channel id */ + if (channelid >= AUH_TYPESIZE) { + dbg("invalid channel id received: %d", channelid); + return; + } + + /* check the byte count */ + if (bytecount > (cp->maxControlLength + AUH_SIZE)) { + dbg("invalid byte count received: %d", bytecount); + return; + } + dbg("Service Channel = %d", channelid); + dbg("Byte Count = %d", bytecount); + + /* get a buffer for the next data paket */ + bp = auerbuf_getbuf(&cp->bufctl); + /* if no buffer available: skip it */ + if (!bp) { + dbg("auerswald_int_complete: no data buffer available"); + /* can we do something more? + This is a big problem: if this int packet is ignored, the + device will wait forever and not signal any more data. + The only real solution is: having enought buffers! + Or perhaps temporary disabling the int endpoint? + */ + return; + } + + /* fill the control message */ + bp->dr->bRequestType = AUT_RREQ; + bp->dr->bRequest = AUV_RBLOCK; + bp->dr->wValue = cpu_to_le16(0); + bp->dr->wIndex = cpu_to_le16(channelid | AUH_DIRECT | AUH_UNSPLIT); + bp->dr->wLength = cpu_to_le16(bytecount); + FILL_CONTROL_URB(bp->urbp, cp->usbdev, + usb_rcvctrlpipe(cp->usbdev, 0), + (unsigned char *) bp->dr, bp->bufp, bytecount, + (usb_complete_t) auerswald_ctrlread_complete, bp); + + /* submit the control msg */ + ret = auerchain_submit_urb(&cp->controlchain, bp->urbp); + if (ret) { + dbg("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret); + bp->urbp->status = ret; + auerswald_ctrlread_complete(bp->urbp); + /* here applies the same problem as above: device locking! */ + } +} + +/* int memory deallocation + NOTE: no mutex please! +*/ +static void auerswald_int_free(struct auerswald *cp) +{ + if (cp->inturbp) { + usb_free_urb(cp->inturbp); + cp->inturbp = NULL; + } + kfree(cp->intbufp); +} + +/* This function is called to activate the interrupt + endpoint. This function returns 0 if successfull or an error code. + NOTE: no mutex please! +*/ +static int auerswald_int_open(struct auerswald *cp) +{ + int ret; + struct usb_endpoint_descriptor *ep; + int irqsize; + dbg("auerswald_int_open"); + + ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_IN | AU_IRQENDP); + if (!ep) { + ret = -EFAULT; + goto intoend; + } + irqsize = ep->wMaxPacketSize; + cp->irqsize = irqsize; + + /* allocate the urb and data buffer */ + if (!cp->inturbp) { + cp->inturbp = usb_alloc_urb(0); + if (!cp->inturbp) { + ret = -ENOMEM; + goto intoend; + } + } + if (!cp->intbufp) { + cp->intbufp = (char *) kmalloc(irqsize, GFP_KERNEL); + if (!cp->intbufp) { + ret = -ENOMEM; + goto intoend; + } + } + /* setup urb */ + FILL_INT_URB(cp->inturbp, cp->usbdev, + usb_rcvintpipe(cp->usbdev, AU_IRQENDP), cp->intbufp, + irqsize, auerswald_int_complete, cp, ep->bInterval); + /* start the urb */ + cp->inturbp->status = 0; /* needed! */ + ret = usb_submit_urb(cp->inturbp); + + intoend: + if (ret < 0) { + /* activation of interrupt endpoint has failed. Now clean up. */ + dbg("auerswald_int_open: activation of int endpoint failed"); + + /* deallocate memory */ + auerswald_int_free(cp); + } + return ret; +} + +/* This function is called to deactivate the interrupt + endpoint. This function returns 0 if successfull or an error code. + NOTE: no mutex please! +*/ +static int auerswald_int_release(struct auerswald *cp) +{ + int ret = 0; + dbg("auerswald_int_release"); + + /* stop the int endpoint */ + if (cp->inturbp) { + ret = usb_unlink_urb(cp->inturbp); + if (ret) + dbg("nonzero int unlink result received: %d", ret); + } + + /* deallocate memory */ + auerswald_int_free(cp); + + return ret; +} + +/* --------------------------------------------------------------------- */ +/* Helper functions */ + +/* Delete an auerswald driver context */ +void auerswald_delete(struct auerswald *cp) +{ + dbg("auerswald_delete"); + if (cp == NULL) + return; + + /* Wake up all processes waiting for a buffer */ + wake_up(&cp->bufferwait); + + /* Cleaning up */ + auerisdn_disconnect(cp); + auerswald_int_release(cp); + auerchain_free(&cp->controlchain); + auerbuf_free_buffers(&cp->bufctl); + + /* release the memory */ + kfree(cp); +} + + +/* add a new service to the device + scp->id must be set! + return: 0 if OK, else error code +*/ +int auerswald_addservice(struct auerswald *cp, struct auerscon *scp) +{ + int ret; + + /* is the device available? */ + if (!cp->usbdev) { + dbg("usbdev == NULL"); + return -EIO; /*no: can not add a service, sorry */ + } + + /* is the service available? */ + if (cp->services[scp->id]) { + dbg("service is busy"); + return -EBUSY; + } + + /* device is available, service is free */ + cp->services[scp->id] = scp; + + /* register service in device */ + ret = auerchain_control_msg(&cp->controlchain, /* pointer to control chain */ + cp->usbdev, /* pointer to device */ + usb_sndctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ + AUV_CHANNELCTL, /* USB message request value */ + AUT_WREQ, /* USB message request type value */ + 0x01, /* open */ /* USB message value */ + scp->id, /* USB message index value */ + NULL, /* pointer to the data to send */ + 0, /* length in bytes of the data to send */ + HZ * 2); /* time to wait for the message to complete before timing out */ + if (ret < 0) { + dbg("auerswald_addservice: auerchain_control_msg returned error code %d", ret); + /* undo above actions */ + cp->services[scp->id] = NULL; + return ret; + } + + dbg("auerswald_addservice: channel open OK"); + return 0; +} + + +/* remove a service from the the device + scp->id must be set! */ +void auerswald_removeservice(struct auerswald *cp, struct auerscon *scp) +{ + dbg("auerswald_removeservice called"); + + /* check if we have a service allocated */ + if (scp->id == AUH_UNASSIGNED) + return; + + /* If there is a device: close the channel */ + if (cp->usbdev && !cp->disconnecting) { + /* Close the service channel inside the device */ + int ret = auerchain_control_msg(&cp->controlchain, /* pointer to control chain */ + cp->usbdev, /* pointer to device */ + usb_sndctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ + AUV_CHANNELCTL, /* USB message request value */ + AUT_WREQ, /* USB message request type value */ + 0x00, /* close */ /* USB message value */ + scp->id, /* USB message index value */ + NULL, /* pointer to the data to send */ + 0, /* length in bytes of the data to send */ + HZ * 2); /* time to wait for the message to complete before timing out */ + if (ret < 0) { + dbg("auerswald_removeservice: auerchain_control_msg returned error code %d", ret); + } else { + dbg("auerswald_removeservice: channel close OK"); + } + } + + /* remove the service from the device */ + cp->services[scp->id] = NULL; + scp->id = AUH_UNASSIGNED; +} + + +/*----------------------------------------------------------------------*/ +/* File operation structure */ +static struct file_operations auerswald_fops = { + owner:THIS_MODULE, + llseek:auerchar_llseek, + read:auerchar_read, + write:auerchar_write, + ioctl:auerchar_ioctl, + open:auerchar_open, + release:auerchar_release, +}; + +/* --------------------------------------------------------------------- */ +/* Special USB driver functions */ + +/* Probe if this driver wants to serve an USB device + + This entry point is called whenever a new device is attached to the bus. + Then the device driver has to create a new instance of its internal data + structures for the new device. + + The dev argument specifies the device context, which contains pointers + to all USB descriptors. The interface argument specifies the interface + number. If a USB driver wants to bind itself to a particular device and + interface it has to return a pointer. This pointer normally references + the device driver's context structure. + + Probing normally is done by checking the vendor and product identifications + or the class and subclass definitions. If they match the interface number + is compared with the ones supported by the driver. When probing is done + class based it might be necessary to parse some more USB descriptors because + the device properties can differ in a wide range. +*/ +static void *auerswald_probe(struct usb_device *usbdev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct auerswald *cp = NULL; + DECLARE_WAIT_QUEUE_HEAD(wqh); + unsigned int dtindex; + unsigned int u = 0; + char *pbuf; + int ret; + + dbg("probe: vendor id 0x%x, device id 0x%x ifnum:%d", + usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, + ifnum); + + /* See if the device offered us matches that we can accept */ + if (usbdev->descriptor.idVendor != ID_AUERSWALD) + return NULL; + + /* we use only the first -and only- interface */ + if (ifnum != 0) + return NULL; + + /* prevent module unloading while sleeping */ + MOD_INC_USE_COUNT; + + /* allocate memory for our device and intialize it */ + cp = kmalloc(sizeof(struct auerswald), GFP_KERNEL); + if (cp == NULL) { + err("out of memory"); + goto pfail; + } + + /* Initialize device descriptor */ + memset(cp, 0, sizeof(struct auerswald)); + init_MUTEX(&cp->mutex); + cp->usbdev = usbdev; + auerchain_init(&cp->controlchain); + auerbuf_init(&cp->bufctl); + init_waitqueue_head(&cp->bufferwait); + auerisdn_init_dev(cp); + + /* find a free slot in the device table */ + down(&auerdev_table_mutex); + for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) { + if (auerdev_table[dtindex] == NULL) + break; + } + if (dtindex >= AUER_MAX_DEVICES) { + err("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES); + up(&auerdev_table_mutex); + goto pfail; + } + + /* Give the device a name */ + sprintf(cp->name, AU_PREFIX "%d", dtindex); + + /* Store the index */ + cp->dtindex = dtindex; + auerdev_table[dtindex] = cp; + up(&auerdev_table_mutex); + + /* initialize the devfs node for this device and register it */ + cp->devfs = devfs_register(usb_devfs_handle, cp->name, + DEVFS_FL_DEFAULT, USB_MAJOR, + AUER_MINOR_BASE + dtindex, + S_IFCHR | S_IRUGO | S_IWUGO, + &auerswald_fops, NULL); + + /* Get the usb version of the device */ + cp->version = cp->usbdev->descriptor.bcdDevice; + dbg("Version is %X", cp->version); + + /* allow some time to settle the device */ + sleep_on_timeout(&wqh, HZ / 3); + + /* Try to get a suitable textual description of the device */ + /* Device name: */ + ret = + usb_string(cp->usbdev, AUSI_DEVICE, cp->dev_desc, + AUSI_DLEN - 1); + if (ret >= 0) { + u += ret; + /* Append Serial Number */ + memcpy(&cp->dev_desc[u], ",Ser# ", 6); + u += 6; + ret = + usb_string(cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u], + AUSI_DLEN - u - 1); + if (ret >= 0) { + u += ret; + /* Append subscriber number */ + memcpy(&cp->dev_desc[u], ", ", 2); + u += 2; + ret = + usb_string(cp->usbdev, AUSI_MSN, + &cp->dev_desc[u], + AUSI_DLEN - u - 1); + if (ret >= 0) { + u += ret; + } + } + } + cp->dev_desc[u] = '\0'; + info("device is a %s", cp->dev_desc); + + /* get the maximum allowed control transfer length */ + pbuf = (char *) kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */ + if (!pbuf) { + err("out of memory"); + goto pfail; + } + ret = usb_control_msg(cp->usbdev, /* pointer to device */ + usb_rcvctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ + AUV_GETINFO, /* USB message request value */ + AUT_RREQ, /* USB message request type value */ + 0, /* USB message value */ + AUDI_MBCTRANS, /* USB message index value */ + pbuf, /* pointer to the receive buffer */ + 2, /* length of the buffer */ + HZ * 2); /* time to wait for the message to complete before timing out */ + if (ret == 2) { + cp->maxControlLength = le16_to_cpup(pbuf); + kfree(pbuf); + dbg("setup: max. allowed control transfersize is %d bytes", + cp->maxControlLength); + } else { + kfree(pbuf); + err("setup: getting max. allowed control transfer length failed with error %d", ret); + goto pfail; + } + /* allocate a chain for the control messages */ + if (auerchain_setup(&cp->controlchain, AUCH_ELEMENTS)) { + err("out of memory"); + goto pfail; + } + + /* allocate buffers for control messages */ + if (auerbuf_setup + (&cp->bufctl, AU_RBUFFERS * 2, + cp->maxControlLength + AUH_SIZE)) { + err("out of memory"); + goto pfail; + } + + /* start the interrupt endpoint */ + if (auerswald_int_open(cp)) { + err("int endpoint failed"); + goto pfail; + } + + /* Try to connect to hisax interface */ + if (auerisdn_probe(cp)) { + err("hisax connect failed"); + goto pfail; + } + + /* all OK */ + return cp; + + /* Error exit: clean up the memory */ + pfail:auerswald_delete(cp); + MOD_DEC_USE_COUNT; + return NULL; +} + + +/* Disconnect driver from a served device + + This function is called whenever a device which was served by this driver + is disconnected. + + The argument dev specifies the device context and the driver_context + returns a pointer to the previously registered driver_context of the + probe function. After returning from the disconnect function the USB + framework completly deallocates all data structures associated with + this device. So especially the usb_device structure must not be used + any longer by the usb driver. +*/ +static void auerswald_disconnect(struct usb_device *usbdev, + void *driver_context) +{ + struct auerswald *cp = (struct auerswald *) driver_context; + unsigned int u; + + /* all parallel tasks can react on disconnect ASAP */ + cp->disconnecting = 1; + down(&cp->mutex); + info("device /dev/usb/%s now disconnecting", cp->name); + + /* remove from device table */ + /* Nobody can open() this device any more */ + down(&auerdev_table_mutex); + auerdev_table[cp->dtindex] = NULL; + up(&auerdev_table_mutex); + + /* remove our devfs node */ + /* Nobody can see this device any more */ + devfs_unregister(cp->devfs); + + /* stop the ISDN connection */ + auerisdn_disconnect(cp); + + /* Stop the interrupt endpoint 0 */ + auerswald_int_release(cp); + + /* remove the control chain allocated in auerswald_probe + This has the benefit of + a) all pending (a)synchronous urbs are unlinked + b) all buffers dealing with urbs are reclaimed + */ + auerchain_free(&cp->controlchain); + + if (cp->open_count == 0) { + struct auerscon *scp; + /* nobody is using this device. So we can clean up now */ + up(&cp->mutex); /* up() is possible here because no other task + can open the device (see above). I don't want + to kfree() a locked mutex. */ + /* disconnect the D channel */ + scp = cp->services[AUH_DCHANNEL]; + if (scp) + scp->disconnect(scp); + auerswald_delete(cp); + } else { + /* device is used. Remove the pointer to the + usb device (it's not valid any more). The last + release() will do the clean up */ + cp->usbdev = NULL; + up(&cp->mutex); + /* Terminate waiting writers */ + wake_up(&cp->bufferwait); + /* Inform all waiting readers */ + for (u = 0; u < AUH_TYPESIZE; u++) { + struct auerscon *scp = cp->services[u]; + if (scp) + scp->disconnect(scp); + } + } + + /* The device releases this module */ + MOD_DEC_USE_COUNT; +} + +/* Descriptor for the devices which are served by this driver. + NOTE: this struct is parsed by the usbmanager install scripts. + Don't change without caution! +*/ +static struct usb_device_id auerswald_ids[] = { + {USB_DEVICE(ID_AUERSWALD, 0x00C0)}, /* COMpact 2104 USB/DSL */ + {USB_DEVICE(ID_AUERSWALD, 0x00DB)}, /* COMpact 4410/2206 USB */ + {USB_DEVICE(ID_AUERSWALD, 0x00DC)}, /* comming soon... */ + {USB_DEVICE(ID_AUERSWALD, 0x00F1)}, /* Comfort 2000 System Telephone */ + {USB_DEVICE(ID_AUERSWALD, 0x00F2)}, /* Comfort 1200 System Telephone */ + {} /* Terminating entry */ +}; + +/* Standard module device table */ +MODULE_DEVICE_TABLE(usb, auerswald_ids); + +/* Standard usb driver struct */ +static struct usb_driver auerswald_driver = { + name:"auerswald", + probe:auerswald_probe, + disconnect:auerswald_disconnect, + fops:&auerswald_fops, + minor:AUER_MINOR_BASE, + id_table:auerswald_ids, +}; + + +/* --------------------------------------------------------------------- */ +/* Module loading/unloading */ + +/* Driver initialisation. Called after module loading. + NOTE: there is no concurrency at _init +*/ +static int __init auerswald_init(void) +{ + int result; + dbg("init"); + + /* initialize the device table */ + memset(&auerdev_table, 0, sizeof(auerdev_table)); + init_MUTEX(&auerdev_table_mutex); + auerisdn_init(); + + /* register driver at the USB subsystem */ + /* NOTE: usb_register() may call probe()! */ + result = usb_register(&auerswald_driver); + if (result < 0) { + err("driver could not be registered"); + return -1; + } + return 0; +} + +/* Driver deinit. Called before module removal. + NOTE: there is no concurrency at _cleanup +*/ +static void __exit auerswald_cleanup(void) +{ + dbg("cleanup"); + auerisdn_cleanup(); + usb_deregister(&auerswald_driver); +} + +/* --------------------------------------------------------------------- */ +/* Linux device driver module description */ + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +module_init(auerswald_init); +module_exit(auerswald_cleanup); + +/* --------------------------------------------------------------------- */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auermain.h linux.21pre4-ac6/drivers/usb/auermain.h --- linux.21pre4/drivers/usb/auermain.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auermain.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,172 @@ +/*****************************************************************************/ +/* + * auermain.h -- Auerswald PBX/System Telephone usb driver. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +#ifndef AUERMAIN_H +#define AUERMAIN_H + +#include +#include +#include "auerchain.h" +#include "auerbuf.h" +#include "auerserv.h" +#include "auerisdn.h" + +/*-------------------------------------------------------------------*/ +/* Private declarations for Auerswald USB driver */ + +/* Auerswald Vendor ID */ +#define ID_AUERSWALD 0x09BF + +#ifndef AUER_MINOR_BASE /* allow external override */ +#define AUER_MINOR_BASE 112 /* auerswald driver minor number */ +#endif + +/* we can have up to this number of device plugged in at once */ +#define AUER_MAX_DEVICES 16 + +/* prefix for the device descriptors in /dev/usb */ +#define AU_PREFIX "auer" + +/* Number of read buffers for each device */ +#define AU_RBUFFERS 10 + +/* Number of chain elements for each control chain */ +#define AUCH_ELEMENTS 20 + +/* Number of retries in communication */ +#define AU_RETRIES 10 + +/*-------------------------------------------------------------------*/ +/* vendor specific protocol */ +/* Header Byte */ +#define AUH_INDIRMASK 0x80 /* mask for direct/indirect bit */ +#define AUH_DIRECT 0x00 /* data is for USB device */ +#define AUH_INDIRECT 0x80 /* USB device is relay */ + +#define AUH_SPLITMASK 0x40 /* mask for split bit */ +#define AUH_UNSPLIT 0x00 /* data block is full-size */ +#define AUH_SPLIT 0x40 /* data block is part of a larger one, + split-byte follows */ +#define AUH_SYNC 0x40 /* Sync to start of HDLC frame for B1,B2 */ + +#define AUH_TYPEMASK 0x3F /* mask for type of data transfer */ +#define AUH_TYPESIZE 0x40 /* different types */ +#define AUH_DCHANNEL 0x00 /* D channel data */ +#define AUH_B1CHANNEL 0x01 /* B1 channel transparent */ +#define AUH_B2CHANNEL 0x02 /* B2 channel transparent */ +/* 0x03..0x0F reserved for driver internal use */ +#define AUH_COMMAND 0x10 /* Command channel */ +#define AUH_BPROT 0x11 /* Configuration block protocol */ +#define AUH_DPROTANA 0x12 /* D channel protocol analyzer */ +#define AUH_TAPI 0x13 /* telephone api data (ATD) */ +/* 0x14..0x3F reserved for other protocols */ +#define AUH_UNASSIGNED 0xFF /* if char device has no assigned service */ +#define AUH_FIRSTUSERCH 0x11 /* first channel which is available for driver users */ + +#define AUH_SIZE 1 /* Size of Header Byte */ + +/* Split Byte. Only present if split bit in header byte set.*/ +#define AUS_STARTMASK 0x80 /* mask for first block of splitted frame */ +#define AUS_FIRST 0x80 /* first block */ +#define AUS_FOLLOW 0x00 /* following block */ + +#define AUS_ENDMASK 0x40 /* mask for last block of splitted frame */ +#define AUS_END 0x40 /* last block */ +#define AUS_NOEND 0x00 /* not the last block */ + +#define AUS_LENMASK 0x3F /* mask for block length information */ + +/* Request types */ +#define AUT_RREQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Read Request */ +#define AUT_WREQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Write Request */ + +/* Vendor Requests */ +#define AUV_GETINFO 0x00 /* GetDeviceInfo */ +#define AUV_WBLOCK 0x01 /* Write Block */ +#define AUV_RBLOCK 0x02 /* Read Block */ +#define AUV_CHANNELCTL 0x03 /* Channel Control */ +#define AUV_DUMMY 0x04 /* Dummy Out for retry */ + +/* Device Info Types */ +#define AUDI_NUMBCH 0x0000 /* Number of supported B channels */ +#define AUDI_OUTFSIZE 0x0001 /* Size of OUT B channel fifos */ +#define AUDI_MBCTRANS 0x0002 /* max. Blocklength of control transfer */ + +/* Interrupt endpoint definitions */ +#define AU_IRQENDP 1 /* Endpoint number */ +#define AU_IRQCMDID 16 /* Command-block ID */ +#define AU_BLOCKRDY 0 /* Command: Block data ready on ctl endpoint */ +#define AU_IRQMINSIZE 5 /* Nr. of bytes decoded in this driver */ + +/* B channel Interrupt endpoint definitions */ +#define AU_IRQENDPBI 2 /* Input Endpoint number */ +#define AU_IRQENDPBO 3 /* Output Endpoint number for 4410, 2206 */ +#define AU_IRQENDPBO_2 2 /* Output Endpoint number for 2104 */ + +/* Device String Descriptors */ +#define AUSI_VENDOR 1 /* "Auerswald GmbH & Co. KG" */ +#define AUSI_DEVICE 2 /* Name of the Device */ +#define AUSI_SERIALNR 3 /* Serial Number */ +#define AUSI_MSN 4 /* "MSN ..." (first) Multiple Subscriber Number */ + +#define AUSI_DLEN 100 /* Max. Length of Device Description */ + +#define AUV_RETRY 0x101 /* First Firmware version which can do control retries */ + +/* ...................................................................*/ +/* USB device context */ +struct auerswald { + struct semaphore mutex; /* protection in user context */ + char name[16]; /* name of the /dev/usb entry */ + unsigned int dtindex; /* index in the device table */ + devfs_handle_t devfs; /* devfs device node */ + struct usb_device *usbdev; /* USB device handle */ + int open_count; /* count the number of open character channels */ + char dev_desc[AUSI_DLEN]; /* for storing a textual description */ + unsigned int maxControlLength; /* max. Length of control paket (without header) */ + struct urb *inturbp; /* interrupt urb */ + char *intbufp; /* data buffer for interrupt urb */ + unsigned int irqsize; /* size of interrupt endpoint 1 */ + struct auerchain controlchain; /* for chaining of control messages */ + struct auerbufctl bufctl; /* Buffer control for control transfers */ + struct auerscon *services[AUH_TYPESIZE];/* context pointers for each service */ + unsigned int version; /* Version of the device */ + wait_queue_head_t bufferwait; /* wait for a control buffer */ + volatile unsigned int disconnecting;/* 1: removal in progress */ + struct auerisdn isdn; /* ISDN-Related parameters */ +}; + +/* array of pointers to our devices that are currently connected */ +extern struct auerswald *auerdev_table[AUER_MAX_DEVICES]; + +/* lock to protect the auerdev_table structure */ +extern struct semaphore auerdev_table_mutex; + +void auerswald_removeservice(struct auerswald *cp, struct auerscon *scp); + +int auerswald_addservice(struct auerswald *cp, struct auerscon *scp); + +void auerchar_ctrlwrite_complete(struct urb *urb); + +void auerswald_delete(struct auerswald *cp); + +#endif /* AUERMAIN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerserv.h linux.21pre4-ac6/drivers/usb/auerserv.h --- linux.21pre4/drivers/usb/auerserv.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/usb/auerserv.h 2003-02-21 16:32:35.000000000 +0000 @@ -0,0 +1,47 @@ +/*****************************************************************************/ +/* + * auerserv.h -- Auerswald PBX/System Telephone service request structure. + * + * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*****************************************************************************/ + +/* The auerswald ISDN devices have a logical channel concept. Many channels are + * realized via one control endpoint or INT endpoint. At the receiver side, these + * messages must be dispatched. Some data may be for an application which is + * connected through the char interface, other data may be D-channel information + * routed to ISDN4LINUX. The auerscon struct is used to dispatch the data. + */ + +#ifndef AUERSERV_H +#define AUERSERV_H + +#include "auerbuf.h" + +/* service context */ +struct auerscon; +typedef void (*auer_dispatch_t) (struct auerscon *, struct auerbuf *); +typedef void (*auer_disconn_t) (struct auerscon *); + +struct auerscon { + unsigned int id; /* protocol service id AUH_xxxx */ + auer_dispatch_t dispatch; /* dispatch read buffer */ + auer_disconn_t disconnect; /* disconnect from device, wake up all readers */ +}; + + +#endif /* AUERSERV_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/auerswald.c linux.21pre4-ac6/drivers/usb/auerswald.c --- linux.21pre4/drivers/usb/auerswald.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/auerswald.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,2196 +0,0 @@ -/*****************************************************************************/ -/* - * auerswald.c -- Auerswald PBX/System Telephone usb driver. - * - * Copyright (C) 2001 Wolfgang Mües (wolfgang@iksw-muees.de) - * - * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl) - * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - /*****************************************************************************/ - -/* Standard Linux module include files */ -#include -#include -#include -#include -#include -#undef DEBUG /* include debug macros until it's done */ -#include - -/*-------------------------------------------------------------------*/ -/* Debug support */ -#ifdef DEBUG -#define dump( adr, len) \ -do { \ - unsigned int u; \ - printk (KERN_DEBUG); \ - for (u = 0; u < len; u++) \ - printk (" %02X", adr[u] & 0xFF); \ - printk ("\n"); \ -} while (0) -#else -#define dump( adr, len) -#endif - -/*-------------------------------------------------------------------*/ -/* Version Information */ -#define DRIVER_VERSION "0.9.11" -#define DRIVER_AUTHOR "Wolfgang Mües " -#define DRIVER_DESC "Auerswald PBX/System Telephone usb driver" - -/*-------------------------------------------------------------------*/ -/* Private declarations for Auerswald USB driver */ - -/* Auerswald Vendor ID */ -#define ID_AUERSWALD 0x09BF - -#ifndef AUER_MINOR_BASE /* allow external override */ -#define AUER_MINOR_BASE 112 /* auerswald driver minor number */ -#endif - -/* we can have up to this number of device plugged in at once */ -#define AUER_MAX_DEVICES 16 - -/* prefix for the device descriptors in /dev/usb */ -#define AU_PREFIX "auer" - -/* Number of read buffers for each device */ -#define AU_RBUFFERS 10 - -/* Number of chain elements for each control chain */ -#define AUCH_ELEMENTS 20 - -/* Number of retries in communication */ -#define AU_RETRIES 10 - -/*-------------------------------------------------------------------*/ -/* vendor specific protocol */ -/* Header Byte */ -#define AUH_INDIRMASK 0x80 /* mask for direct/indirect bit */ -#define AUH_DIRECT 0x00 /* data is for USB device */ -#define AUH_INDIRECT 0x80 /* USB device is relay */ - -#define AUH_SPLITMASK 0x40 /* mask for split bit */ -#define AUH_UNSPLIT 0x00 /* data block is full-size */ -#define AUH_SPLIT 0x40 /* data block is part of a larger one, - split-byte follows */ - -#define AUH_TYPEMASK 0x3F /* mask for type of data transfer */ -#define AUH_TYPESIZE 0x40 /* different types */ -#define AUH_DCHANNEL 0x00 /* D channel data */ -#define AUH_B1CHANNEL 0x01 /* B1 channel transparent */ -#define AUH_B2CHANNEL 0x02 /* B2 channel transparent */ -/* 0x03..0x0F reserved for driver internal use */ -#define AUH_COMMAND 0x10 /* Command channel */ -#define AUH_BPROT 0x11 /* Configuration block protocol */ -#define AUH_DPROTANA 0x12 /* D channel protocol analyzer */ -#define AUH_TAPI 0x13 /* telephone api data (ATD) */ -/* 0x14..0x3F reserved for other protocols */ -#define AUH_UNASSIGNED 0xFF /* if char device has no assigned service */ -#define AUH_FIRSTUSERCH 0x11 /* first channel which is available for driver users */ - -#define AUH_SIZE 1 /* Size of Header Byte */ - -/* Split Byte. Only present if split bit in header byte set.*/ -#define AUS_STARTMASK 0x80 /* mask for first block of splitted frame */ -#define AUS_FIRST 0x80 /* first block */ -#define AUS_FOLLOW 0x00 /* following block */ - -#define AUS_ENDMASK 0x40 /* mask for last block of splitted frame */ -#define AUS_END 0x40 /* last block */ -#define AUS_NOEND 0x00 /* not the last block */ - -#define AUS_LENMASK 0x3F /* mask for block length information */ - -/* Request types */ -#define AUT_RREQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Read Request */ -#define AUT_WREQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Write Request */ - -/* Vendor Requests */ -#define AUV_GETINFO 0x00 /* GetDeviceInfo */ -#define AUV_WBLOCK 0x01 /* Write Block */ -#define AUV_RBLOCK 0x02 /* Read Block */ -#define AUV_CHANNELCTL 0x03 /* Channel Control */ -#define AUV_DUMMY 0x04 /* Dummy Out for retry */ - -/* Device Info Types */ -#define AUDI_NUMBCH 0x0000 /* Number of supported B channels */ -#define AUDI_OUTFSIZE 0x0001 /* Size of OUT B channel fifos */ -#define AUDI_MBCTRANS 0x0002 /* max. Blocklength of control transfer */ - -/* Interrupt endpoint definitions */ -#define AU_IRQENDP 1 /* Endpoint number */ -#define AU_IRQCMDID 16 /* Command-block ID */ -#define AU_BLOCKRDY 0 /* Command: Block data ready on ctl endpoint */ -#define AU_IRQMINSIZE 5 /* Nr. of bytes decoded in this driver */ - -/* Device String Descriptors */ -#define AUSI_VENDOR 1 /* "Auerswald GmbH & Co. KG" */ -#define AUSI_DEVICE 2 /* Name of the Device */ -#define AUSI_SERIALNR 3 /* Serial Number */ -#define AUSI_MSN 4 /* "MSN ..." (first) Multiple Subscriber Number */ - -#define AUSI_DLEN 100 /* Max. Length of Device Description */ - -#define AUV_RETRY 0x101 /* First Firmware version which can do control retries */ - -/*-------------------------------------------------------------------*/ -/* External data structures / Interface */ -typedef struct -{ - char *buf; /* return buffer for string contents */ - unsigned int bsize; /* size of return buffer */ -} audevinfo_t,*paudevinfo_t; - -/* IO controls */ -#define IOCTL_AU_SLEN _IOR( 'U', 0xF0, int) /* return the max. string descriptor length */ -#define IOCTL_AU_DEVINFO _IOWR('U', 0xF1, audevinfo_t) /* get name of a specific device */ -#define IOCTL_AU_SERVREQ _IOW( 'U', 0xF2, int) /* request a service channel */ -#define IOCTL_AU_BUFLEN _IOR( 'U', 0xF3, int) /* return the max. buffer length for the device */ -#define IOCTL_AU_RXAVAIL _IOR( 'U', 0xF4, int) /* return != 0 if Receive Data available */ -#define IOCTL_AU_CONNECT _IOR( 'U', 0xF5, int) /* return != 0 if connected to a service channel */ -#define IOCTL_AU_TXREADY _IOR( 'U', 0xF6, int) /* return != 0 if Transmitt channel ready to send */ -/* 'U' 0xF7..0xFF reseved */ - -/*-------------------------------------------------------------------*/ -/* Internal data structures */ - -/* ..................................................................*/ -/* urb chain element */ -struct auerchain; /* forward for circular reference */ -typedef struct -{ - struct auerchain *chain; /* pointer to the chain to which this element belongs */ - struct urb * urbp; /* pointer to attached urb */ - void *context; /* saved URB context */ - usb_complete_t complete; /* saved URB completion function */ - struct list_head list; /* to include element into a list */ -} auerchainelement_t,*pauerchainelement_t; - -/* urb chain */ -typedef struct auerchain -{ - pauerchainelement_t active; /* element which is submitted to urb */ - spinlock_t lock; /* protection agains interrupts */ - struct list_head waiting_list; /* list of waiting elements */ - struct list_head free_list; /* list of available elements */ -} auerchain_t,*pauerchain_t; - -/* urb blocking completion helper struct */ -typedef struct -{ - wait_queue_head_t wqh; /* wait for completion */ - unsigned int done; /* completion flag */ -} auerchain_chs_t,*pauerchain_chs_t; - -/* ...................................................................*/ -/* buffer element */ -struct auerbufctl; /* forward */ -typedef struct -{ - char *bufp; /* reference to allocated data buffer */ - unsigned int len; /* number of characters in data buffer */ - unsigned int retries; /* for urb retries */ - struct usb_ctrlrequest *dr; /* for setup data in control messages */ - struct urb * urbp; /* USB urb */ - struct auerbufctl *list; /* pointer to list */ - struct list_head buff_list; /* reference to next buffer in list */ -} auerbuf_t,*pauerbuf_t; - -/* buffer list control block */ -typedef struct auerbufctl -{ - spinlock_t lock; /* protection in interrupt */ - struct list_head free_buff_list;/* free buffers */ - struct list_head rec_buff_list; /* buffers with receive data */ -} auerbufctl_t,*pauerbufctl_t; - -/* ...................................................................*/ -/* service context */ -struct auerscon; /* forward */ -typedef void (*auer_dispatch_t)(struct auerscon*, pauerbuf_t); -typedef void (*auer_disconn_t) (struct auerscon*); -typedef struct auerscon -{ - unsigned int id; /* protocol service id AUH_xxxx */ - auer_dispatch_t dispatch; /* dispatch read buffer */ - auer_disconn_t disconnect; /* disconnect from device, wake up all char readers */ -} auerscon_t,*pauerscon_t; - -/* ...................................................................*/ -/* USB device context */ -typedef struct -{ - struct semaphore mutex; /* protection in user context */ - char name[16]; /* name of the /dev/usb entry */ - unsigned int dtindex; /* index in the device table */ - devfs_handle_t devfs; /* devfs device node */ - struct usb_device * usbdev; /* USB device handle */ - int open_count; /* count the number of open character channels */ - char dev_desc[AUSI_DLEN];/* for storing a textual description */ - unsigned int maxControlLength; /* max. Length of control paket (without header) */ - struct urb * inturbp; /* interrupt urb */ - char * intbufp; /* data buffer for interrupt urb */ - unsigned int irqsize; /* size of interrupt endpoint 1 */ - struct auerchain controlchain; /* for chaining of control messages */ - auerbufctl_t bufctl; /* Buffer control for control transfers */ - pauerscon_t services[AUH_TYPESIZE];/* context pointers for each service */ - unsigned int version; /* Version of the device */ - wait_queue_head_t bufferwait; /* wait for a control buffer */ -} auerswald_t,*pauerswald_t; - -/* the global usb devfs handle */ -extern devfs_handle_t usb_devfs_handle; - -/* array of pointers to our devices that are currently connected */ -static pauerswald_t dev_table[AUER_MAX_DEVICES]; - -/* lock to protect the dev_table structure */ -static struct semaphore dev_table_mutex; - -/* ................................................................... */ -/* character device context */ -typedef struct -{ - struct semaphore mutex; /* protection in user context */ - pauerswald_t auerdev; /* context pointer of assigned device */ - auerbufctl_t bufctl; /* controls the buffer chain */ - auerscon_t scontext; /* service context */ - wait_queue_head_t readwait; /* for synchronous reading */ - struct semaphore readmutex; /* protection against multiple reads */ - pauerbuf_t readbuf; /* buffer held for partial reading */ - unsigned int readoffset; /* current offset in readbuf */ - unsigned int removed; /* is != 0 if device is removed */ -} auerchar_t,*pauerchar_t; - - -/*-------------------------------------------------------------------*/ -/* Forwards */ -static void auerswald_ctrlread_complete (struct urb * urb); -static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp); - - -/*-------------------------------------------------------------------*/ -/* USB chain helper functions */ -/* -------------------------- */ - -/* completion function for chained urbs */ -static void auerchain_complete (struct urb * urb) -{ - unsigned long flags; - int result; - - /* get pointer to element and to chain */ - pauerchainelement_t acep = (pauerchainelement_t) urb->context; - pauerchain_t acp = acep->chain; - - /* restore original entries in urb */ - urb->context = acep->context; - urb->complete = acep->complete; - - dbg ("auerchain_complete called"); - - /* call original completion function - NOTE: this function may lead to more urbs submitted into the chain. - (no chain lock at calling complete()!) - acp->active != NULL is protecting us against recursion.*/ - urb->complete (urb); - - /* detach element from chain data structure */ - spin_lock_irqsave (&acp->lock, flags); - if (acp->active != acep) /* paranoia debug check */ - dbg ("auerchain_complete: completion on non-active element called!"); - else - acp->active = NULL; - - /* add the used chain element to the list of free elements */ - list_add_tail (&acep->list, &acp->free_list); - acep = NULL; - - /* is there a new element waiting in the chain? */ - if (!acp->active && !list_empty (&acp->waiting_list)) { - /* yes: get the entry */ - struct list_head *tmp = acp->waiting_list.next; - list_del (tmp); - acep = list_entry (tmp, auerchainelement_t, list); - acp->active = acep; - } - spin_unlock_irqrestore (&acp->lock, flags); - - /* submit the new urb */ - if (acep) { - urb = acep->urbp; - dbg ("auerchain_complete: submitting next urb from chain"); - urb->status = 0; /* needed! */ - result = usb_submit_urb( urb); - - /* check for submit errors */ - if (result) { - urb->status = result; - dbg("auerchain_complete: usb_submit_urb with error code %d", result); - /* and do error handling via *this* completion function (recursive) */ - auerchain_complete( urb); - } - } else { - /* simple return without submitting a new urb. - The empty chain is detected with acp->active == NULL. */ - }; -} - - -/* submit function for chained urbs - this function may be called from completion context or from user space! - early = 1 -> submit in front of chain -*/ -static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int early) -{ - int result; - unsigned long flags; - pauerchainelement_t acep = NULL; - - dbg ("auerchain_submit_urb called"); - - /* try to get a chain element */ - spin_lock_irqsave (&acp->lock, flags); - if (!list_empty (&acp->free_list)) { - /* yes: get the entry */ - struct list_head *tmp = acp->free_list.next; - list_del (tmp); - acep = list_entry (tmp, auerchainelement_t, list); - } - spin_unlock_irqrestore (&acp->lock, flags); - - /* if no chain element available: return with error */ - if (!acep) { - return -ENOMEM; - } - - /* fill in the new chain element values */ - acep->chain = acp; - acep->context = urb->context; - acep->complete = urb->complete; - acep->urbp = urb; - INIT_LIST_HEAD (&acep->list); - - /* modify urb */ - urb->context = acep; - urb->complete = auerchain_complete; - urb->status = -EINPROGRESS; /* usb_submit_urb does this, too */ - - /* add element to chain - or start it immediately */ - spin_lock_irqsave (&acp->lock, flags); - if (acp->active) { - /* there is traffic in the chain, simple add element to chain */ - if (early) { - dbg ("adding new urb to head of chain"); - list_add (&acep->list, &acp->waiting_list); - } else { - dbg ("adding new urb to end of chain"); - list_add_tail (&acep->list, &acp->waiting_list); - } - acep = NULL; - } else { - /* the chain is empty. Prepare restart */ - acp->active = acep; - } - /* Spin has to be removed before usb_submit_urb! */ - spin_unlock_irqrestore (&acp->lock, flags); - - /* Submit urb if immediate restart */ - if (acep) { - dbg("submitting urb immediate"); - urb->status = 0; /* needed! */ - result = usb_submit_urb( urb); - /* check for submit errors */ - if (result) { - urb->status = result; - dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result); - /* and do error handling via completion function */ - auerchain_complete( urb); - } - } - - return 0; -} - -/* submit function for chained urbs - this function may be called from completion context or from user space! -*/ -static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb) -{ - return auerchain_submit_urb_list (acp, urb, 0); -} - -/* cancel an urb which is submitted to the chain - the result is 0 if the urb is cancelled, or -EINPROGRESS if - USB_ASYNC_UNLINK is set and the function is successfully started. -*/ -static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb) -{ - unsigned long flags; - struct urb * urbp; - pauerchainelement_t acep; - struct list_head *tmp; - - dbg ("auerchain_unlink_urb called"); - - /* search the chain of waiting elements */ - spin_lock_irqsave (&acp->lock, flags); - list_for_each (tmp, &acp->waiting_list) { - acep = list_entry (tmp, auerchainelement_t, list); - if (acep->urbp == urb) { - list_del (tmp); - urb->context = acep->context; - urb->complete = acep->complete; - list_add_tail (&acep->list, &acp->free_list); - spin_unlock_irqrestore (&acp->lock, flags); - dbg ("unlink waiting urb"); - urb->status = -ENOENT; - urb->complete (urb); - return 0; - } - } - /* not found. */ - spin_unlock_irqrestore (&acp->lock, flags); - - /* get the active urb */ - acep = acp->active; - if (acep) { - urbp = acep->urbp; - - /* check if we have to cancel the active urb */ - if (urbp == urb) { - /* note that there is a race condition between the check above - and the unlink() call because of no lock. This race is harmless, - because the usb module will detect the unlink() after completion. - We can't use the acp->lock here because the completion function - wants to grab it. - */ - dbg ("unlink active urb"); - return usb_unlink_urb (urbp); - } - } - - /* not found anyway - ... is some kind of success - */ - dbg ("urb to unlink not found in chain"); - return 0; -} - -/* cancel all urbs which are in the chain. - this function must not be called from interrupt or completion handler. -*/ -static void auerchain_unlink_all (pauerchain_t acp) -{ - unsigned long flags; - struct urb * urbp; - pauerchainelement_t acep; - - dbg ("auerchain_unlink_all called"); - - /* clear the chain of waiting elements */ - spin_lock_irqsave (&acp->lock, flags); - while (!list_empty (&acp->waiting_list)) { - /* get the next entry */ - struct list_head *tmp = acp->waiting_list.next; - list_del (tmp); - acep = list_entry (tmp, auerchainelement_t, list); - urbp = acep->urbp; - urbp->context = acep->context; - urbp->complete = acep->complete; - list_add_tail (&acep->list, &acp->free_list); - spin_unlock_irqrestore (&acp->lock, flags); - dbg ("unlink waiting urb"); - urbp->status = -ENOENT; - urbp->complete (urbp); - spin_lock_irqsave (&acp->lock, flags); - } - spin_unlock_irqrestore (&acp->lock, flags); - - /* clear the active urb */ - acep = acp->active; - if (acep) { - urbp = acep->urbp; - urbp->transfer_flags &= ~USB_ASYNC_UNLINK; - dbg ("unlink active urb"); - usb_unlink_urb (urbp); - } -} - - -/* free the chain. - this function must not be called from interrupt or completion handler. -*/ -static void auerchain_free (pauerchain_t acp) -{ - unsigned long flags; - pauerchainelement_t acep; - - dbg ("auerchain_free called"); - - /* first, cancel all pending urbs */ - auerchain_unlink_all (acp); - - /* free the elements */ - spin_lock_irqsave (&acp->lock, flags); - while (!list_empty (&acp->free_list)) { - /* get the next entry */ - struct list_head *tmp = acp->free_list.next; - list_del (tmp); - spin_unlock_irqrestore (&acp->lock, flags); - acep = list_entry (tmp, auerchainelement_t, list); - kfree (acep); - spin_lock_irqsave (&acp->lock, flags); - } - spin_unlock_irqrestore (&acp->lock, flags); -} - - -/* Init the chain control structure */ -static void auerchain_init (pauerchain_t acp) -{ - /* init the chain data structure */ - acp->active = NULL; - spin_lock_init (&acp->lock); - INIT_LIST_HEAD (&acp->waiting_list); - INIT_LIST_HEAD (&acp->free_list); -} - -/* setup a chain. - It is assumed that there is no concurrency while setting up the chain - requirement: auerchain_init() -*/ -static int auerchain_setup (pauerchain_t acp, unsigned int numElements) -{ - pauerchainelement_t acep; - - dbg ("auerchain_setup called with %d elements", numElements); - - /* fill the list of free elements */ - for (;numElements; numElements--) { - acep = (pauerchainelement_t) kmalloc (sizeof (auerchainelement_t), GFP_KERNEL); - if (!acep) goto ac_fail; - memset (acep, 0, sizeof (auerchainelement_t)); - INIT_LIST_HEAD (&acep->list); - list_add_tail (&acep->list, &acp->free_list); - } - return 0; - -ac_fail:/* free the elements */ - while (!list_empty (&acp->free_list)) { - /* get the next entry */ - struct list_head *tmp = acp->free_list.next; - list_del (tmp); - acep = list_entry (tmp, auerchainelement_t, list); - kfree (acep); - } - return -ENOMEM; -} - - -/* completion handler for synchronous chained URBs */ -static void auerchain_blocking_completion (struct urb *urb) -{ - pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context; - pchs->done = 1; - wmb(); - wake_up (&pchs->wqh); -} - - -/* Starts chained urb and waits for completion or timeout */ -static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int timeout, int* actual_length) -{ - DECLARE_WAITQUEUE (wait, current); - auerchain_chs_t chs; - int status; - - dbg ("auerchain_start_wait_urb called"); - init_waitqueue_head (&chs.wqh); - chs.done = 0; - - set_current_state (TASK_UNINTERRUPTIBLE); - add_wait_queue (&chs.wqh, &wait); - urb->context = &chs; - status = auerchain_submit_urb (acp, urb); - if (status) { - /* something went wrong */ - set_current_state (TASK_RUNNING); - remove_wait_queue (&chs.wqh, &wait); - return status; - } - - while (timeout && !chs.done) - { - timeout = schedule_timeout (timeout); - set_current_state(TASK_UNINTERRUPTIBLE); - rmb(); - } - - set_current_state (TASK_RUNNING); - remove_wait_queue (&chs.wqh, &wait); - - if (!timeout && !chs.done) { - if (urb->status != -EINPROGRESS) { /* No callback?!! */ - dbg ("auerchain_start_wait_urb: raced timeout"); - status = urb->status; - } else { - dbg ("auerchain_start_wait_urb: timeout"); - auerchain_unlink_urb (acp, urb); /* remove urb safely */ - status = -ETIMEDOUT; - } - } else - status = urb->status; - - if (actual_length) - *actual_length = urb->actual_length; - - return status; -} - - -/* auerchain_control_msg - Builds a control urb, sends it off and waits for completion - acp: pointer to the auerchain - dev: pointer to the usb device to send the message to - pipe: endpoint "pipe" to send the message to - request: USB message request value - requesttype: USB message request type value - value: USB message value - index: USB message index value - data: pointer to the data to send - size: length in bytes of the data to send - timeout: time to wait for the message to complete before timing out (if 0 the wait is forever) - - This function sends a simple control message to a specified endpoint - and waits for the message to complete, or timeout. - - If successful, it returns the transfered length, othwise a negative error number. - - Don't use this function from within an interrupt context, like a - bottom half handler. If you need a asyncronous message, or need to send - a message from within interrupt context, use auerchain_submit_urb() -*/ -static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, - __u16 value, __u16 index, void *data, __u16 size, int timeout) -{ - int ret; - struct usb_ctrlrequest *dr; - struct urb *urb; - int length; - - dbg ("auerchain_control_msg"); - dr = kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); - if (!dr) - return -ENOMEM; - urb = usb_alloc_urb (0); - if (!urb) { - kfree (dr); - return -ENOMEM; - } - - dr->bRequestType = requesttype; - dr->bRequest = request; - dr->wValue = cpu_to_le16 (value); - dr->wIndex = cpu_to_le16 (index); - dr->wLength = cpu_to_le16 (size); - - FILL_CONTROL_URB (urb, dev, pipe, (unsigned char*)dr, data, size, /* build urb */ - (usb_complete_t)auerchain_blocking_completion,0); - ret = auerchain_start_wait_urb (acp, urb, timeout, &length); - - usb_free_urb (urb); - kfree (dr); - - if (ret < 0) - return ret; - else - return length; -} - - -/*-------------------------------------------------------------------*/ -/* Buffer List helper functions */ - -/* free a single auerbuf */ -static void auerbuf_free (pauerbuf_t bp) -{ - if (bp->bufp) { - kfree (bp->bufp); - } - if (bp->dr) { - kfree (bp->dr); - } - if (bp->urbp) { - usb_free_urb (bp->urbp); - } - kfree (bp); -} - -/* free the buffers from an auerbuf list */ -static void auerbuf_free_list (struct list_head *q) -{ - struct list_head *tmp; - struct list_head *p; - pauerbuf_t bp; - - dbg ("auerbuf_free_list"); - for (p = q->next; p != q;) { - bp = list_entry (p, auerbuf_t, buff_list); - tmp = p->next; - list_del (p); - p = tmp; - auerbuf_free (bp); - } -} - -/* init the members of a list control block */ -static void auerbuf_init (pauerbufctl_t bcp) -{ - dbg ("auerbuf_init"); - spin_lock_init (&bcp->lock); - INIT_LIST_HEAD (&bcp->free_buff_list); - INIT_LIST_HEAD (&bcp->rec_buff_list); -} - -/* free all buffers from an auerbuf chain */ -static void auerbuf_free_buffers (pauerbufctl_t bcp) -{ - unsigned long flags; - dbg ("auerbuf_free_buffers"); - - spin_lock_irqsave (&bcp->lock, flags); - - auerbuf_free_list (&bcp->free_buff_list); - auerbuf_free_list (&bcp->rec_buff_list); - - spin_unlock_irqrestore (&bcp->lock, flags); -} - -/* setup a list of buffers */ -/* requirement: auerbuf_init() */ -static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned int bufsize) -{ - pauerbuf_t bep; - - dbg ("auerbuf_setup called with %d elements of %d bytes", numElements, bufsize); - - /* fill the list of free elements */ - for (;numElements; numElements--) { - bep = (pauerbuf_t) kmalloc (sizeof (auerbuf_t), GFP_KERNEL); - if (!bep) goto bl_fail; - memset (bep, 0, sizeof (auerbuf_t)); - bep->list = bcp; - INIT_LIST_HEAD (&bep->buff_list); - bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL); - if (!bep->bufp) goto bl_fail; - bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); - if (!bep->dr) goto bl_fail; - bep->urbp = usb_alloc_urb (0); - if (!bep->urbp) goto bl_fail; - list_add_tail (&bep->buff_list, &bcp->free_buff_list); - } - return 0; - -bl_fail:/* not enought memory. Free allocated elements */ - dbg ("auerbuf_setup: no more memory"); - auerbuf_free_buffers (bcp); - return -ENOMEM; -} - -/* insert a used buffer into the free list */ -static void auerbuf_releasebuf( pauerbuf_t bp) -{ - unsigned long flags; - pauerbufctl_t bcp = bp->list; - bp->retries = 0; - - dbg ("auerbuf_releasebuf called"); - spin_lock_irqsave (&bcp->lock, flags); - list_add_tail (&bp->buff_list, &bcp->free_buff_list); - spin_unlock_irqrestore (&bcp->lock, flags); -} - - -/*-------------------------------------------------------------------*/ -/* Completion handlers */ - -/* Values of urb->status or results of usb_submit_urb(): -0 Initial, OK --EINPROGRESS during submission until end --ENOENT if urb is unlinked --ETIMEDOUT Transfer timed out, NAK --ENOMEM Memory Overflow --ENODEV Specified USB-device or bus doesn't exist --ENXIO URB already queued --EINVAL a) Invalid transfer type specified (or not supported) - b) Invalid interrupt interval (0n256) --EAGAIN a) Specified ISO start frame too early - b) (using ISO-ASAP) Too much scheduled for the future wait some time and try again. --EFBIG Too much ISO frames requested (currently uhci900) --EPIPE Specified pipe-handle/Endpoint is already stalled --EMSGSIZE Endpoint message size is zero, do interface/alternate setting --EPROTO a) Bitstuff error - b) Unknown USB error --EILSEQ CRC mismatch --ENOSR Buffer error --EREMOTEIO Short packet detected --EXDEV ISO transfer only partially completed look at individual frame status for details --EINVAL ISO madness, if this happens: Log off and go home --EOVERFLOW babble -*/ - -/* check if a status code allows a retry */ -static int auerswald_status_retry (int status) -{ - switch (status) { - case 0: - case -ETIMEDOUT: - case -EOVERFLOW: - case -EAGAIN: - case -EPIPE: - case -EPROTO: - case -EILSEQ: - case -ENOSR: - case -EREMOTEIO: - return 1; /* do a retry */ - } - return 0; /* no retry possible */ -} - -/* Completion of asynchronous write block */ -static void auerchar_ctrlwrite_complete (struct urb * urb) -{ - pauerbuf_t bp = (pauerbuf_t) urb->context; - pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); - dbg ("auerchar_ctrlwrite_complete called"); - - /* reuse the buffer */ - auerbuf_releasebuf (bp); - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); -} - -/* Completion handler for dummy retry packet */ -static void auerswald_ctrlread_wretcomplete (struct urb * urb) -{ - pauerbuf_t bp = (pauerbuf_t) urb->context; - pauerswald_t cp; - int ret; - dbg ("auerswald_ctrlread_wretcomplete called"); - dbg ("complete with status: %d", urb->status); - cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); - - /* check if it is possible to advance */ - if (!auerswald_status_retry (urb->status) || !cp->usbdev) { - /* reuse the buffer */ - err ("control dummy: transmission error %d, can not retry", urb->status); - auerbuf_releasebuf (bp); - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); - return; - } - - /* fill the control message */ - bp->dr->bRequestType = AUT_RREQ; - bp->dr->bRequest = AUV_RBLOCK; - bp->dr->wLength = bp->dr->wValue; /* temporary stored */ - bp->dr->wValue = cpu_to_le16 (1); /* Retry Flag */ - /* bp->dr->index = channel id; remains */ - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0), - (unsigned char*)bp->dr, bp->bufp, le16_to_cpu (bp->dr->wLength), - (usb_complete_t)auerswald_ctrlread_complete,bp); - - /* submit the control msg as next paket */ - ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1); - if (ret) { - dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); - bp->urbp->status = ret; - auerswald_ctrlread_complete (bp->urbp); - } -} - -/* completion handler for receiving of control messages */ -static void auerswald_ctrlread_complete (struct urb * urb) -{ - unsigned int serviceid; - pauerswald_t cp; - pauerscon_t scp; - pauerbuf_t bp = (pauerbuf_t) urb->context; - int ret; - dbg ("auerswald_ctrlread_complete called"); - - cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); - - /* check if there is valid data in this urb */ - if (urb->status) { - dbg ("complete with non-zero status: %d", urb->status); - /* should we do a retry? */ - if (!auerswald_status_retry (urb->status) - || !cp->usbdev - || (cp->version < AUV_RETRY) - || (bp->retries >= AU_RETRIES)) { - /* reuse the buffer */ - err ("control read: transmission error %d, can not retry", urb->status); - auerbuf_releasebuf (bp); - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); - return; - } - bp->retries++; - dbg ("Retry count = %d", bp->retries); - /* send a long dummy control-write-message to allow device firmware to react */ - bp->dr->bRequestType = AUT_WREQ; - bp->dr->bRequest = AUV_DUMMY; - bp->dr->wValue = bp->dr->wLength; /* temporary storage */ - // bp->dr->index channel ID remains - bp->dr->wLength = cpu_to_le16 (32); /* >= 8 bytes */ - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0), - (unsigned char*)bp->dr, bp->bufp, 32, - (usb_complete_t)auerswald_ctrlread_wretcomplete,bp); - - /* submit the control msg as next paket */ - ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1); - if (ret) { - dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); - bp->urbp->status = ret; - auerswald_ctrlread_wretcomplete (bp->urbp); - } - return; - } - - /* get the actual bytecount (incl. headerbyte) */ - bp->len = urb->actual_length; - serviceid = bp->bufp[0] & AUH_TYPEMASK; - dbg ("Paket with serviceid %d and %d bytes received", serviceid, bp->len); - - /* dispatch the paket */ - scp = cp->services[serviceid]; - if (scp) { - /* look, Ma, a listener! */ - scp->dispatch (scp, bp); - } - - /* release the paket */ - auerbuf_releasebuf (bp); - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); -} - -/*-------------------------------------------------------------------*/ -/* Handling of Interrupt Endpoint */ -/* This interrupt Endpoint is used to inform the host about waiting - messages from the USB device. -*/ -/* int completion handler. */ -static void auerswald_int_complete (struct urb * urb) -{ - unsigned long flags; - unsigned int channelid; - unsigned int bytecount; - int ret; - pauerbuf_t bp = NULL; - pauerswald_t cp = (pauerswald_t) urb->context; - - dbg ("auerswald_int_complete called"); - - /* do not respond to an error condition */ - if (urb->status != 0) { - dbg ("nonzero URB status = %d", urb->status); - return; - } - - /* check if all needed data was received */ - if (urb->actual_length < AU_IRQMINSIZE) { - dbg ("invalid data length received: %d bytes", urb->actual_length); - return; - } - - /* check the command code */ - if (cp->intbufp[0] != AU_IRQCMDID) { - dbg ("invalid command received: %d", cp->intbufp[0]); - return; - } - - /* check the command type */ - if (cp->intbufp[1] != AU_BLOCKRDY) { - dbg ("invalid command type received: %d", cp->intbufp[1]); - return; - } - - /* now extract the information */ - channelid = cp->intbufp[2]; - bytecount = le16_to_cpup (&cp->intbufp[3]); - - /* check the channel id */ - if (channelid >= AUH_TYPESIZE) { - dbg ("invalid channel id received: %d", channelid); - return; - } - - /* check the byte count */ - if (bytecount > (cp->maxControlLength+AUH_SIZE)) { - dbg ("invalid byte count received: %d", bytecount); - return; - } - dbg ("Service Channel = %d", channelid); - dbg ("Byte Count = %d", bytecount); - - /* get a buffer for the next data paket */ - spin_lock_irqsave (&cp->bufctl.lock, flags); - if (!list_empty (&cp->bufctl.free_buff_list)) { - /* yes: get the entry */ - struct list_head *tmp = cp->bufctl.free_buff_list.next; - list_del (tmp); - bp = list_entry (tmp, auerbuf_t, buff_list); - } - spin_unlock_irqrestore (&cp->bufctl.lock, flags); - - /* if no buffer available: skip it */ - if (!bp) { - dbg ("auerswald_int_complete: no data buffer available"); - /* can we do something more? - This is a big problem: if this int packet is ignored, the - device will wait forever and not signal any more data. - The only real solution is: having enought buffers! - Or perhaps temporary disabling the int endpoint? - */ - return; - } - - /* fill the control message */ - bp->dr->bRequestType = AUT_RREQ; - bp->dr->bRequest = AUV_RBLOCK; - bp->dr->wValue = cpu_to_le16 (0); - bp->dr->wIndex = cpu_to_le16 (channelid | AUH_DIRECT | AUH_UNSPLIT); - bp->dr->wLength = cpu_to_le16 (bytecount); - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0), - (unsigned char*)bp->dr, bp->bufp, bytecount, - (usb_complete_t)auerswald_ctrlread_complete,bp); - - /* submit the control msg */ - ret = auerchain_submit_urb (&cp->controlchain, bp->urbp); - if (ret) { - dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret); - bp->urbp->status = ret; - auerswald_ctrlread_complete( bp->urbp); - /* here applies the same problem as above: device locking! */ - } -} - -/* int memory deallocation - NOTE: no mutex please! -*/ -static void auerswald_int_free (pauerswald_t cp) -{ - if (cp->inturbp) { - usb_free_urb (cp->inturbp); - cp->inturbp = NULL; - } - if (cp->intbufp) { - kfree (cp->intbufp); - cp->intbufp = NULL; - } -} - -/* This function is called to activate the interrupt - endpoint. This function returns 0 if successfull or an error code. - NOTE: no mutex please! -*/ -static int auerswald_int_open (pauerswald_t cp) -{ - int ret; - struct usb_endpoint_descriptor *ep; - int irqsize; - dbg ("auerswald_int_open"); - - ep = usb_epnum_to_ep_desc (cp->usbdev, USB_DIR_IN | AU_IRQENDP); - if (!ep) { - ret = -EFAULT; - goto intoend; - } - irqsize = ep->wMaxPacketSize; - cp->irqsize = irqsize; - - /* allocate the urb and data buffer */ - if (!cp->inturbp) { - cp->inturbp = usb_alloc_urb (0); - if (!cp->inturbp) { - ret = -ENOMEM; - goto intoend; - } - } - if (!cp->intbufp) { - cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL); - if (!cp->intbufp) { - ret = -ENOMEM; - goto intoend; - } - } - /* setup urb */ - FILL_INT_URB (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval); - /* start the urb */ - cp->inturbp->status = 0; /* needed! */ - ret = usb_submit_urb (cp->inturbp); - -intoend: - if (ret < 0) { - /* activation of interrupt endpoint has failed. Now clean up. */ - dbg ("auerswald_int_open: activation of int endpoint failed"); - - /* deallocate memory */ - auerswald_int_free (cp); - } - return ret; -} - -/* This function is called to deactivate the interrupt - endpoint. This function returns 0 if successfull or an error code. - NOTE: no mutex please! -*/ -static int auerswald_int_release (pauerswald_t cp) -{ - int ret = 0; - dbg ("auerswald_int_release"); - - /* stop the int endpoint */ - if (cp->inturbp) { - ret = usb_unlink_urb (cp->inturbp); - if (ret) - dbg ("nonzero int unlink result received: %d", ret); - } - - /* deallocate memory */ - auerswald_int_free (cp); - - return ret; -} - -/* --------------------------------------------------------------------- */ -/* Helper functions */ - -/* wake up waiting readers */ -static void auerchar_disconnect (pauerscon_t scp) -{ - pauerchar_t ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext))); - dbg ("auerchar_disconnect called"); - ccp->removed = 1; - wake_up (&ccp->readwait); -} - - -/* dispatch a read paket to a waiting character device */ -static void auerchar_ctrlread_dispatch (pauerscon_t scp, pauerbuf_t bp) -{ - unsigned long flags; - pauerchar_t ccp; - pauerbuf_t newbp = NULL; - char * charp; - dbg ("auerchar_ctrlread_dispatch called"); - ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext))); - - /* get a read buffer from character device context */ - spin_lock_irqsave (&ccp->bufctl.lock, flags); - if (!list_empty (&ccp->bufctl.free_buff_list)) { - /* yes: get the entry */ - struct list_head *tmp = ccp->bufctl.free_buff_list.next; - list_del (tmp); - newbp = list_entry (tmp, auerbuf_t, buff_list); - } - spin_unlock_irqrestore (&ccp->bufctl.lock, flags); - - if (!newbp) { - dbg ("No read buffer available, discard paket!"); - return; /* no buffer, no dispatch */ - } - - /* copy information to new buffer element - (all buffers have the same length) */ - charp = newbp->bufp; - newbp->bufp = bp->bufp; - bp->bufp = charp; - newbp->len = bp->len; - - /* insert new buffer in read list */ - spin_lock_irqsave (&ccp->bufctl.lock, flags); - list_add_tail (&newbp->buff_list, &ccp->bufctl.rec_buff_list); - spin_unlock_irqrestore (&ccp->bufctl.lock, flags); - dbg ("read buffer appended to rec_list"); - - /* wake up pending synchronous reads */ - wake_up (&ccp->readwait); -} - - -/* Delete an auerswald driver context */ -static void auerswald_delete( pauerswald_t cp) -{ - dbg( "auerswald_delete"); - if (cp == NULL) return; - - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); - - /* Cleaning up */ - auerswald_int_release (cp); - auerchain_free (&cp->controlchain); - auerbuf_free_buffers (&cp->bufctl); - - /* release the memory */ - kfree( cp); -} - - -/* Delete an auerswald character context */ -static void auerchar_delete( pauerchar_t ccp) -{ - dbg ("auerchar_delete"); - if (ccp == NULL) return; - - /* wake up pending synchronous reads */ - ccp->removed = 1; - wake_up (&ccp->readwait); - - /* remove the read buffer */ - if (ccp->readbuf) { - auerbuf_releasebuf (ccp->readbuf); - ccp->readbuf = NULL; - } - - /* remove the character buffers */ - auerbuf_free_buffers (&ccp->bufctl); - - /* release the memory */ - kfree( ccp); -} - - -/* add a new service to the device - scp->id must be set! - return: 0 if OK, else error code -*/ -static int auerswald_addservice (pauerswald_t cp, pauerscon_t scp) -{ - int ret; - - /* is the device available? */ - if (!cp->usbdev) { - dbg ("usbdev == NULL"); - return -EIO; /*no: can not add a service, sorry*/ - } - - /* is the service available? */ - if (cp->services[scp->id]) { - dbg ("service is busy"); - return -EBUSY; - } - - /* device is available, service is free */ - cp->services[scp->id] = scp; - - /* register service in device */ - ret = auerchain_control_msg( - &cp->controlchain, /* pointer to control chain */ - cp->usbdev, /* pointer to device */ - usb_sndctrlpipe (cp->usbdev, 0), /* pipe to control endpoint */ - AUV_CHANNELCTL, /* USB message request value */ - AUT_WREQ, /* USB message request type value */ - 0x01, /* open USB message value */ - scp->id, /* USB message index value */ - NULL, /* pointer to the data to send */ - 0, /* length in bytes of the data to send */ - HZ * 2); /* time to wait for the message to complete before timing out */ - if (ret < 0) { - dbg ("auerswald_addservice: auerchain_control_msg returned error code %d", ret); - /* undo above actions */ - cp->services[scp->id] = NULL; - return ret; - } - - dbg ("auerswald_addservice: channel open OK"); - return 0; -} - - -/* remove a service from the device - scp->id must be set! */ -static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp) -{ - dbg ("auerswald_removeservice called"); - - /* check if we have a service allocated */ - if (scp->id == AUH_UNASSIGNED) return; - - /* If there is a device: close the channel */ - if (cp->usbdev) { - /* Close the service channel inside the device */ - int ret = auerchain_control_msg( - &cp->controlchain, /* pointer to control chain */ - cp->usbdev, /* pointer to device */ - usb_sndctrlpipe (cp->usbdev, 0), /* pipe to control endpoint */ - AUV_CHANNELCTL, /* USB message request value */ - AUT_WREQ, /* USB message request type value */ - 0x00, // close /* USB message value */ - scp->id, /* USB message index value */ - NULL, /* pointer to the data to send */ - 0, /* length in bytes of the data to send */ - HZ * 2); /* time to wait for the message to complete before timing out */ - if (ret < 0) { - dbg ("auerswald_removeservice: auerchain_control_msg returned error code %d", ret); - } - else { - dbg ("auerswald_removeservice: channel close OK"); - } - } - - /* remove the service from the device */ - cp->services[scp->id] = NULL; - scp->id = AUH_UNASSIGNED; -} - - -/* --------------------------------------------------------------------- */ -/* Char device functions */ - -/* Open a new character device */ -static int auerchar_open (struct inode *inode, struct file *file) -{ - int dtindex = MINOR(inode->i_rdev) - AUER_MINOR_BASE; - pauerswald_t cp = NULL; - pauerchar_t ccp = NULL; - int ret; - - /* minor number in range? */ - if ((dtindex < 0) || (dtindex >= AUER_MAX_DEVICES)) { - return -ENODEV; - } - /* usb device available? */ - if (down_interruptible (&dev_table_mutex)) { - return -ERESTARTSYS; - } - cp = dev_table[dtindex]; - if (cp == NULL) { - up (&dev_table_mutex); - return -ENODEV; - } - if (down_interruptible (&cp->mutex)) { - up (&dev_table_mutex); - return -ERESTARTSYS; - } - up (&dev_table_mutex); - - /* we have access to the device. Now lets allocate memory */ - ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL); - if (ccp == NULL) { - err ("out of memory"); - ret = -ENOMEM; - goto ofail; - } - - /* Initialize device descriptor */ - memset( ccp, 0, sizeof(auerchar_t)); - init_MUTEX( &ccp->mutex); - init_MUTEX( &ccp->readmutex); - auerbuf_init (&ccp->bufctl); - ccp->scontext.id = AUH_UNASSIGNED; - ccp->scontext.dispatch = auerchar_ctrlread_dispatch; - ccp->scontext.disconnect = auerchar_disconnect; - init_waitqueue_head (&ccp->readwait); - - ret = auerbuf_setup (&ccp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE); - if (ret) { - goto ofail; - } - - cp->open_count++; - ccp->auerdev = cp; - dbg("open %s as /dev/usb/%s", cp->dev_desc, cp->name); - up (&cp->mutex); - - /* file IO stuff */ - file->f_pos = 0; - file->private_data = ccp; - return 0; - - /* Error exit */ -ofail: up (&cp->mutex); - auerchar_delete (ccp); - return ret; -} - - -/* IOCTL functions */ -static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - pauerchar_t ccp = (pauerchar_t) file->private_data; - int ret = 0; - audevinfo_t devinfo; - pauerswald_t cp = NULL; - unsigned int u; - dbg ("ioctl"); - - /* get the mutexes */ - if (down_interruptible (&ccp->mutex)) { - return -ERESTARTSYS; - } - cp = ccp->auerdev; - if (!cp) { - up (&ccp->mutex); - return -ENODEV; - } - if (down_interruptible (&cp->mutex)) { - up(&ccp->mutex); - return -ERESTARTSYS; - } - - /* Check for removal */ - if (!cp->usbdev) { - up(&cp->mutex); - up(&ccp->mutex); - return -ENODEV; - } - - switch (cmd) { - - /* return != 0 if Transmitt channel ready to send */ - case IOCTL_AU_TXREADY: - dbg ("IOCTL_AU_TXREADY"); - u = ccp->auerdev - && (ccp->scontext.id != AUH_UNASSIGNED) - && !list_empty (&cp->bufctl.free_buff_list); - ret = put_user (u, (unsigned int *) arg); - break; - - /* return != 0 if connected to a service channel */ - case IOCTL_AU_CONNECT: - dbg ("IOCTL_AU_CONNECT"); - u = (ccp->scontext.id != AUH_UNASSIGNED); - ret = put_user (u, (unsigned int *) arg); - break; - - /* return != 0 if Receive Data available */ - case IOCTL_AU_RXAVAIL: - dbg ("IOCTL_AU_RXAVAIL"); - if (ccp->scontext.id == AUH_UNASSIGNED) { - ret = -EIO; - break; - } - u = 0; /* no data */ - if (ccp->readbuf) { - int restlen = ccp->readbuf->len - ccp->readoffset; - if (restlen > 0) u = 1; - } - if (!u) { - if (!list_empty (&ccp->bufctl.rec_buff_list)) { - u = 1; - } - } - ret = put_user (u, (unsigned int *) arg); - break; - - /* return the max. buffer length for the device */ - case IOCTL_AU_BUFLEN: - dbg ("IOCTL_AU_BUFLEN"); - u = cp->maxControlLength; - ret = put_user (u, (unsigned int *) arg); - break; - - /* requesting a service channel */ - case IOCTL_AU_SERVREQ: - dbg ("IOCTL_AU_SERVREQ"); - /* requesting a service means: release the previous one first */ - auerswald_removeservice (cp, &ccp->scontext); - /* get the channel number */ - ret = get_user (u, (unsigned int *) arg); - if (ret) { - break; - } - if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) { - ret = -EIO; - break; - } - dbg ("auerchar service request parameters are ok"); - ccp->scontext.id = u; - - /* request the service now */ - ret = auerswald_addservice (cp, &ccp->scontext); - if (ret) { - /* no: revert service entry */ - ccp->scontext.id = AUH_UNASSIGNED; - } - break; - - /* get a string descriptor for the device */ - case IOCTL_AU_DEVINFO: - dbg ("IOCTL_AU_DEVINFO"); - if (copy_from_user (&devinfo, (void *) arg, sizeof (audevinfo_t))) { - ret = -EFAULT; - break; - } - u = strlen(cp->dev_desc)+1; - if (u > devinfo.bsize) { - u = devinfo.bsize; - } - ret = copy_to_user(devinfo.buf, cp->dev_desc, u)?-EFAULT:0; - break; - - /* get the max. string descriptor length */ - case IOCTL_AU_SLEN: - dbg ("IOCTL_AU_SLEN"); - u = AUSI_DLEN; - ret = put_user (u, (unsigned int *) arg); - break; - - default: - dbg ("IOCTL_AU_UNKNOWN"); - ret = -ENOIOCTLCMD; - break; - } - /* release the mutexes */ - up(&cp->mutex); - up(&ccp->mutex); - return ret; -} - - -/* Seek is not supported */ -static loff_t auerchar_llseek (struct file *file, loff_t offset, int origin) -{ - dbg ("auerchar_seek"); - return -ESPIPE; -} - - -/* Read data from the device */ -static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t * ppos) -{ - unsigned long flags; - pauerchar_t ccp = (pauerchar_t) file->private_data; - pauerbuf_t bp = NULL; - wait_queue_t wait; - - dbg ("auerchar_read"); - - /* Error checking */ - if (!ccp) - return -EIO; - if (*ppos) - return -ESPIPE; - if (count == 0) - return 0; - - /* get the mutex */ - if (down_interruptible (&ccp->mutex)) - return -ERESTARTSYS; - - /* Can we expect to read something? */ - if (ccp->scontext.id == AUH_UNASSIGNED) { - up (&ccp->mutex); - return -EIO; - } - - /* only one reader per device allowed */ - if (down_interruptible (&ccp->readmutex)) { - up (&ccp->mutex); - return -ERESTARTSYS; - } - - /* read data from readbuf, if available */ -doreadbuf: - bp = ccp->readbuf; - if (bp) { - /* read the maximum bytes */ - int restlen = bp->len - ccp->readoffset; - if (restlen < 0) - restlen = 0; - if (count > restlen) - count = restlen; - if (count) { - if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) { - dbg ("auerswald_read: copy_to_user failed"); - up (&ccp->readmutex); - up (&ccp->mutex); - return -EFAULT; - } - } - /* advance the read offset */ - ccp->readoffset += count; - restlen -= count; - // reuse the read buffer - if (restlen <= 0) { - auerbuf_releasebuf (bp); - ccp->readbuf = NULL; - } - /* return with number of bytes read */ - if (count) { - up (&ccp->readmutex); - up (&ccp->mutex); - return count; - } - } - - /* a read buffer is not available. Try to get the next data block. */ -doreadlist: - /* Preparing for sleep */ - init_waitqueue_entry (&wait, current); - set_current_state (TASK_INTERRUPTIBLE); - add_wait_queue (&ccp->readwait, &wait); - - bp = NULL; - spin_lock_irqsave (&ccp->bufctl.lock, flags); - if (!list_empty (&ccp->bufctl.rec_buff_list)) { - /* yes: get the entry */ - struct list_head *tmp = ccp->bufctl.rec_buff_list.next; - list_del (tmp); - bp = list_entry (tmp, auerbuf_t, buff_list); - } - spin_unlock_irqrestore (&ccp->bufctl.lock, flags); - - /* have we got data? */ - if (bp) { - ccp->readbuf = bp; - ccp->readoffset = AUH_SIZE; /* for headerbyte */ - set_current_state (TASK_RUNNING); - remove_wait_queue (&ccp->readwait, &wait); - goto doreadbuf; /* now we can read! */ - } - - /* no data available. Should we wait? */ - if (file->f_flags & O_NONBLOCK) { - dbg ("No read buffer available, returning -EAGAIN"); - set_current_state (TASK_RUNNING); - remove_wait_queue (&ccp->readwait, &wait); - up (&ccp->readmutex); - up (&ccp->mutex); - return -EAGAIN; /* nonblocking, no data available */ - } - - /* yes, we should wait! */ - up (&ccp->mutex); /* allow other operations while we wait */ - schedule(); - remove_wait_queue (&ccp->readwait, &wait); - if (signal_pending (current)) { - /* waked up by a signal */ - up (&ccp->readmutex); - return -ERESTARTSYS; - } - - /* Anything left to read? */ - if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) { - up (&ccp->readmutex); - return -EIO; - } - - if (down_interruptible (&ccp->mutex)) { - up (&ccp->readmutex); - return -ERESTARTSYS; - } - - /* try to read the incomming data again */ - goto doreadlist; -} - - -/* Write a data block into the right service channel of the device */ -static ssize_t auerchar_write (struct file *file, const char *buf, size_t len, loff_t *ppos) -{ - pauerchar_t ccp = (pauerchar_t) file->private_data; - pauerswald_t cp = NULL; - pauerbuf_t bp; - unsigned long flags; - int ret; - wait_queue_t wait; - - dbg ("auerchar_write %d bytes", len); - - /* Error checking */ - if (!ccp) - return -EIO; - if (*ppos) - return -ESPIPE; - if (len == 0) - return 0; - -write_again: - /* get the mutex */ - if (down_interruptible (&ccp->mutex)) - return -ERESTARTSYS; - - /* Can we expect to write something? */ - if (ccp->scontext.id == AUH_UNASSIGNED) { - up (&ccp->mutex); - return -EIO; - } - - cp = ccp->auerdev; - if (!cp) { - up (&ccp->mutex); - return -ERESTARTSYS; - } - if (down_interruptible (&cp->mutex)) { - up (&ccp->mutex); - return -ERESTARTSYS; - } - if (!cp->usbdev) { - up (&cp->mutex); - up (&ccp->mutex); - return -EIO; - } - /* Prepare for sleep */ - init_waitqueue_entry (&wait, current); - set_current_state (TASK_INTERRUPTIBLE); - add_wait_queue (&cp->bufferwait, &wait); - - /* Try to get a buffer from the device pool. - We can't use a buffer from ccp->bufctl because the write - command will last beond a release() */ - bp = NULL; - spin_lock_irqsave (&cp->bufctl.lock, flags); - if (!list_empty (&cp->bufctl.free_buff_list)) { - /* yes: get the entry */ - struct list_head *tmp = cp->bufctl.free_buff_list.next; - list_del (tmp); - bp = list_entry (tmp, auerbuf_t, buff_list); - } - spin_unlock_irqrestore (&cp->bufctl.lock, flags); - - /* are there any buffers left? */ - if (!bp) { - up (&cp->mutex); - up (&ccp->mutex); - - /* NONBLOCK: don't wait */ - if (file->f_flags & O_NONBLOCK) { - set_current_state (TASK_RUNNING); - remove_wait_queue (&cp->bufferwait, &wait); - return -EAGAIN; - } - - /* BLOCKING: wait */ - schedule(); - remove_wait_queue (&cp->bufferwait, &wait); - if (signal_pending (current)) { - /* waked up by a signal */ - return -ERESTARTSYS; - } - goto write_again; - } else { - set_current_state (TASK_RUNNING); - remove_wait_queue (&cp->bufferwait, &wait); - } - - /* protect against too big write requests */ - if (len > cp->maxControlLength) len = cp->maxControlLength; - - /* Fill the buffer */ - if (copy_from_user ( bp->bufp+AUH_SIZE, buf, len)) { - dbg ("copy_from_user failed"); - auerbuf_releasebuf (bp); - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); - up (&cp->mutex); - up (&ccp->mutex); - return -EIO; - } - - /* set the header byte */ - *(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT; - - /* Set the transfer Parameters */ - bp->len = len+AUH_SIZE; - bp->dr->bRequestType = AUT_WREQ; - bp->dr->bRequest = AUV_WBLOCK; - bp->dr->wValue = cpu_to_le16 (0); - bp->dr->wIndex = cpu_to_le16 (ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT); - bp->dr->wLength = cpu_to_le16 (len+AUH_SIZE); - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0), - (unsigned char*)bp->dr, bp->bufp, len+AUH_SIZE, - auerchar_ctrlwrite_complete, bp); - /* up we go */ - ret = auerchain_submit_urb (&cp->controlchain, bp->urbp); - up (&cp->mutex); - if (ret) { - dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret); - auerbuf_releasebuf (bp); - /* Wake up all processes waiting for a buffer */ - wake_up (&cp->bufferwait); - up (&ccp->mutex); - return -EIO; - } - else { - dbg ("auerchar_write: Write OK"); - up (&ccp->mutex); - return len; - } -} - - -/* Close a character device */ -static int auerchar_release (struct inode *inode, struct file *file) -{ - pauerchar_t ccp = (pauerchar_t) file->private_data; - pauerswald_t cp; - dbg("release"); - - /* get the mutexes */ - if (down_interruptible (&ccp->mutex)) { - return -ERESTARTSYS; - } - cp = ccp->auerdev; - if (cp) { - if (down_interruptible (&cp->mutex)) { - up (&ccp->mutex); - return -ERESTARTSYS; - } - /* remove an open service */ - auerswald_removeservice (cp, &ccp->scontext); - /* detach from device */ - if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) { - /* usb device waits for removal */ - up (&cp->mutex); - auerswald_delete (cp); - } else { - up (&cp->mutex); - } - cp = NULL; - ccp->auerdev = NULL; - } - up (&ccp->mutex); - auerchar_delete (ccp); - - return 0; -} - - -/*----------------------------------------------------------------------*/ -/* File operation structure */ -static struct file_operations auerswald_fops = -{ - owner: THIS_MODULE, - llseek: auerchar_llseek, - read: auerchar_read, - write: auerchar_write, - ioctl: auerchar_ioctl, - open: auerchar_open, - release: auerchar_release, -}; - - -/* --------------------------------------------------------------------- */ -/* Special USB driver functions */ - -/* Probe if this driver wants to serve an USB device - - This entry point is called whenever a new device is attached to the bus. - Then the device driver has to create a new instance of its internal data - structures for the new device. - - The dev argument specifies the device context, which contains pointers - to all USB descriptors. The interface argument specifies the interface - number. If a USB driver wants to bind itself to a particular device and - interface it has to return a pointer. This pointer normally references - the device driver's context structure. - - Probing normally is done by checking the vendor and product identifications - or the class and subclass definitions. If they match the interface number - is compared with the ones supported by the driver. When probing is done - class based it might be necessary to parse some more USB descriptors because - the device properties can differ in a wide range. -*/ -static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum, - const struct usb_device_id *id) -{ - pauerswald_t cp = NULL; - DECLARE_WAIT_QUEUE_HEAD (wqh); - unsigned int dtindex; - unsigned int u = 0; - char *pbuf; - int ret; - - dbg ("probe: vendor id 0x%x, device id 0x%x ifnum:%d", - usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum); - - /* See if the device offered us matches that we can accept */ - if (usbdev->descriptor.idVendor != ID_AUERSWALD) return NULL; - - /* we use only the first -and only- interface */ - if (ifnum != 0) return NULL; - - /* prevent module unloading while sleeping */ - MOD_INC_USE_COUNT; - - /* allocate memory for our device and intialize it */ - cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL); - if (cp == NULL) { - err ("out of memory"); - goto pfail; - } - - /* Initialize device descriptor */ - memset (cp, 0, sizeof(auerswald_t)); - init_MUTEX (&cp->mutex); - cp->usbdev = usbdev; - auerchain_init (&cp->controlchain); - auerbuf_init (&cp->bufctl); - init_waitqueue_head (&cp->bufferwait); - - /* find a free slot in the device table */ - down (&dev_table_mutex); - for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) { - if (dev_table[dtindex] == NULL) - break; - } - if ( dtindex >= AUER_MAX_DEVICES) { - err ("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES); - up (&dev_table_mutex); - goto pfail; - } - - /* Give the device a name */ - sprintf (cp->name, AU_PREFIX "%d", dtindex); - - /* Store the index */ - cp->dtindex = dtindex; - dev_table[dtindex] = cp; - up (&dev_table_mutex); - - /* initialize the devfs node for this device and register it */ - cp->devfs = devfs_register (usb_devfs_handle, cp->name, - DEVFS_FL_DEFAULT, USB_MAJOR, - AUER_MINOR_BASE + dtindex, - S_IFCHR | S_IRUGO | S_IWUGO, - &auerswald_fops, NULL); - - /* Get the usb version of the device */ - cp->version = cp->usbdev->descriptor.bcdDevice; - dbg ("Version is %X", cp->version); - - /* allow some time to settle the device */ - sleep_on_timeout (&wqh, HZ / 3 ); - - /* Try to get a suitable textual description of the device */ - /* Device name:*/ - ret = usb_string( cp->usbdev, AUSI_DEVICE, cp->dev_desc, AUSI_DLEN-1); - if (ret >= 0) { - u += ret; - /* Append Serial Number */ - memcpy(&cp->dev_desc[u], ",Ser# ", 6); - u += 6; - ret = usb_string( cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u], AUSI_DLEN-u-1); - if (ret >= 0) { - u += ret; - /* Append subscriber number */ - memcpy(&cp->dev_desc[u], ", ", 2); - u += 2; - ret = usb_string( cp->usbdev, AUSI_MSN, &cp->dev_desc[u], AUSI_DLEN-u-1); - if (ret >= 0) { - u += ret; - } - } - } - cp->dev_desc[u] = '\0'; - info("device is a %s", cp->dev_desc); - - /* get the maximum allowed control transfer length */ - pbuf = (char *) kmalloc (2, GFP_KERNEL); /* use an allocated buffer because of urb target */ - if (!pbuf) { - err( "out of memory"); - goto pfail; - } - ret = usb_control_msg(cp->usbdev, /* pointer to device */ - usb_rcvctrlpipe( cp->usbdev, 0 ), /* pipe to control endpoint */ - AUV_GETINFO, /* USB message request value */ - AUT_RREQ, /* USB message request type value */ - 0, /* USB message value */ - AUDI_MBCTRANS, /* USB message index value */ - pbuf, /* pointer to the receive buffer */ - 2, /* length of the buffer */ - HZ * 2); /* time to wait for the message to complete before timing out */ - if (ret == 2) { - cp->maxControlLength = le16_to_cpup(pbuf); - kfree(pbuf); - dbg("setup: max. allowed control transfersize is %d bytes", cp->maxControlLength); - } else { - kfree(pbuf); - err("setup: getting max. allowed control transfer length failed with error %d", ret); - goto pfail; - } - - /* allocate a chain for the control messages */ - if (auerchain_setup (&cp->controlchain, AUCH_ELEMENTS)) { - err ("out of memory"); - goto pfail; - } - - /* allocate buffers for control messages */ - if (auerbuf_setup (&cp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE)) { - err ("out of memory"); - goto pfail; - } - - /* start the interrupt endpoint */ - if (auerswald_int_open (cp)) { - err ("int endpoint failed"); - goto pfail; - } - - /* all OK */ - return cp; - - /* Error exit: clean up the memory */ -pfail: auerswald_delete (cp); - MOD_DEC_USE_COUNT; - return NULL; -} - - -/* Disconnect driver from a served device - - This function is called whenever a device which was served by this driver - is disconnected. - - The argument dev specifies the device context and the driver_context - returns a pointer to the previously registered driver_context of the - probe function. After returning from the disconnect function the USB - framework completly deallocates all data structures associated with - this device. So especially the usb_device structure must not be used - any longer by the usb driver. -*/ -static void auerswald_disconnect (struct usb_device *usbdev, void *driver_context) -{ - pauerswald_t cp = (pauerswald_t) driver_context; - unsigned int u; - - down (&cp->mutex); - info ("device /dev/usb/%s now disconnecting", cp->name); - - /* remove from device table */ - /* Nobody can open() this device any more */ - down (&dev_table_mutex); - dev_table[cp->dtindex] = NULL; - up (&dev_table_mutex); - - /* remove our devfs node */ - /* Nobody can see this device any more */ - devfs_unregister (cp->devfs); - - /* Stop the interrupt endpoint */ - auerswald_int_release (cp); - - /* remove the control chain allocated in auerswald_probe - This has the benefit of - a) all pending (a)synchronous urbs are unlinked - b) all buffers dealing with urbs are reclaimed - */ - auerchain_free (&cp->controlchain); - - if (cp->open_count == 0) { - /* nobody is using this device. So we can clean up now */ - up (&cp->mutex);/* up() is possible here because no other task - can open the device (see above). I don't want - to kfree() a locked mutex. */ - auerswald_delete (cp); - } else { - /* device is used. Remove the pointer to the - usb device (it's not valid any more). The last - release() will do the clean up */ - cp->usbdev = NULL; - up (&cp->mutex); - /* Terminate waiting writers */ - wake_up (&cp->bufferwait); - /* Inform all waiting readers */ - for ( u = 0; u < AUH_TYPESIZE; u++) { - pauerscon_t scp = cp->services[u]; - if (scp) scp->disconnect( scp); - } - } - - /* The device releases this module */ - MOD_DEC_USE_COUNT; -} - -/* Descriptor for the devices which are served by this driver. - NOTE: this struct is parsed by the usbmanager install scripts. - Don't change without caution! -*/ -static struct usb_device_id auerswald_ids [] = { - { USB_DEVICE (ID_AUERSWALD, 0x00C0) }, /* COMpact 2104 USB */ - { USB_DEVICE (ID_AUERSWALD, 0x00DB) }, /* COMpact 4410/2206 USB */ - { USB_DEVICE (ID_AUERSWALD, 0x00F1) }, /* Comfort 2000 System Telephone */ - { USB_DEVICE (ID_AUERSWALD, 0x00F2) }, /* Comfort 1200 System Telephone */ - { } /* Terminating entry */ -}; - -/* Standard module device table */ -MODULE_DEVICE_TABLE (usb, auerswald_ids); - -/* Standard usb driver struct */ -static struct usb_driver auerswald_driver = { - name: "auerswald", - probe: auerswald_probe, - disconnect: auerswald_disconnect, - fops: &auerswald_fops, - minor: AUER_MINOR_BASE, - id_table: auerswald_ids, -}; - - -/* --------------------------------------------------------------------- */ -/* Module loading/unloading */ - -/* Driver initialisation. Called after module loading. - NOTE: there is no concurrency at _init -*/ -static int __init auerswald_init (void) -{ - int result; - dbg ("init"); - - /* initialize the device table */ - memset (&dev_table, 0, sizeof(dev_table)); - init_MUTEX (&dev_table_mutex); - - /* register driver at the USB subsystem */ - result = usb_register (&auerswald_driver); - if (result < 0) { - err ("driver could not be registered"); - return -1; - } - return 0; -} - -/* Driver deinit. Called before module removal. - NOTE: there is no concurrency at _cleanup -*/ -static void __exit auerswald_cleanup (void) -{ - dbg ("cleanup"); - usb_deregister (&auerswald_driver); -} - -/* --------------------------------------------------------------------- */ -/* Linux device driver module description */ - -MODULE_AUTHOR (DRIVER_AUTHOR); -MODULE_DESCRIPTION (DRIVER_DESC); - -module_init (auerswald_init); -module_exit (auerswald_cleanup); - -/* --------------------------------------------------------------------- */ - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/CDCEther.c linux.21pre4-ac6/drivers/usb/CDCEther.c --- linux.21pre4/drivers/usb/CDCEther.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/CDCEther.c 2003-02-23 23:56:31.000000000 +0000 @@ -562,7 +562,7 @@ MODE_FLAG_DIRECTED | MODE_FLAG_BROADCAST | MODE_FLAG_MULTICAST; - buff = kmalloc(6 * net->mc_count, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + buff = kmalloc(6 * net->mc_count, GFP_ATOMIC); for (i = 0, mclist = net->mc_list; mclist && i < net->mc_count; i++, mclist = mclist->next) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/Config.in linux.21pre4-ac6/drivers/usb/Config.in --- linux.21pre4/drivers/usb/Config.in 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/Config.in 2003-02-21 15:46:07.000000000 +0000 @@ -46,7 +46,7 @@ dep_mbool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG $CONFIG_USB_STORAGE dep_mbool ' Datafab MDCFE-B Compact Flash Reader support' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL dep_mbool ' Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM $CONFIG_USB_STORAGE - dep_mbool ' ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE + dep_mbool ' ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE $CONFIG_IDE dep_mbool ' Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM $CONFIG_USB_STORAGE dep_mbool ' HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL dep_mbool ' SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL @@ -110,7 +110,7 @@ comment 'USB Miscellaneous drivers' dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL - dep_tristate ' USB Auerswald ISDN support (EXPERIMENTAL)' CONFIG_USB_AUERSWALD $CONFIG_USB $CONFIG_EXPERIMENTAL + dep_tristate ' Auerswald device support' CONFIG_USB_AUERSWALD $CONFIG_USB dep_tristate ' Texas Instruments Graph Link USB (aka SilverLink) cable support' CONFIG_USB_TIGL $CONFIG_USB dep_tristate ' Tieman Voyager USB Braille display support (EXPERIMENTAL)' CONFIG_USB_BRLVGER $CONFIG_USB $CONFIG_EXPERIMENTAL dep_tristate ' USB LCD device support' CONFIG_USB_LCD $CONFIG_USB diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/devio.c linux.21pre4-ac6/drivers/usb/devio.c --- linux.21pre4/drivers/usb/devio.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/devio.c 2003-01-06 17:29:33.000000000 +0000 @@ -43,7 +43,7 @@ #include #include #include - +#include struct async { struct list_head asynclist; @@ -1078,6 +1078,8 @@ int size; void *buf = 0; int retval = 0; + struct usb_interface *ifp = 0; + struct usb_driver *driver = 0; /* get input parameters and alloc buffer */ if (copy_from_user(&ctrl, (void *) arg, sizeof (ctrl))) @@ -1095,32 +1097,55 @@ } } - /* ioctl to device */ - if (ctrl.ifno < 0) { - switch (ctrl.ioctl_code) { - /* access/release token for issuing control messages - * ask a particular driver to bind/unbind, ... etc - */ - } - retval = -ENOSYS; - - /* ioctl to the driver which has claimed a given interface */ - } else { - struct usb_interface *ifp = 0; - if (!ps->dev) - retval = -ENODEV; - else if (ctrl.ifno >= ps->dev->actconfig->bNumInterfaces) + if (!ps->dev) + retval = -ENODEV; + else if (!(ifp = usb_ifnum_to_if (ps->dev, ctrl.ifno))) + retval = -EINVAL; + else switch (ctrl.ioctl_code) { + + /* disconnect kernel driver from interface, leaving it unbound */ + case USBDEVFS_DISCONNECT: + driver = ifp->driver; + if (driver) { + down (&driver->serialize); + dbg ("disconnect '%s' from dev %d interface %d", + driver->name, ps->dev->devnum, ctrl.ifno); + driver->disconnect (ps->dev, ifp->private_data); + usb_driver_release_interface (driver, ifp); + up (&driver->serialize); + } else retval = -EINVAL; - else { - if (!(ifp = usb_ifnum_to_if (ps->dev, ctrl.ifno))) - retval = -EINVAL; - else if (ifp->driver == 0 || ifp->driver->ioctl == 0) - retval = -ENOSYS; - } - if (retval == 0) + break; + + /* let kernel drivers try to (re)bind to the interface */ + case USBDEVFS_CONNECT: + usb_find_interface_driver_for_ifnum (ps->dev, ctrl.ifno); + break; + + /* talk directly to the interface's driver */ + default: + lock_kernel(); /* against module unload */ + driver = ifp->driver; + if (driver == 0 || driver->ioctl == 0) { + unlock_kernel(); + retval = -ENOSYS; + } else { + if (ifp->driver->owner) { + __MOD_INC_USE_COUNT(ifp->driver->owner); + unlock_kernel(); + } /* ifno might usefully be passed ... */ - retval = ifp->driver->ioctl (ps->dev, ctrl.ioctl_code, buf); + retval = driver->ioctl (ps->dev, ctrl.ioctl_code, buf); /* size = min_t(int, size, retval)? */ + if (ifp->driver->owner) { + __MOD_DEC_USE_COUNT(ifp->driver->owner); + } else { + unlock_kernel(); + } + } + + if (retval == -ENOIOCTLCMD) + retval = -ENOTTY; } /* cleanup and return */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hcd/ehci-dbg.c linux.21pre4-ac6/drivers/usb/hcd/ehci-dbg.c --- linux.21pre4/drivers/usb/hcd/ehci-dbg.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hcd/ehci-dbg.c 2003-02-04 15:00:43.000000000 +0000 @@ -287,7 +287,26 @@ default: tmp = '?'; break; \ }; tmp; }) -static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) +static inline char token_mark (u32 token) +{ + token = le32_to_cpu (token); + if (token & QTD_STS_ACTIVE) + return '*'; + if (token & QTD_STS_HALT) + return '-'; + if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */ + || QTD_LENGTH (token) == 0) + return ' '; + /* tries to advance through hw_alt_next */ + return '/'; +} + +static void qh_lines ( + struct ehci_hcd *ehci, + struct ehci_qh *qh, + char **nextp, + unsigned *sizep +) { u32 scratch; u32 hw_curr; @@ -296,26 +315,49 @@ unsigned temp; unsigned size = *sizep; char *next = *nextp; + char mark; + mark = token_mark (qh->hw_token); + if (mark == '/') { /* qh_alt_next controls qh advance? */ + if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next) + mark = '#'; /* blocked */ + else if (qh->hw_alt_next & cpu_to_le32 (0x01)) + mark = '.'; /* use hw_qtd_next */ + /* else alt_next points to some other qtd */ + } scratch = cpu_to_le32p (&qh->hw_info1); - hw_curr = cpu_to_le32p (&qh->hw_current); + hw_curr = (mark == '*') ? cpu_to_le32p (&qh->hw_current) : 0; temp = snprintf (next, size, - "qh/%p dev%d %cs ep%d %08x %08x (%08x %08x)", + "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", qh, scratch & 0x007f, speed_char (scratch), (scratch >> 8) & 0x000f, scratch, cpu_to_le32p (&qh->hw_info2), - hw_curr, cpu_to_le32p (&qh->hw_token)); + cpu_to_le32p (&qh->hw_token), mark, + (cpu_to_le32 (0x8000000) & qh->hw_token) + ? "data0" : "data1", + (cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f); size -= temp; next += temp; + /* hc may be modifying the list as we read it ... */ list_for_each (entry, &qh->qtd_list) { td = list_entry (entry, struct ehci_qtd, qtd_list); scratch = cpu_to_le32p (&td->hw_token); + mark = ' '; + if (hw_curr == td->qtd_dma) + mark = '*'; + else if (qh->hw_qtd_next == td->qtd_dma) + mark = '+'; + else if (QTD_LENGTH (scratch)) { + if (td->hw_alt_next == ehci->async->hw_alt_next) + mark = '#'; + else if (td->hw_alt_next != EHCI_LIST_END) + mark = '/'; + } temp = snprintf (next, size, - "\n\t%std/%p %s len=%d %08x urb %p", - (hw_curr == td->qtd_dma) ? "*" : "", - td, ({ char *tmp; + "\n\t%p%c%s len=%d %08x urb %p", + td, mark, ({ char *tmp; switch ((scratch>>8)&0x03) { case 0: tmp = "out"; break; case 1: tmp = "in"; break; @@ -325,17 +367,31 @@ (scratch >> 16) & 0x7fff, scratch, td->urb); + if (temp < 0) + temp = 0; + else if (size < temp) + temp = size; size -= temp; next += temp; + if (temp == size) + goto done; } temp = snprintf (next, size, "\n"); - *sizep = size - temp; - *nextp = next + temp; + if (temp < 0) + temp = 0; + else if (size < temp) + temp = size; + size -= temp; + next += temp; + +done: + *sizep = size; + *nextp = next; } static ssize_t -show_async (struct device *dev, char *buf, size_t count, loff_t off) +show_async (struct device *dev, char *buf) { struct pci_dev *pdev; struct ehci_hcd *ehci; @@ -344,38 +400,36 @@ char *next; struct ehci_qh *qh; - if (off != 0) - return 0; - pdev = container_of (dev, struct pci_dev, dev); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); next = buf; - size = count; + size = PAGE_SIZE; /* dumps a snapshot of the async schedule. * usually empty except for long-term bulk reads, or head. * one QH per line, and TDs we know about */ spin_lock_irqsave (&ehci->lock, flags); - for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) - qh_lines (qh, &next, &size); - if (ehci->reclaim) { + for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh) + qh_lines (ehci, qh, &next, &size); + if (ehci->reclaim && size > 0) { temp = snprintf (next, size, "\nreclaim =\n"); size -= temp; next += temp; - qh_lines (ehci->reclaim, &next, &size); + for (qh = ehci->reclaim; size > 0 && qh; qh = qh->reclaim) + qh_lines (ehci, qh, &next, &size); } spin_unlock_irqrestore (&ehci->lock, flags); - return count - size; + return PAGE_SIZE - size; } static DEVICE_ATTR (async, S_IRUGO, show_async, NULL); #define DBG_SCHED_LIMIT 64 static ssize_t -show_periodic (struct device *dev, char *buf, size_t count, loff_t off) +show_periodic (struct device *dev, char *buf) { struct pci_dev *pdev; struct ehci_hcd *ehci; @@ -385,8 +439,6 @@ char *next; unsigned i, tag; - if (off != 0) - return 0; if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC))) return 0; seen_count = 0; @@ -394,7 +446,7 @@ pdev = container_of (dev, struct pci_dev, dev); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); next = buf; - size = count; + size = PAGE_SIZE; temp = snprintf (next, size, "size = %d\n", ehci->periodic_size); size -= temp; @@ -436,7 +488,7 @@ scratch & 0x007f, (scratch >> 8) & 0x000f, p.qh->usecs, p.qh->c_usecs, - scratch >> 16); + 0x7ff & (scratch >> 16)); /* FIXME TD info too */ @@ -478,14 +530,14 @@ spin_unlock_irqrestore (&ehci->lock, flags); kfree (seen); - return count - size; + return PAGE_SIZE - size; } static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL); #undef DBG_SCHED_LIMIT static ssize_t -show_registers (struct device *dev, char *buf, size_t count, loff_t off) +show_registers (struct device *dev, char *buf) { struct pci_dev *pdev; struct ehci_hcd *ehci; @@ -495,20 +547,18 @@ static char fmt [] = "%*s\n"; static char label [] = ""; - if (off != 0) - return 0; - pdev = container_of (dev, struct pci_dev, dev); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); next = buf; - size = count; + size = PAGE_SIZE; spin_lock_irqsave (&ehci->lock, flags); /* Capability Registers */ i = readw (&ehci->caps->hci_version); - temp = snprintf (next, size, "EHCI %x.%02x, hcd state %d\n", + temp = snprintf (next, size, + "EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n", i >> 8, i & 0x0ff, ehci->hcd.state); size -= temp; next += temp; @@ -578,7 +628,7 @@ spin_unlock_irqrestore (&ehci->lock, flags); - return count - size; + return PAGE_SIZE - size; } static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hcd/ehci.h linux.21pre4-ac6/drivers/usb/hcd/ehci.h --- linux.21pre4/drivers/usb/hcd/ehci.h 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hcd/ehci.h 2003-02-21 16:32:35.000000000 +0000 @@ -81,6 +81,7 @@ struct pci_pool *sitd_pool; /* sitd per split iso urb */ struct timer_list watchdog; + unsigned stamp; #ifdef EHCI_STATS struct ehci_stats stats; @@ -235,12 +236,12 @@ /* the rest is HCD-private */ dma_addr_t qtd_dma; /* qtd address */ struct list_head qtd_list; /* sw qtd list */ - - /* dma same in urb's qtds, except 1st control qtd (setup buffer) */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ } __attribute__ ((aligned (32))); +#define QTD_MASK cpu_to_le32 (~0x1f) /* mask NakCnt+T in qh->hw_alt_next */ + /*-------------------------------------------------------------------------*/ /* type tag from {qh,itd,sitd,fstn}->hw_next */ @@ -304,13 +305,17 @@ union ehci_shadow qh_next; /* ptr to qh; or periodic */ struct list_head qtd_list; /* sw qtd list */ struct ehci_qtd *dummy; + struct ehci_qh *reclaim; /* next to reclaim */ atomic_t refcount; + unsigned stamp; u8 qh_state; #define QH_STATE_LINKED 1 /* HC sees this */ #define QH_STATE_UNLINK 2 /* HC may still see this */ #define QH_STATE_IDLE 3 /* HC doesn't see this */ +#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ +#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ /* periodic schedule info */ u8 usecs; /* intr bandwidth */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hcd/ehci-hcd.c linux.21pre4-ac6/drivers/usb/hcd/ehci-hcd.c --- linux.21pre4/drivers/usb/hcd/ehci-hcd.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hcd/ehci-hcd.c 2003-02-04 15:00:43.000000000 +0000 @@ -93,7 +93,7 @@ * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ -#define DRIVER_VERSION "2002-Dec-20" +#define DRIVER_VERSION "2003-Jan-22" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" @@ -107,14 +107,15 @@ #define EHCI_STATS #endif -#define INTR_AUTOMAGIC /* to be removed later in 2.5 */ +#define INTR_AUTOMAGIC /* urb lifecycle mode, gone in 2.5 */ /* magic numbers that can affect system performance */ #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ -#define EHCI_TUNE_RL_HS 0 /* nak throttle; see 4.9 */ +#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ #define EHCI_TUNE_RL_TT 0 #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ #define EHCI_TUNE_MULT_TT 1 +#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ #define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ @@ -406,9 +407,10 @@ * streaming mappings for I/O buffers, like pci_map_single(), * can return segments above 4GB, if the device allows. * - * NOTE: layered drivers can't yet tell when we enable that, - * so they can't pass this info along (like NETIF_F_HIGHDMA) - * (or like Scsi_Host.highmem_io) ... usb_bus.flags? + * NOTE: the dma mask is visible through dma_supported(), so + * drivers can pass this info along ... like NETIF_F_HIGHDMA, + * Scsi_Host.highmem_io, and so forth. It's readonly to all + * host side drivers though. */ if (HCC_64BIT_ADDR (hcc_params)) { writel (0, &ehci->regs->segment); @@ -416,13 +418,26 @@ ehci_info (ehci, "enabled 64bit PCI DMA\n"); } + /* help hc dma work well with cachelines */ + pci_set_mwi (ehci->hcd.pdev); + /* clear interrupt enables, set irq latency */ temp = readl (&ehci->regs->command) & 0xff; if (log2_irq_thresh < 0 || log2_irq_thresh > 6) log2_irq_thresh = 0; temp |= 1 << (16 + log2_irq_thresh); // if hc can park (ehci >= 0.96), default is 3 packets per async QH - // keeping default periodic framelist size + if (HCC_PGM_FRAMELISTLEN (hcc_params)) { + /* periodic schedule size can be smaller than default */ + temp &= ~(3 << 2); + temp |= (EHCI_TUNE_FLS << 2); + switch (EHCI_TUNE_FLS) { + case 0: ehci->periodic_size = 1024; break; + case 1: ehci->periodic_size = 512; break; + case 2: ehci->periodic_size = 256; break; + default: BUG (); + } + } temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE), // Philips, Intel, and maybe others need CMD_RUN before the // root hub will detect new devices (why?); NEC doesn't @@ -476,7 +491,6 @@ ehci_ready (ehci); ehci_reset (ehci); bus->root_hub = 0; - usb_free_dev (udev); retval = -ENODEV; goto done2; } @@ -637,9 +651,13 @@ static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 status = readl (&ehci->regs->status); + u32 status; int bh; + spin_lock (&ehci->lock); + + status = readl (&ehci->regs->status); + /* e.g. cardbus physical eject */ if (status == ~(u32) 0) { ehci_dbg (ehci, "device removed\n"); @@ -648,9 +666,7 @@ status &= INTR_MASK; if (!status) /* irq sharing? */ - return; - - spin_lock (&ehci->lock); + goto done; /* clear (just) interrupts */ writel (status, &ehci->regs->status); @@ -693,6 +709,7 @@ if (bh) ehci_work (ehci, regs); +done: spin_unlock (&ehci->lock); } @@ -756,7 +773,6 @@ struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_qh *qh; unsigned long flags; - int maybe_irq = 1; spin_lock_irqsave (&ehci->lock, flags); switch (usb_pipetype (urb->pipe)) { @@ -766,23 +782,23 @@ qh = (struct ehci_qh *) urb->hcpriv; if (!qh) break; - while (qh->qh_state == QH_STATE_LINKED + + /* if we need to use IAA and it's busy, defer */ + if (qh->qh_state == QH_STATE_LINKED && ehci->reclaim && HCD_IS_RUNNING (ehci->hcd.state) ) { - spin_unlock_irqrestore (&ehci->lock, flags); + struct ehci_qh *last; - if (maybe_irq) { - if (in_interrupt ()) - return -EAGAIN; - maybe_irq = 0; - } - /* let pending unlinks complete, so this can start */ - wait_ms (1); + for (last = ehci->reclaim; + last->reclaim; + last = last->reclaim) + continue; + qh->qh_state = QH_STATE_UNLINK_WAIT; + last->reclaim = qh; - spin_lock_irqsave (&ehci->lock, flags); - } - if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim) + /* bypass IAA if the hc can't care */ + } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim) end_unlink_async (ehci, NULL); /* something else might have unlinked the qh by now */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hcd/ehci-mem.c linux.21pre4-ac6/drivers/usb/hcd/ehci-mem.c --- linux.21pre4/drivers/usb/hcd/ehci-mem.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hcd/ehci-mem.c 2003-02-04 15:00:43.000000000 +0000 @@ -75,8 +75,6 @@ qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma); if (qtd != 0) { ehci_qtd_init (qtd, dma); - if (ehci->async) - qtd->hw_alt_next = ehci->async->hw_alt_next; } return qtd; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hcd/ehci-q.c linux.21pre4-ac6/drivers/usb/hcd/ehci-q.c --- linux.21pre4/drivers/usb/hcd/ehci-q.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hcd/ehci-q.c 2003-02-21 15:49:41.000000000 +0000 @@ -43,7 +43,8 @@ /* fill a qtd, returning how much of the buffer we were able to queue up */ static int -qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) +qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, + int token, int maxpacket) { int i, count; u64 addr = buf; @@ -69,6 +70,10 @@ else count = len; } + + /* short packets may only terminate transfers */ + if (count != len) + count -= (count % maxpacket); } qtd->hw_token = cpu_to_le32 ((count << 16) | token); qtd->length = count; @@ -85,7 +90,7 @@ { qh->hw_current = 0; qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma); - qh->hw_alt_next = ehci->async->hw_alt_next; + qh->hw_alt_next = EHCI_LIST_END; /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ wmb (); @@ -96,7 +101,7 @@ #define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1) -static inline void qtd_copy_status ( +static void qtd_copy_status ( struct ehci_hcd *ehci, struct urb *urb, size_t length, @@ -235,7 +240,7 @@ int status; resubmit->dev = dev; - status = SUBMIT_URB (resubmit, SLAB_KERNEL); + status = SUBMIT_URB (resubmit, SLAB_ATOMIC); if (status != 0) err ("can't resubmit interrupt urb %p: status %d", resubmit, status); @@ -256,14 +261,26 @@ static unsigned qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) { - struct ehci_qtd *last = 0; + struct ehci_qtd *last = 0, *end = qh->dummy; struct list_head *entry, *tmp; - int stopped = 0; + int stopped; unsigned count = 0; + int do_status = 0; + u8 state; if (unlikely (list_empty (&qh->qtd_list))) return count; + /* completions (or tasks on other cpus) must never clobber HALT + * till we've gone through and cleaned everything up, even when + * they add urbs to this qh's queue or mark them for unlinking. + * + * NOTE: unlinking expects to be done in queue order. + */ + state = qh->qh_state; + qh->qh_state = QH_STATE_COMPLETING; + stopped = (state == QH_STATE_IDLE); + /* remove de-activated QTDs from front of queue. * after faults (including short reads), cleanup this urb * then let the queue advance. @@ -287,11 +304,14 @@ last = 0; } + /* ignore urbs submitted during completions we reported */ + if (qtd == end) + break; + /* hardware copies qtd out of qh overlay */ rmb (); token = le32_to_cpu (qtd->hw_token); stopped = stopped - || (qh->qh_state == QH_STATE_IDLE) || (HALT_BIT & qh->hw_token) != 0 || (ehci->hcd.state == USB_STATE_HALT); @@ -301,36 +321,53 @@ /* magic dummy for short reads; won't advance */ if (IS_SHORT_READ (token) && !(token & QTD_STS_HALT) - && ehci->async->hw_alt_next - == qh->hw_alt_next) + && (qh->hw_alt_next & QTD_MASK) + == ehci->async->hw_alt_next) { + stopped = 1; goto halt; + } /* stop scanning when we reach qtds the hc is using */ } else if (likely (!stopped)) { - last = 0; break; } else { - /* ignore active qtds unless some previous qtd + /* ignore active urbs unless some previous qtd * for the urb faulted (including short read) or * its urb was canceled. we may patch qh or qtds. */ - if ((token & QTD_STS_ACTIVE) - && urb->status == -EINPROGRESS) { - last = 0; + if (likely (urb->status == -EINPROGRESS)) + continue; + + /* issue status after short control reads */ + if (unlikely (do_status != 0) + && QTD_PID (token) == 0 /* OUT */) { + do_status = 0; continue; } + + /* token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_le32 (qtd->qtd_dma) + == qh->hw_current) + token = le32_to_cpu (qh->hw_token); + + /* force halt for unlinked or blocked qh, so we'll + * patch the qh later and so that completions can't + * activate it while we "know" it's stopped. + */ if ((HALT_BIT & qh->hw_token) == 0) { halt: qh->hw_token |= HALT_BIT; wmb (); - stopped = 1; } } /* remove it from the queue */ spin_lock (&urb->lock); qtd_copy_status (ehci, urb, qtd->length, token); + do_status = (urb->status == -EREMOTEIO) + && usb_pipecontrol (urb->pipe); spin_unlock (&urb->lock); if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { @@ -349,6 +386,9 @@ ehci_qtd_free (ehci, last); } + /* restore original state; caller must unlink or relink */ + qh->qh_state = state; + /* update qh after fault cleanup */ if (unlikely ((HALT_BIT & qh->hw_token) != 0)) { qh_update (ehci, qh, @@ -397,7 +437,7 @@ struct ehci_qtd *qtd, *qtd_prev; dma_addr_t buf; int len, maxpacket; - int is_input, status_patch = 0; + int is_input; u32 token; /* @@ -418,7 +458,7 @@ if (usb_pipecontrol (urb->pipe)) { /* SETUP pid */ qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest), - token | (2 /* "setup" */ << 8)); + token | (2 /* "setup" */ << 8), 8); /* ... and always at least one more pid */ token ^= QTD_TOGGLE; @@ -429,10 +469,6 @@ qtd->urb = urb; qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); list_add_tail (&qtd->qtd_list, head); - - if (len > 0 && is_input - && !(urb->transfer_flags & URB_SHORT_NOT_OK)) - status_patch = 1; } /* @@ -443,6 +479,7 @@ else buf = 0; + // FIXME this 'buf' check break some zlps... if (!buf || is_input) token |= (1 /* "in" */ << 8); /* else it's already initted to "out" pid (0 << 8) */ @@ -457,9 +494,11 @@ for (;;) { int this_qtd_len; - this_qtd_len = qtd_fill (qtd, buf, len, token); + this_qtd_len = qtd_fill (qtd, buf, len, token, maxpacket); len -= this_qtd_len; buf += this_qtd_len; + if (is_input) + qtd->hw_alt_next = ehci->async->hw_alt_next; /* qh makes control packets use qtd toggle; maybe switch it */ if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) @@ -477,6 +516,13 @@ list_add_tail (&qtd->qtd_list, head); } + /* unless the bulk/interrupt caller wants a chance to clean + * up after short reads, hc should advance qh past this urb + */ + if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 + || usb_pipecontrol (urb->pipe))) + qtd->hw_alt_next = EHCI_LIST_END; + /* * control requests may need a terminating data "status" ack; * bulk ones may need a terminating short packet (zero length). @@ -503,23 +549,10 @@ list_add_tail (&qtd->qtd_list, head); /* never any data in such packets */ - qtd_fill (qtd, 0, 0, token); + qtd_fill (qtd, 0, 0, token, 0); } } - /* if we're permitting a short control read, we want the hardware to - * just continue after short data and send the status ack. it can do - * that on the last data packet (typically the only one). for other - * packets, software fixup is needed (in qh_completions). - */ - if (status_patch) { - struct ehci_qtd *prev; - - prev = list_entry (qtd->qtd_list.prev, - struct ehci_qtd, qtd_list); - prev->hw_alt_next = QTD_NEXT (qtd->qtd_dma); - } - /* by default, enable interrupt on urb completion */ if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT))) qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC); @@ -641,7 +674,8 @@ case USB_SPEED_FULL: /* EPS 0 means "full" */ - info1 |= (EHCI_TUNE_RL_TT << 28); + if (type != PIPE_INTERRUPT) + info1 |= (EHCI_TUNE_RL_TT << 28); if (type == PIPE_CONTROL) { info1 |= (1 << 27); /* for TT */ info1 |= 1 << 14; /* toggle from qtd */ @@ -658,12 +692,13 @@ case USB_SPEED_HIGH: /* no TT involved */ info1 |= (2 << 12); /* EPS "high" */ - info1 |= (EHCI_TUNE_RL_HS << 28); if (type == PIPE_CONTROL) { + info1 |= (EHCI_TUNE_RL_HS << 28); info1 |= 64 << 16; /* usb2 fixed maxpacket */ info1 |= 1 << 14; /* toggle from qtd */ info2 |= (EHCI_TUNE_MULT_HS << 30); } else if (type == PIPE_BULK) { + info1 |= (EHCI_TUNE_RL_HS << 28); info1 |= 512 << 16; /* usb2 fixed maxpacket */ info2 |= (EHCI_TUNE_MULT_HS << 30); } else { /* PIPE_INTERRUPT */ @@ -799,8 +834,8 @@ && !usb_pipecontrol (urb->pipe)) { /* "never happens": drivers do stall cleanup right */ if (qh->qh_state != QH_STATE_IDLE - && (cpu_to_le32 (QTD_STS_HALT) - & qh->hw_token) == 0) + && !list_empty (&qh->qtd_list) + && qh->qh_state != QH_STATE_COMPLETING) ehci_warn (ehci, "clear toggle dev%d " "ep%d%s: not idle\n", usb_pipedevice (urb->pipe), @@ -839,7 +874,6 @@ __list_splice (qtd_list, qh->qtd_list.prev); ehci_qtd_init (qtd, qtd->qtd_dma); - qtd->hw_alt_next = ehci->async->hw_alt_next; qh->dummy = qtd; /* hc must see the new dummy at list end */ @@ -907,9 +941,12 @@ /* the async qh for the qtds being reclaimed are now unlinked from the HC */ +static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh); + static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh = ehci->reclaim; + struct ehci_qh *next; del_timer (&ehci->watchdog); @@ -920,6 +957,10 @@ ehci->reclaim = 0; ehci->reclaim_ready = 0; + /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ + next = qh->reclaim; + qh->reclaim = 0; + qh_completions (ehci, qh, regs); if (!list_empty (&qh->qtd_list) @@ -939,6 +980,9 @@ jiffies + EHCI_ASYNC_JIFFIES); } } + + if (next) + start_unlink_async (ehci, next); } /* makes sure the async qh will become idle */ @@ -951,7 +995,8 @@ #ifdef DEBUG if (ehci->reclaim - || qh->qh_state != QH_STATE_LINKED + || (qh->qh_state != QH_STATE_LINKED + && qh->qh_state != QH_STATE_UNLINK_WAIT) #ifdef CONFIG_SMP // this macro lies except on SMP compiles || !spin_is_locked (&ehci->lock) @@ -983,6 +1028,9 @@ wmb (); if (unlikely (ehci->hcd.state == USB_STATE_HALT)) { + /* if (unlikely (qh->reclaim != 0)) + * this will recurse, probably not much + */ end_unlink_async (ehci, NULL); return; } @@ -1001,40 +1049,52 @@ scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh; - unsigned count; + int unlink_delay = 0; + if (!++(ehci->stamp)) + ehci->stamp++; rescan: qh = ehci->async->qh_next.qh; - count = 0; if (likely (qh != 0)) { do { /* clean any finished work for this qh */ - if (!list_empty (&qh->qtd_list)) { + if (!list_empty (&qh->qtd_list) + && qh->stamp != ehci->stamp) { int temp; /* unlinks could happen here; completion - * reporting drops the lock. + * reporting drops the lock. rescan using + * the latest schedule, but don't rescan + * qhs we already finished (no looping). */ qh = qh_get (qh); + qh->stamp = ehci->stamp; temp = qh_completions (ehci, qh, regs); qh_put (ehci, qh); if (temp != 0) { - count += temp; goto rescan; } } - /* unlink idle entries, reducing HC PCI usage as - * well as HCD schedule-scanning costs. - * - * FIXME don't unlink idle entries so quickly; it - * can penalize (common) half duplex protocols. + /* unlink idle entries, reducing HC PCI usage as well + * as HCD schedule-scanning costs. delay for any qh + * we just scanned, there's a not-unusual case that it + * doesn't stay idle for long. + * (plus, avoids some kind of re-activation race.) */ - if (list_empty (&qh->qtd_list) && !ehci->reclaim) { - start_unlink_async (ehci, qh); + if (list_empty (&qh->qtd_list)) { + if (qh->stamp == ehci->stamp) + unlink_delay = 1; + else if (!ehci->reclaim) { + start_unlink_async (ehci, qh); + unlink_delay = 0; + } } qh = qh->qh_next.qh; } while (qh); } + + if (unlink_delay && !timer_pending (&ehci->watchdog)) + mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES/2); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hcd.c linux.21pre4-ac6/drivers/usb/hcd.c --- linux.21pre4/drivers/usb/hcd.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hcd.c 2003-02-23 23:56:31.000000000 +0000 @@ -1025,7 +1025,7 @@ return -EPIPE; /* NOTE: 2.5 passes this value explicitly in submit() */ - mem_flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL; + mem_flags = GFP_ATOMIC; /* FIXME there should be a sharable lock protecting us against * config/altsetting changes and disconnects, kicking in here. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/hid-core.c linux.21pre4-ac6/drivers/usb/hid-core.c --- linux.21pre4/drivers/usb/hid-core.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/hid-core.c 2003-02-21 16:00:58.000000000 +0000 @@ -1090,6 +1090,12 @@ #define USB_DEVICE_ID_POWERMATE 0x0410 /* Griffin PowerMate */ #define USB_DEVICE_ID_SOUNDKNOB 0x04AA /* Griffin SoundKnob */ +#define USB_VENDOR_ID_ONTRAK 0x0a07 +#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 + +#define USB_VENDOR_ID_TANGTOP 0x0d3d +#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1121,6 +1127,13 @@ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { 0, 0 } }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/kaweth.c linux.21pre4-ac6/drivers/usb/kaweth.c --- linux.21pre4/drivers/usb/kaweth.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/kaweth.c 2003-02-21 15:50:47.000000000 +0000 @@ -131,6 +131,7 @@ { USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */ { USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */ { USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */ + { USB_DEVICE(0x0506, 0x11f8) }, /* 3Com 3C460 */ { USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */ { USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */ { USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */ @@ -700,7 +701,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) { struct kaweth_device *kaweth = net->priv; - char *private_header; + u16 *private_header; int res; @@ -732,7 +733,7 @@ } private_header = __skb_push(skb, 2); - *private_header = cpu_to_le16(skb->len); + *private_header = cpu_to_le16(skb->len-2); kaweth->tx_skb = skb; FILL_BULK_URB(kaweth->tx_urb, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/Makefile linux.21pre4-ac6/drivers/usb/Makefile --- linux.21pre4/drivers/usb/Makefile 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/Makefile 2003-02-21 15:46:07.000000000 +0000 @@ -18,7 +18,7 @@ usbcore-objs := usb.o usb-debug.o hub.o hid-objs := hid-core.o pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o - +auerswald-objs := auerbuf.o auerchain.o auerchar.o auermain.o # Optional parts of multipart objects. @@ -34,6 +34,12 @@ hid-objs += hid-input.o endif +ifdef CONFIG_USB_AUERISDN +ifneq ($(CONFIG_USB_AUERISDN),n) + auerswald-objs += auerisdn.o auerisdn_b.o +endif +endif + # Object file lists. obj-y := @@ -125,3 +131,6 @@ pwc.o: $(pwc-objs) $(LD) -r -o $@ $(pwc-objs) + +auerswald.o: $(auerswald-objs) + $(LD) -r -o $@ $(auerswald-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/pegasus.h linux.21pre4-ac6/drivers/usb/pegasus.h --- linux.21pre4/drivers/usb/pegasus.h 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/pegasus.h 2003-02-21 15:51:38.000000000 +0000 @@ -122,7 +122,6 @@ #define VENDOR_COMPAQ 0x049f #define VENDOR_COREGA 0x07aa #define VENDOR_DLINK 0x2001 -#define VENDOR_EASIDOCK 0x1342 #define VENDOR_ELCON 0x0db7 #define VENDOR_ELSA 0x05cc #define VENDOR_HAWKING 0x0e66 @@ -131,6 +130,7 @@ #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b #define VENDOR_MELCO 0x0411 +#define VENDOR_MOBILITY 0x1342 #define VENDOR_NETGEAR 0x0846 #define VENDOR_SMARTBRIDGES 0x08d1 #define VENDOR_SMC 0x0707 @@ -164,7 +164,7 @@ PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, - DEFAULT_GPIO_RESET ) + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", VENDOR_ADMTEK, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II ) @@ -212,7 +212,7 @@ DEFAULT_GPIO_RESET ) PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002, DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) -PEGASUS_DEV( "EasiDock Ethernet", VENDOR_EASIDOCK, 0x0304, +PEGASUS_DEV( "EasiDock Ethernet", VENDOR_MOBILITY, 0x0304, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000, DEFAULT_GPIO_RESET ) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/serial/ftdi_sio.c linux.21pre4-ac6/drivers/usb/serial/ftdi_sio.c --- linux.21pre4/drivers/usb/serial/ftdi_sio.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/serial/ftdi_sio.c 2003-02-21 15:48:38.000000000 +0000 @@ -161,6 +161,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { } /* Terminating entry */ }; @@ -169,6 +170,7 @@ static __devinitdata struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { } /* Terminating entry */ }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/serial/ftdi_sio.h linux.21pre4-ac6/drivers/usb/serial/ftdi_sio.h --- linux.21pre4/drivers/usb/serial/ftdi_sio.h 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/serial/ftdi_sio.h 2003-02-21 15:48:38.000000000 +0000 @@ -17,11 +17,14 @@ * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the * FTDI_SIO implementation. * + * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais + * from Rudolf Gugler */ #define FTDI_VID 0x0403 /* Vendor Id */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/serial/pl2303.c linux.21pre4-ac6/drivers/usb/serial/pl2303.c --- linux.21pre4/drivers/usb/serial/pl2303.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/serial/pl2303.c 2003-02-21 15:47:31.000000000 +0000 @@ -70,6 +70,7 @@ { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, + { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, { } /* Terminating entry */ }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/serial/pl2303.h linux.21pre4-ac6/drivers/usb/serial/pl2303.h --- linux.21pre4/drivers/usb/serial/pl2303.h 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/serial/pl2303.h 2003-02-21 15:47:31.000000000 +0000 @@ -28,3 +28,6 @@ #define RATOC_VENDOR_ID 0x0584 #define RATOC_PRODUCT_ID 0xb000 + +#define TRIPP_VENDOR_ID 0x2478 +#define TRIPP_PRODUCT_ID 0x2008 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/datafab.c linux.21pre4-ac6/drivers/usb/storage/datafab.c --- linux.21pre4/drivers/usb/storage/datafab.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/datafab.c 2003-02-21 15:46:55.000000000 +0000 @@ -121,8 +121,8 @@ return US_BULK_TRANSFER_FAILED; } - // -ENOENT -- we canceled this transfer - if (result == -ENOENT) { + // -ECONNRESET -- we canceled this transfer + if (result == -ECONNRESET) { US_DEBUGP("datafab_raw_bulk: transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/freecom.c linux.21pre4-ac6/drivers/usb/storage/freecom.c --- linux.21pre4/drivers/usb/storage/freecom.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/freecom.c 2003-02-21 15:46:55.000000000 +0000 @@ -198,7 +198,7 @@ result = usb_stor_bulk_msg (us, ideout, opipe, FCM_PACKET_LENGTH, &partial); if (result != 0) { - if (result == -ENOENT) + if (result == -ECONNRESET) return US_BULK_TRANSFER_ABORTED; else return USB_STOR_TRANSPORT_ERROR; @@ -238,7 +238,7 @@ result = usb_stor_bulk_msg (us, idein, opipe, FCM_PACKET_LENGTH, &partial); if (result != 0) { - if (result == -ENOENT) + if (result == -ECONNRESET) return US_BULK_TRANSFER_ABORTED; else return USB_STOR_TRANSPORT_ERROR; @@ -251,7 +251,7 @@ result = usb_stor_bulk_msg (us, buffer, ipipe, desired_length, &partial); if (result != 0) { - if (result == -ENOENT) + if (result == -ECONNRESET) return US_BULK_TRANSFER_ABORTED; else return USB_STOR_TRANSPORT_ERROR; @@ -292,8 +292,8 @@ US_DEBUGP ("Freecom readdata xpot failure: r=%d, p=%d\n", result, partial); - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("freecom_readdata(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -333,8 +333,8 @@ US_DEBUGP ("Freecom writedata xpot failure: r=%d, p=%d\n", result, partial); - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("freecom_writedata(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -396,8 +396,8 @@ US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", result, partial); - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -410,8 +410,8 @@ result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); US_DEBUGP("foo Status result %d %d\n", result, partial); - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -448,8 +448,8 @@ US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", result, partial); - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -463,8 +463,8 @@ US_DEBUGP("bar Status result %d %d\n", result, partial); - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -524,7 +524,7 @@ result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); US_DEBUG(pdump ((void *) fst, partial)); - if (result == -ENOENT) { + if (result == -ECONNRESET) { US_DEBUGP ("freecom_transport: transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -552,7 +552,7 @@ US_DEBUGP("FCM: Waiting for status\n"); result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); - if (result == -ENOENT) { + if (result == -ECONNRESET) { US_DEBUGP ("freecom_transport: transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/isd200.c linux.21pre4-ac6/drivers/usb/storage/isd200.c --- linux.21pre4/drivers/usb/storage/isd200.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/isd200.c 2003-02-21 15:46:55.000000000 +0000 @@ -435,8 +435,8 @@ return ISD200_TRANSPORT_FAILED; } - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("isd200_transfer_partial(): transfer aborted\n"); return ISD200_TRANSPORT_ABORTED; } @@ -574,7 +574,7 @@ &partial); US_DEBUGP("Bulk command transfer result=%d\n", result); - if (result == -ENOENT) + if (result == -ECONNRESET) return ISD200_TRANSPORT_ABORTED; else if (result == -EPIPE) { /* if we stall, we need to clear it before we go on */ @@ -603,7 +603,7 @@ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_msg(us, &bcs, pipe, US_BULK_CS_WRAP_LEN, &partial); - if (result == -ENOENT) + if (result == -ECONNRESET) return ISD200_TRANSPORT_ABORTED; /* did the attempt to read the CSW fail? */ @@ -617,7 +617,7 @@ US_BULK_CS_WRAP_LEN, &partial); /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return ISD200_TRANSPORT_ABORTED; /* if it fails again, we need a reset and return an error*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/jumpshot.c linux.21pre4-ac6/drivers/usb/storage/jumpshot.c --- linux.21pre4/drivers/usb/storage/jumpshot.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/jumpshot.c 2003-02-21 15:46:55.000000000 +0000 @@ -132,7 +132,7 @@ if (result < 0) { /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; /* a stall is a fatal condition from the device */ @@ -181,8 +181,8 @@ return US_BULK_TRANSFER_FAILED; } - // -ENOENT -- we canceled this transfer - if (result == -ENOENT) { + // -ECONNRESET -- we canceled this transfer + if (result == -ECONNRESET) { US_DEBUGP("jumpshot_raw_bulk: transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/sddr09.c linux.21pre4-ac6/drivers/usb/storage/sddr09.c --- linux.21pre4/drivers/usb/storage/sddr09.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/sddr09.c 2003-02-21 15:46:55.000000000 +0000 @@ -110,7 +110,7 @@ if (result < 0) { /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; /* a stall is a fatal condition from the device */ @@ -161,8 +161,8 @@ return US_BULK_TRANSFER_FAILED; } - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("usbat_raw_bulk():" " transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/sddr55.c linux.21pre4-ac6/drivers/usb/storage/sddr55.c --- linux.21pre4/drivers/usb/storage/sddr55.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/sddr55.c 2003-02-21 15:46:55.000000000 +0000 @@ -106,8 +106,8 @@ return US_BULK_TRANSFER_FAILED; } - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("usbat_raw_bulk():" " transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/shuttle_usbat.c linux.21pre4-ac6/drivers/usb/storage/shuttle_usbat.c --- linux.21pre4/drivers/usb/storage/shuttle_usbat.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/shuttle_usbat.c 2003-02-21 15:46:55.000000000 +0000 @@ -104,7 +104,7 @@ if (result < 0) { /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; /* a stall is a fatal condition from the device */ @@ -155,8 +155,8 @@ return US_BULK_TRANSFER_FAILED; } - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { + /* -ECONNRESET -- we canceled this transfer */ + if (result == -ECONNRESET) { US_DEBUGP("usbat_raw_bulk():" " transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/storage/transport.c linux.21pre4-ac6/drivers/usb/storage/transport.c --- linux.21pre4/drivers/usb/storage/transport.c 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/storage/transport.c 2003-02-21 15:46:55.000000000 +0000 @@ -520,7 +520,7 @@ } /* did we abort this command? */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -820,7 +820,7 @@ } /* is the device removed? */ - if (urb->status == -ENOENT) { + if (urb->status == -ENODEV) { US_DEBUGP("-- device has been removed\n"); return; } @@ -876,7 +876,7 @@ } /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; /* STALL must be cleared when it is detected */ @@ -886,7 +886,7 @@ usb_sndctrlpipe(us->pusb_dev, 0)); /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_FAILED; } @@ -989,7 +989,7 @@ US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result); if (result < 0) { /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; /* a stall is a fatal condition from the device */ @@ -999,7 +999,7 @@ usb_sndctrlpipe(us->pusb_dev, 0)); /* if the command was aborted, indicate that */ - if (result == -ENOENT) + if (result == -ECONNRESET) return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_FAILED; } @@ -1129,7 +1129,7 @@ US_DEBUGP("Bulk command transfer result=%d\n", result); /* if the command was aborted, indicate that */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } @@ -1140,7 +1140,7 @@ result = usb_stor_clear_halt(us, pipe); /* if the command was aborted, indicate that */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } @@ -1180,7 +1180,7 @@ &partial); /* if the command was aborted, indicate that */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } @@ -1191,7 +1191,7 @@ result = usb_stor_clear_halt(us, pipe); /* if the command was aborted, indicate that */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } @@ -1202,7 +1202,7 @@ US_BULK_CS_WRAP_LEN, &partial); /* if the command was aborted, indicate that */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } @@ -1213,7 +1213,7 @@ result = usb_stor_clear_halt(us, pipe); /* if the command was aborted, indicate that */ - if (result == -ENOENT) { + if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; } else { ret = USB_STOR_TRANSPORT_ERROR; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/uhci.c linux.21pre4-ac6/drivers/usb/uhci.c --- linux.21pre4/drivers/usb/uhci.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/uhci.c 2003-02-21 15:54:11.000000000 +0000 @@ -3136,7 +3136,7 @@ up_failed: #ifdef CONFIG_PROC_FS - remove_proc_entry("uhci", 0); + remove_proc_entry("driver/uhci", 0); proc_failed: #endif @@ -3156,7 +3156,7 @@ printk(KERN_INFO "uhci: not all urb_priv's were freed\n"); #ifdef CONFIG_PROC_FS - remove_proc_entry("uhci", 0); + remove_proc_entry("driver/uhci", 0); #endif if (errbuf) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usb.c linux.21pre4-ac6/drivers/usb/usb.c --- linux.21pre4/drivers/usb/usb.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usb.c 2003-02-23 23:56:31.000000000 +0000 @@ -164,6 +164,26 @@ } } +/* + * usb_ifnum_to_ifpos - convert the interface _number_ (as in interface.bInterfaceNumber) + * to the interface _position_ (as in dev->actconfig->interface + position) + * @dev: the device to use + * @ifnum: the interface number (bInterfaceNumber); not interface position + * + * Note that the number is the same as the position for all interfaces _except_ + * devices with interfaces not sequentially numbered (e.g., 0, 2, 3, etc). + */ +int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum) +{ + int i; + + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) + if (dev->actconfig->interface[i].altsetting[0].bInterfaceNumber == ifnum) + return i; + + return -EINVAL; +} + /** * usb_deregister - unregister a USB driver * @driver: USB operations of the driver to unregister @@ -546,7 +566,6 @@ iface->private_data = NULL; } - /** * usb_match_id - find first usb_device_id matching device or interface * @dev: the device whose descriptors are considered when matching @@ -759,6 +778,23 @@ return -1; } +/* + * usb_find_interface_driver_for_ifnum - convert ifnum to ifpos via + * usb_ifnum_to_ifpos and call usb_find_interface_driver(). + * @dev: the device to use + * @ifnum: the interface number (bInterfaceNumber); not interface position! + * + * Note usb_find_interface_driver's ifnum parameter is actually interface position. + */ +int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum) +{ + int ifpos = usb_ifnum_to_ifpos(dev, ifnum); + + if (0 > ifpos) + return -EINVAL; + + return usb_find_interface_driver(dev, ifpos); +} #ifdef CONFIG_HOTPLUG @@ -1003,7 +1039,7 @@ struct urb *urb; urb = (struct urb *)kmalloc(sizeof(struct urb) + iso_packets * sizeof(struct iso_packet_descriptor), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + GFP_ATOMIC); if (!urb) { err("alloc_urb: kmalloc failed"); return NULL; @@ -2382,6 +2418,7 @@ * into the kernel, and other device drivers are built as modules, * then these symbols need to be exported for the modules to use. */ +EXPORT_SYMBOL(usb_ifnum_to_ifpos); EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_epnum_to_ep_desc); @@ -2396,6 +2433,7 @@ EXPORT_SYMBOL(usb_free_dev); EXPORT_SYMBOL(usb_inc_dev_use); +EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum); EXPORT_SYMBOL(usb_driver_claim_interface); EXPORT_SYMBOL(usb_interface_claimed); EXPORT_SYMBOL(usb_driver_release_interface); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usbkbd.c linux.21pre4-ac6/drivers/usb/usbkbd.c --- linux.21pre4/drivers/usb/usbkbd.c 2003-01-29 16:26:59.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usbkbd.c 2003-02-21 15:58:54.000000000 +0000 @@ -272,7 +272,7 @@ MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); static struct usb_driver usb_kbd_driver = { - name: "keyboard", + name: "usbkbd", probe: usb_kbd_probe, disconnect: usb_kbd_disconnect, id_table: usb_kbd_id_table, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usb-midi.h linux.21pre4-ac6/drivers/usb/usb-midi.h --- linux.21pre4/drivers/usb/usb-midi.h 2003-01-29 16:27:00.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usb-midi.h 2003-02-21 15:57:33.000000000 +0000 @@ -41,6 +41,7 @@ #define USBMIDI_ROLAND_UA100G 0x0000 #define USBMIDI_ROLAND_MPU64 0x0002 #define USBMIDI_ROLAND_SC8850 0x0003 +#define USBMIDI_ROLAND_SC8820 0x0007 #define USBMIDI_ROLAND_UM2 0x0005 #define USBMIDI_ROLAND_UM1 0x0009 #define USBMIDI_ROLAND_PC300 0x0008 @@ -104,6 +105,13 @@ { { 0x01, 15 }, {-1, -1} }, }, + { /* Roland SC8820 */ + "Roland SC8820", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820, 2, -1, + { { 0x81, 17 }, {-1, -1} }, + { { 0x01, 17 }, {-1, -1} }, + }, + { /* YAMAHA MU1000 */ "YAMAHA MU1000", USB_VENDOR_ID_YAMAHA, USBMIDI_YAMAHA_MU1000, 0, -1, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usbmouse.c linux.21pre4-ac6/drivers/usb/usbmouse.c --- linux.21pre4/drivers/usb/usbmouse.c 2003-01-29 16:26:59.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usbmouse.c 2003-02-21 15:58:54.000000000 +0000 @@ -188,7 +188,7 @@ MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); static struct usb_driver usb_mouse_driver = { - name: "usb_mouse", + name: "usbmouse", probe: usb_mouse_probe, disconnect: usb_mouse_disconnect, id_table: usb_mouse_id_table, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usbnet.c linux.21pre4-ac6/drivers/usb/usbnet.c --- linux.21pre4/drivers/usb/usbnet.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usbnet.c 2003-02-21 15:52:40.000000000 +0000 @@ -35,7 +35,7 @@ * - GeneSys GL620USB-A * - NetChip 1080 (interoperates with NetChip Win32 drivers) * - Prolific PL-2301/2302 (replaces "plusb" driver) - * - PXA-250 or SA-1100 Linux PDAs like iPaq, Yopy, and Zaurus + * - PXA-250 or SA-1100 Linux PDAs like iPAQ, Yopy, and Zaurus * * USB devices can implement their side of this protocol at the cost * of two bulk endpoints; it's not restricted to "cable" applications. @@ -1276,7 +1276,7 @@ /*------------------------------------------------------------------------- * * Intel's SA-1100 chip integrates basic USB support, and is used - * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more. + * in PDAs like some iPAQs, the Yopy, some Zaurus models, and more. * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to * network using minimal USB framing data. * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usb-ohci.c linux.21pre4-ac6/drivers/usb/usb-ohci.c --- linux.21pre4/drivers/usb/usb-ohci.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usb-ohci.c 2003-02-23 23:56:31.000000000 +0000 @@ -621,7 +621,7 @@ /* allocate the private part of the URB */ urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + GFP_ATOMIC); if (!urb_priv) { usb_dec_dev_use (urb->dev); return -ENOMEM; @@ -695,9 +695,6 @@ if (urb->timeout) { struct list_head *entry; - // FIXME: usb-uhci uses relative timeouts (like this), - // while uhci uses absolute ones (probably better). - // Pick one solution and change the affected drivers. urb->timeout += jiffies; list_for_each (entry, &ohci->timeout_list) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usb-ohci.h linux.21pre4-ac6/drivers/usb/usb-ohci.h --- linux.21pre4/drivers/usb/usb-ohci.h 2003-01-29 16:26:59.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usb-ohci.h 2003-02-21 15:49:00.000000000 +0000 @@ -386,7 +386,6 @@ struct ohci_regs * regs; /* OHCI controller's memory */ struct list_head ohci_hcd_list; /* list of all ohci_hcd */ - struct ohci * next; // chain of ohci device contexts struct list_head timeout_list; // struct list_head urb_list; // list of all pending urbs // spinlock_t urb_list_lock; // lock to keep consistency diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/usb/usb-uhci.c linux.21pre4-ac6/drivers/usb/usb-uhci.c --- linux.21pre4/drivers/usb/usb-uhci.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/usb/usb-uhci.c 2003-02-23 23:56:31.000000000 +0000 @@ -88,9 +88,6 @@ static kmem_cache_t *urb_priv_kmem; #endif -#define SLAB_FLAG (in_interrupt () || current->state != TASK_RUNNING ? SLAB_ATOMIC : SLAB_KERNEL) -#define KMALLOC_FLAG (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_KERNEL) - /* CONFIG_USB_UHCI_HIGH_BANDWITH turns on Full Speed Bandwidth * Reclamation: feature that puts loop on descriptor loop when * there's some transfer going on. With FSBR, USB performance @@ -1515,7 +1512,7 @@ if (ret) goto err; - tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), KMALLOC_FLAG); + tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), GFP_ATOMIC); if (!tdm) { ret = -ENOMEM; @@ -1667,9 +1664,9 @@ } #ifdef DEBUG_SLAB - urb_priv = kmem_cache_alloc(urb_priv_kmem, SLAB_FLAG); + urb_priv = kmem_cache_alloc(urb_priv_kmem, SLAB_ATOMIC); #else - urb_priv = kmalloc (sizeof (urb_priv_t), KMALLOC_FLAG); + urb_priv = kmalloc (sizeof (urb_priv_t), GFP_ATOMIC); #endif if (!urb_priv) { usb_dec_dev_use (urb->dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/atafb.c linux.21pre4-ac6/drivers/video/atafb.c --- linux.21pre4/drivers/video/atafb.c 2003-01-29 16:26:56.000000000 +0000 +++ linux.21pre4-ac6/drivers/video/atafb.c 2003-02-06 22:51:44.000000000 +0000 @@ -1193,7 +1193,7 @@ par->HBB = gend2 - par->HHT - 2; #if 0 /* One more Videl constraint: data fetch of two lines must not overlap */ - if (par->HDB & 0x200 && par->HDB & ~0x200 - par->HDE <= 5) { + if ((par->HDB & 0x200) && (par->HDB & ~0x200) - par->HDE <= 5) { /* if this happens increase margins, decrease hfreq. */ } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/aty/atyfb_base.c linux.21pre4-ac6/drivers/video/aty/atyfb_base.c --- linux.21pre4/drivers/video/aty/atyfb_base.c 2003-01-29 16:26:59.000000000 +0000 +++ linux.21pre4-ac6/drivers/video/aty/atyfb_base.c 2003-01-06 17:41:28.000000000 +0000 @@ -360,6 +360,7 @@ /* 3D RAGE Mobility */ { 0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS }, + { 0x4c52, 0x4c52, 0x00, 0x00, m64n_mob_p, 230, 40, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS | M64F_MAGIC_POSTDIV | M64F_SDRAM_MAGIC_PLL | M64F_XL_DLL }, { 0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS }, #endif /* CONFIG_FB_ATY_CT */ }; @@ -438,7 +439,7 @@ #endif /* defined(CONFIG_PPC) */ -#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT) +#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_CT_VAIO_LCD) static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info) { unsigned long temp; @@ -460,7 +461,7 @@ /* read the register value */ return aty_ld_le32(LCD_DATA, info); } -#endif /* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT */ +#endif /* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT || CONFIG_FB_ATY_CT_VAIO_LCD */ /* ------------------------------------------------------------------------- */ @@ -1772,6 +1773,9 @@ #if defined(CONFIG_PPC) int sense; #endif +#if defined(CONFIG_FB_ATY_CT_VAIO_LCD) + u32 pm, hs; +#endif u8 pll_ref_div; info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0); @@ -2089,6 +2093,35 @@ var = default_var; #endif /* !__sparc__ */ #endif /* !CONFIG_PPC */ +#if defined(CONFIG_FB_ATY_CT_VAIO_LCD) + /* Power Management */ + pm=aty_ld_lcd(POWER_MANAGEMENT, info); + pm=(pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_PCI; + pm|=PWR_MGT_ON; + aty_st_lcd(POWER_MANAGEMENT, pm, info); + udelay(10); + + /* OVR_WID_LEFT_RIGHT */ + hs=aty_ld_le32(OVR_WID_LEFT_RIGHT,info); + hs= 0x00000000; + aty_st_le32(OVR_WID_LEFT_RIGHT, hs, info); + udelay(10); + + /* CONFIG_PANEL */ + hs=aty_ld_lcd(CONFIG_PANEL,info); + hs|=DONT_SHADOW_HEND ; + aty_st_lcd(CONFIG_PANEL, hs, info); + udelay(10); + +#if defined(DEBUG) + printk("LCD_INDEX CONFIG_PANEL LCD_GEN_CTRL POWER_MANAGEMENT\n" + "%08x %08x %08x %08x\n", + aty_ld_le32(LCD_INDEX, info), + aty_ld_lcd(CONFIG_PANEL, info), + aty_ld_lcd(LCD_GEN_CTRL, info), + aty_ld_lcd(POWER_MANAGEMENT, info), +#endif /* DEBUG */ +#endif /* CONFIG_FB_ATY_CT_VAIO_LCD */ #endif /* !MODULE */ if (noaccel) var.accel_flags &= ~FB_ACCELF_TEXT; @@ -2714,6 +2747,23 @@ /* * Blank the display. */ +#if defined(CONFIG_FB_ATY_CT_VAIO_LCD) +static int set_backlight_enable(int on, struct fb_info_aty *info) +{ + unsigned int reg = aty_ld_lcd(POWER_MANAGEMENT, info); + if(on) { + reg=(reg & ~SUSPEND_NOW) | PWR_BLON; + } else { + reg=(reg & ~PWR_BLON) | SUSPEND_NOW; + } + aty_st_lcd(POWER_MANAGEMENT, reg, info); + udelay(10); +#ifdef DEBUG + printk(KERN_INFO "set_backlight_enable(%i): %08x\n", on, aty_ld_lcd(POWER_MANAGEMENT, info) ); +#endif + return 0; +} +#endif /* CONFIG_FB_ATY_CT_VAIO_LCD */ static void atyfbcon_blank(int blank, struct fb_info *fb) { @@ -2725,6 +2775,9 @@ set_backlight_enable(0); #endif /* CONFIG_PMAC_BACKLIGHT */ +#if defined(CONFIG_FB_ATY_CT_VAIO_LCD) + set_backlight_enable(!blank, info); +#endif /* CONFIG_FB_ATY_CT_VAIO_LCD */ gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info); if (blank > 0) switch (blank-1) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/aty/mach64_ct.c linux.21pre4-ac6/drivers/video/aty/mach64_ct.c --- linux.21pre4/drivers/video/aty/mach64_ct.c 2003-01-29 16:26:59.000000000 +0000 +++ linux.21pre4-ac6/drivers/video/aty/mach64_ct.c 2003-01-06 17:41:28.000000000 +0000 @@ -178,11 +178,14 @@ } pll->pll_gen_cntl |= mpostdiv<<4; /* mclk */ - if (M64_HAS(MAGIC_POSTDIV)) - pll->pll_ext_cntl = 0; - else +#if defined(CONFIG_FB_ATY_CT_VAIO_LCD) pll->pll_ext_cntl = mpostdiv; /* xclk == mclk */ - +#else + if ( M64_HAS(MAGIC_POSTDIV) ) + pll->pll_ext_cntl = 0; + else + pll->pll_ext_cntl = mpostdiv; /* xclk == mclk */ +#endif switch (pll->vclk_post_div_real) { case 2: vpostdiv = 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/aty/mach64.h linux.21pre4-ac6/drivers/video/aty/mach64.h --- linux.21pre4/drivers/video/aty/mach64.h 2003-01-29 16:26:59.000000000 +0000 +++ linux.21pre4-ac6/drivers/video/aty/mach64.h 2003-01-06 17:41:28.000000000 +0000 @@ -1148,6 +1148,8 @@ #define APC_LUT_MN 0x39 #define APC_LUT_OP 0x3A +/* Values in CONFIG_PANEL */ +#define DONT_SHADOW_HEND 0x00004000 /* Values in LCD_MISC_CNTL */ #define BIAS_MOD_LEVEL_MASK 0x0000ff00 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/Config.in linux.21pre4-ac6/drivers/video/Config.in --- linux.21pre4/drivers/video/Config.in 2003-01-29 16:26:56.000000000 +0000 +++ linux.21pre4-ac6/drivers/video/Config.in 2003-02-24 00:08:30.000000000 +0000 @@ -124,22 +124,35 @@ if [ "$CONFIG_FB_MATROX" != "n" ]; then bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE - bool ' G100/G200/G400/G450/G550 support' CONFIG_FB_MATROX_G100 + bool ' G100/G200/G400/G450/G550 support' CONFIG_FB_MATROX_G450 + if [ "$CONFIG_FB_MATROX_G450" = "n" ]; then + bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100A + fi + if [ "$CONFIG_FB_MATROX_G450" = "y" -o "$CONFIG_FB_MATROX_G100A" = "y" ]; then + define_bool CONFIG_FB_MATROX_G100 y + fi if [ "$CONFIG_I2C" != "n" ]; then dep_tristate ' Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then dep_tristate ' G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C fi fi - dep_tristate ' G450/G550 second head support (mandatory for G550)' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100 + dep_tristate ' Matrox /proc interface' CONFIG_FB_MATROX_PROC $CONFIG_FB_MATROX bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD fi tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY if [ "$CONFIG_FB_ATY" != "n" ]; then bool ' Mach64 GX support (EXPERIMENTAL)' CONFIG_FB_ATY_GX bool ' Mach64 CT/VT/GT/LT (incl. 3D RAGE) support' CONFIG_FB_ATY_CT + if [ "$CONFIG_FB_ATY_CT" = "y" ]; then + bool ' Sony Vaio C1VE 1024x480 LCD support' CONFIG_FB_ATY_CT_VAIO_LCD + fi fi + tristate ' Intel 830M/845G/852GM/855GM/865G display support (EXPERIMENTAL)' CONFIG_FB_INTEL tristate ' ATI Radeon display support (EXPERIMENTAL)' CONFIG_FB_RADEON +# if [ "$CONFIG_FB_RADEON" = "y" ]; then +# bool ' Sony Vaio C1MV 1280x600 LCD support' CONFIG_FB_RADEON_VAIO_LCD +# fi tristate ' ATI Rage128 display support (EXPERIMENTAL)' CONFIG_FB_ATY128 tristate ' SIS acceleration (EXPERIMENTAL)' CONFIG_FB_SIS if [ "$CONFIG_FB_SIS" != "n" ]; then @@ -287,6 +300,7 @@ "$CONFIG_FB_PM3" = "y" -o "$CONFIG_FB_TRIDENT" = "y" -o \ "$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \ + "$CONFIG_FB_INTEL" = "y" -o \ "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \ "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \ "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \ @@ -306,12 +320,13 @@ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_TRIDENT" = "y" -o \ + "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \ "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \ "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \ "$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \ "$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ + "$CONFIG_FB_INTEL" = "m" -o \ "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \ "$CONFIG_FB_STI" = "m" ]; then @@ -322,6 +337,7 @@ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ "$CONFIG_FB_Q40" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \ + "$CONFIG_FB_INTEL" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ @@ -344,10 +360,11 @@ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \ - "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_TRIDENT" = "y" -o \ + "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \ "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ + "$CONFIG_FB_INTEL" = "m" -o \ "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \ "$CONFIG_FB_NEOMAGIC" = "m" ]; then define_tristate CONFIG_FBCON_CFB16 m @@ -379,6 +396,7 @@ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \ "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \ + "$CONFIG_FB_INTEL" = "y" -o \ "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" -o \ "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \ "$CONFIG_FB_STI" = "y" ]; then @@ -389,12 +407,13 @@ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_TRIDENT" = "y" -o \ + "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \ "$CONFIG_FB_3DFX" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ + "$CONFIG_FB_INTEL" = "m" -o \ "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \ - "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_STI" = "y" ]; then + "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_STI" = "m" ]; then define_tristate CONFIG_FBCON_CFB32 m fi fi @@ -441,9 +460,9 @@ define_tristate CONFIG_FBCON_HGA m fi fi - if [ "$CONFIG_FB_STI" = "y" ]; then - define_tristate CONFIG_FBCON_STI y - fi + fi + if [ "$CONFIG_FB_STI" = "y" ]; then + define_tristate CONFIG_FBCON_STI y fi bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/fbmem.c linux.21pre4-ac6/drivers/video/fbmem.c --- linux.21pre4/drivers/video/fbmem.c 2003-01-29 17:07:46.000000000 +0000 +++ linux.21pre4-ac6/drivers/video/fbmem.c 2003-02-24 00:07:23.000000000 +0000 @@ -130,6 +130,8 @@ extern int tx3912fb_init(void); extern int radeonfb_init(void); extern int radeonfb_setup(char*); +extern int intelfb_init(void); +extern int intelfb_setup(char*); extern int e1355fb_init(void); extern int e1355fb_setup(char*); extern int au1100fb_init(void); @@ -199,6 +201,9 @@ #ifdef CONFIG_FB_RADEON { "radeon", radeonfb_init, radeonfb_setup }, #endif +#ifdef CONFIG_FB_INTEL + { "intelfb", intelfb_init, intelfb_setup }, +#endif #ifdef CONFIG_FB_CONTROL { "controlfb", control_init, control_setup }, #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/intel/builtinmodes.c linux.21pre4-ac6/drivers/video/intel/builtinmodes.c --- linux.21pre4/drivers/video/intel/builtinmodes.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/video/intel/builtinmodes.c 2003-02-24 00:07:47.000000000 +0000 @@ -0,0 +1,222 @@ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED BY fbmode.pl -- DO NOT EDIT + */ + +static struct fb_videomode modedb[] = { + { + /* 640x350 @ 85 Hz, 37.9 kHz hsync */ + "640x350@85", 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, + FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 640x400 @ 85 Hz, 37.9 kHz hsync */ + "640x400@85", 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 720x400 @ 85 Hz, 37.9 kHz hsync */ + "720x400@85", 85, 720, 400, 28169, 108, 36, 42, 1, 72, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 640x480 @ 60 Hz, 31.5 kHz hsync */ + "640x480@60", 60, 640, 480, 39683, 48, 16, 33, 10, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 640x480 @ 73 Hz, 37.9 kHz hsync */ + "640x480@73", 73, 640, 480, 31746, 128, 24, 29, 9, 40, 2, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 640x480 @ 75 Hz, 37.5 kHz hsync */ + "640x480@75", 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 640x480 @ 85 Hz, 43.3 kHz hsync */ + "640x480@85", 85, 640, 480, 27778, 80, 56, 25, 1, 56, 3, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 800x600 @ 56 Hz, 35.2 kHz hsync */ + "800x600@56", 56, 800, 600, 27778, 128, 24, 22, 1, 72, 2, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 800x600 @ 60 Hz, 37.9 kHz hsync */ + "800x600@60", 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 800x600 @ 72 Hz, 48.1 kHz hsync */ + "800x600@72", 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 800x600 @ 75 Hz, 46.9 kHz hsync */ + "800x600@75", 75, 800, 600, 20202, 160, 16, 21, 1, 80, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 800x600 @ 85 Hz, 53.7 kHz hsync */ + "800x600@85", 85, 800, 600, 17762, 152, 32, 27, 1, 64, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ + "1024x768@60", 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ + "1024x768@70", 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 1024x768 @ 75 Hz, 60.1 kHz hsync */ + "1024x768@75", 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1024x768 @ 85 Hz, 68.7 kHz hsync */ + "1024x768@85", 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1152x864 @ 75 Hz, 67.5 kHz hsync */ + "1152x864@75", 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1280x960 @ 60 Hz, 60.0 kHz hsync */ + "1280x960@60", 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1280x960 @ 85 Hz, 85.9 kHz hsync */ + "1280x960@85", 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1280x1024 @ 60 Hz, 64.0 kHz hsync */ + "1280x1024@60", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1280x1024 @ 75 Hz, 80.0 kHz hsync */ + "1280x1024@75", 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1280x1024 @ 85 Hz, 91.1 kHz hsync */ + "1280x1024@85", 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1600x1200 @ 60 Hz, 75.0 kHz hsync */ + "1600x1200@60", 60, 1600, 1200, 6173, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1600x1200 @ 65 Hz, 81.2 kHz hsync */ + "1600x1200@65", 65, 1600, 1200, 5698, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1600x1200 @ 70 Hz, 87.5 kHz hsync */ + "1600x1200@70", 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1600x1200 @ 75 Hz, 93.8 kHz hsync */ + "1600x1200@75", 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1600x1200 @ 85 Hz, 106.2 kHz hsync */ + "1600x1200@85", 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1792x1344 @ 60 Hz, 83.7 kHz hsync */ + "1792x1344@60", 60, 1792, 1344, 4883, 328, 128, 46, 1, 200, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1792x1344 @ 75 Hz, 106.3 kHz hsync */ + "1792x1344@75", 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1856x1392 @ 60 Hz, 86.4 kHz hsync */ + "1856x1392@60", 60, 1856, 1392, 4581, 352, 96, 43, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1856x1392 @ 75 Hz, 112.5 kHz hsync */ + "1856x1392@75", 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1920x1440 @ 60 Hz, 90.0 kHz hsync */ + "1920x1440@60", 60, 1920, 1440, 4274, 344, 128, 56, 1, 208, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1920x1440 @ 75 Hz, 112.5 kHz hsync */ + "1920x1440@75", 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 832x624 @ 75 Hz, 49.7 kHz hsync */ + "832x624@75", 75, 832, 624, 17457, 224, 32, 39, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 1152x768 @ 55 Hz, 44.2 kHz hsync */ + "1152x768@55", 55, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1400x1050 @ 60 Hz, 64.9 kHz hsync */ + "1400x1050@60", 60, 1400, 1050, 8197, 240, 88, 18, 2, 152, 12, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1400x1050 @ 75 Hz, 81.5 kHz hsync */ + "1400x1050@75", 75, 1400, 1050, 6418, 128, 64, 26, 2, 320, 12, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 1600x1024 @ 60 Hz, 64.0 kHz hsync */ + "1600x1024@60", 60, 1600, 1024, 9354, 30, 20, 37, 3, 20, 3, + 0, FB_VMODE_NONINTERLACED + }, + { + /* 1920x1440 @ 85 Hz, 128.5 kHz hsync */ + "1920x1440@85", 85, 1920, 1440, 2930, 368, 152, 68, 1, 216, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 2048x1536 @ 60 Hz, 95.3 kHz hsync */ + "2048x1536@60", 60, 2048, 1536, 3746, 376, 152, 49, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 2048x1536 @ 75 Hz, 120.2 kHz hsync */ + "2048x1536@75", 75, 2048, 1536, 2937, 392, 168, 63, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + /* 2048x1536 @ 85 Hz, 137.0 kHz hsync */ + "2048x1536@85", 85, 2048, 1536, 2577, 392, 168, 72, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + } +}; + +static int num_modes = sizeof(modedb) / sizeof(modedb[0]); + +#define DFLT_MODE 3 + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre4/drivers/video/intel/intelfbdrv.c linux.21pre4-ac6/drivers/video/intel/intelfbdrv.c --- linux.21pre4/drivers/video/intel/intelfbdrv.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre4-ac6/drivers/video/intel/intelfbdrv.c 2003-02-24 00:09:54.000000000 +0000 @@ -0,0 +1,2219 @@ +/* + * intelfb + * + * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G + * integrated graphics chips. + * + * Copyright (C) 2002, 2003 David Dawes + * + * This driver consists of two parts. The first part (intelfbdrv.c) provides + * the basic fbdev interfaces, is derived in part from the radeonfb and + * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) + * provides the code to program the hardware. Most of it is derived from + * the i810/i830 XFree86 driver. The HW-specific code is covered here + * under a dual license (GPL and MIT/XFree86 license). + * + * Author: David Dawes + * + */ + +/* $DHD: intelfb/intelfbdrv.c,v 1.15 2003/02/06 17:50:08 dawes Exp $ */ +/* $TG$ */ + +/* + * Changes: + * 01/2003 - Initial driver (0.1.0), no mode switching, no acceleration. + * This initial version is a basic core that works a lot like + * the vesafb driver. It must be built-in to the kernel, + * and the initial video mode must be set with vga=XXX at + * boot time. (David Dawes) + * + * 01/2003 - Version 0.2.0: Mode switching added, colormap support + * implemented, Y panning, and soft screen blanking implemented. + * No acceleration yet. (David Dawes) + * + * 01/2003 - Version 0.3.0: fbcon acceleration support added. Module + * option handling added. (David Dawes) + * + * 01/2003 - Version 0.4.0: fbcon HW cursor support added. (David Dawes) + * + * 01/2003 - Version 0.4.1: Add auto-generation of built-in modes. + * (David Dawes) + * + * 02/2003 - Version 0.4.2: Add check for active non-CRT devices, and + * mode validation checks. (David Dawes) + * + * 02/2003 - Version 0.4.3: Check when the VC is in graphics mode so that + * acceleration is disabled while an XFree86 server is running. + * (David Dawes) + * + * 02/2003 - Version 0.4.4: Monitor DPMS support. (David Dawes) + * + * 02/2003 - Version 0.4.5: Basic XFree86 + fbdev working. (David Dawes) + * + * 02/2003 - Version 0.5.0: Modify to work with the 2.5.32 kernel as well + * as 2.4.x kernels. (David Dawes) + * + * 02/2003 - Version 0.6.0: Split out HW-specifics into a separate file. + * (David Dawes) + * + * 02/2003 - Version 0.7.0: Test on 852GM/855GM. Acceleration and HW + * cursor are disabled on this platform. (David Dawes) + * + * 02/2003 - Version 0.7.1: Test on 845G. Acceleration is disabled + * on this platform. (David Dawes) + * + * 02/2003 - Version 0.7.2: Test on 830M. Acceleration and HW + * cursor are disabled on this platform. (David Dawes) + * + * 02/2003 - Version 0.7.3: Fix 8-bit modes for mobile platforms + * (David Dawes) + * + * 02/2003 - Version 0.7.4: Add checks for FB and FBCON_HAS_CFB* configured + * in the kernel, and add mode bpp verification and default + * bpp selection based on which FBCON_HAS_CFB* are configured. + * (David Dawes) + * + * 02/2003 - Version 0.7.5: Add basic package/install scripts based on the + * DRI packaging scripts. (David Dawes) + * + * TODO: + * - + * + * Wish List: + * - Check clock limits for 845G and 830M. + * - Test on SMP config. + * - Check if any functions/data should be __devinit, etc. + * - See if it's feasible to get/use DDC/EDID info. + * - MTRR support. + * - See if module unloading can work. + * - See if driver works built-in to 2.5.32 kernel. + * - Check acceleration problems on 830M-855GM. + * - Add gtf support so that arbitrary modes can be calculated. + * - Port driver to latest 2.5.x fbdev interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include