diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/arch/alpha/kernel/process.c linux.21pre5-ac1/arch/alpha/kernel/process.c --- linux.21pre5/arch/alpha/kernel/process.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/alpha/kernel/process.c 2003-02-27 00:10:40.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.21pre5/arch/alpha/kernel/smp.c linux.21pre5-ac1/arch/alpha/kernel/smp.c --- linux.21pre5/arch/alpha/kernel/smp.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/alpha/kernel/smp.c 2003-02-27 20:00:50.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.21pre5/arch/alpha/mm/fault.c linux.21pre5-ac1/arch/alpha/mm/fault.c --- linux.21pre5/arch/alpha/mm/fault.c 2003-02-27 18:40:11.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/arm/config.in linux.21pre5-ac1/arch/arm/config.in --- linux.21pre5/arch/arm/config.in 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/arm/mm/fault-common.c linux.21pre5-ac1/arch/arm/mm/fault-common.c --- linux.21pre5/arch/arm/mm/fault-common.c 2003-02-27 18:40:18.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/cris/drivers/eeprom.c linux.21pre5-ac1/arch/cris/drivers/eeprom.c --- linux.21pre5/arch/cris/drivers/eeprom.c 2003-02-27 18:40:23.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/boot/setup.S linux.21pre5-ac1/arch/i386/boot/setup.S --- linux.21pre5/arch/i386/boot/setup.S 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/config.in linux.21pre5-ac1/arch/i386/config.in --- linux.21pre5/arch/i386/config.in 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/defconfig linux.21pre5-ac1/arch/i386/defconfig --- linux.21pre5/arch/i386/defconfig 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/apic.c linux.21pre5-ac1/arch/i386/kernel/apic.c --- linux.21pre5/arch/i386/kernel/apic.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/i386/kernel/apic.c 2003-03-01 18:57:18.000000000 +0000 @@ -649,7 +649,6 @@ } set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - boot_cpu_physical_apicid = 0; if (nmi_watchdog != NMI_NONE) nmi_watchdog = NMI_LOCAL_APIC; @@ -1169,8 +1168,7 @@ connect_bsp_APIC(); - phys_cpu_present_map = 1; - apic_write_around(APIC_ID, boot_cpu_physical_apicid); + phys_cpu_present_map = 1 << boot_cpu_physical_apicid; apic_pm_init2(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/arch/i386/kernel/dmi_scan.c linux.21pre5-ac1/arch/i386/kernel/dmi_scan.c --- linux.21pre5/arch/i386/kernel/dmi_scan.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/i386/kernel/dmi_scan.c 2003-03-03 15:23:00.000000000 +0000 @@ -11,6 +11,8 @@ #include #include +#include "pci-i386.h" + unsigned long dmi_broken; int is_sony_vaio_laptop; @@ -413,6 +415,8 @@ */ extern int skip_ioapic_setup; +extern int broken_440gx_bios; +extern unsigned int pci_probe; static __init int broken_pirq(struct dmi_blacklist *d) { printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n"); @@ -423,16 +427,9 @@ #ifdef CONFIG_X86_IO_APIC skip_ioapic_setup = 0; #endif - return 0; -} - -/* - * Toshiba keyboard likes to repeat keys when they are not repeated. - */ - -static __init int broken_toshiba_keyboard(struct dmi_blacklist *d) -{ - printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, contact pavel@ucw.cz\n"); + broken_440gx_bios = 1; + pci_probe |= PCI_BIOS_IRQ_SCAN; + return 0; } @@ -753,10 +750,6 @@ NO_MATCH, 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 - } }, { init_ints_after_s1, "Toshiba Satellite 4030cdt", { /* Reinitialization of 8259 is needed after S1 resume */ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), NO_MATCH, NO_MATCH, NO_MATCH diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/arch/i386/kernel/edd.c linux.21pre5-ac1/arch/i386/kernel/edd.c --- linux.21pre5/arch/i386/kernel/edd.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/elanfreq.c linux.21pre5-ac1/arch/i386/kernel/elanfreq.c --- linux.21pre5/arch/i386/kernel/elanfreq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/entry.S linux.21pre5-ac1/arch/i386/kernel/entry.S --- linux.21pre5/arch/i386/kernel/entry.S 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/i386/kernel/entry.S 2003-02-27 20:02:07.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.21pre5/arch/i386/kernel/gx-suspmod.c linux.21pre5-ac1/arch/i386/kernel/gx-suspmod.c --- linux.21pre5/arch/i386/kernel/gx-suspmod.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/head.S linux.21pre5-ac1/arch/i386/kernel/head.S --- linux.21pre5/arch/i386/kernel/head.S 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/i386_ksyms.c linux.21pre5-ac1/arch/i386/kernel/i386_ksyms.c --- linux.21pre5/arch/i386/kernel/i386_ksyms.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/i387.c linux.21pre5-ac1/arch/i386/kernel/i387.c --- linux.21pre5/arch/i386/kernel/i387.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/io_apic.c linux.21pre5-ac1/arch/i386/kernel/io_apic.c --- linux.21pre5/arch/i386/kernel/io_apic.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/irq.c linux.21pre5-ac1/arch/i386/kernel/irq.c --- linux.21pre5/arch/i386/kernel/irq.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/ldt.c linux.21pre5-ac1/arch/i386/kernel/ldt.c --- linux.21pre5/arch/i386/kernel/ldt.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/longhaul.c linux.21pre5-ac1/arch/i386/kernel/longhaul.c --- linux.21pre5/arch/i386/kernel/longhaul.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/longrun.c linux.21pre5-ac1/arch/i386/kernel/longrun.c --- linux.21pre5/arch/i386/kernel/longrun.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/Makefile linux.21pre5-ac1/arch/i386/kernel/Makefile --- linux.21pre5/arch/i386/kernel/Makefile 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/p4-clockmod.c linux.21pre5-ac1/arch/i386/kernel/p4-clockmod.c --- linux.21pre5/arch/i386/kernel/p4-clockmod.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/pci-dma.c linux.21pre5-ac1/arch/i386/kernel/pci-dma.c --- linux.21pre5/arch/i386/kernel/pci-dma.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/pci-irq.c linux.21pre5-ac1/arch/i386/kernel/pci-irq.c --- linux.21pre5/arch/i386/kernel/pci-irq.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/arch/i386/kernel/pci-irq.c 2003-03-03 15:23:00.000000000 +0000 @@ -23,6 +23,7 @@ #define PIRQ_VERSION 0x0100 int broken_hp_bios_irq9; +int broken_440gx_bios; static struct irq_routing_table *pirq_table; @@ -681,7 +682,10 @@ void __init pcibios_irq_init(void) { DBG("PCI: IRQ init\n"); - pirq_table = pirq_find_routing_table(); + if (broken_440gx_bios) + pirq_table = NULL; + else + pirq_table = pirq_find_routing_table(); #ifdef CONFIG_PCI_BIOS if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) pirq_table = pcibios_get_irq_routing_table(); @@ -779,9 +783,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 +802,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.21pre5/arch/i386/kernel/powernow-k6.c linux.21pre5-ac1/arch/i386/kernel/powernow-k6.c --- linux.21pre5/arch/i386/kernel/powernow-k6.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/process.c linux.21pre5-ac1/arch/i386/kernel/process.c --- linux.21pre5/arch/i386/kernel/process.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/setup.c linux.21pre5-ac1/arch/i386/kernel/setup.c --- linux.21pre5/arch/i386/kernel/setup.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/smpboot.c linux.21pre5-ac1/arch/i386/kernel/smpboot.c --- linux.21pre5/arch/i386/kernel/smpboot.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/smp.c linux.21pre5-ac1/arch/i386/kernel/smp.c --- linux.21pre5/arch/i386/kernel/smp.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/speedstep.c linux.21pre5-ac1/arch/i386/kernel/speedstep.c --- linux.21pre5/arch/i386/kernel/speedstep.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/time.c linux.21pre5-ac1/arch/i386/kernel/time.c --- linux.21pre5/arch/i386/kernel/time.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/kernel/traps.c linux.21pre5-ac1/arch/i386/kernel/traps.c --- linux.21pre5/arch/i386/kernel/traps.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/lib/delay.c linux.21pre5-ac1/arch/i386/lib/delay.c --- linux.21pre5/arch/i386/lib/delay.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/i386/lib/delay.c 2003-02-27 20:02:30.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) { @@ -82,7 +82,7 @@ __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } -void __ndelay(unsigned long usecs) +void __ndelay(unsigned long nsecs) { - __const_udelay(usecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/arch/i386/lib/usercopy.c linux.21pre5-ac1/arch/i386/lib/usercopy.c --- linux.21pre5/arch/i386/lib/usercopy.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/arch/i386/lib/usercopy.c 2003-03-03 15:21:43.000000000 +0000 @@ -95,6 +95,26 @@ : "memory"); \ } while (0) +/** + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * Caller must check the specified block with access_ok() before calling + * this function. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ long __strncpy_from_user(char *dst, const char *src, long count) { @@ -103,6 +123,24 @@ return res; } +/** + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ long strncpy_from_user(char *dst, const char *src, long count) { @@ -138,6 +176,16 @@ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ } while (0) +/** + * clear_user: - Zero a block of memory in user space. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ unsigned long clear_user(void *to, unsigned long n) { @@ -146,6 +194,17 @@ return n; } +/** + * __clear_user: - Zero a block of memory in user space, with less checking. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ unsigned long __clear_user(void *to, unsigned long n) { @@ -153,12 +212,17 @@ return n; } -/* - * Return the size of a string (including the ending 0) +/** + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * @n: The maximum valid length * - * Return 0 on exception, a value greater than N if too long + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * If the string is too long, returns a value greater than @n. */ - long strnlen_user(const char *s, long n) { unsigned long mask = -__addr_ok(s); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/arch/i386/math-emu/fpu_system.h linux.21pre5-ac1/arch/i386/math-emu/fpu_system.h --- linux.21pre5/arch/i386/math-emu/fpu_system.h 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/mm/fault.c linux.21pre5-ac1/arch/i386/mm/fault.c --- linux.21pre5/arch/i386/mm/fault.c 2003-02-27 18:40:09.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/i386/mm/init.c linux.21pre5-ac1/arch/i386/mm/init.c --- linux.21pre5/arch/i386/mm/init.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/ia64/ia32/sys_ia32.c linux.21pre5-ac1/arch/ia64/ia32/sys_ia32.c --- linux.21pre5/arch/ia64/ia32/sys_ia32.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ia64/ia32/sys_ia32.c 2003-02-27 20:03:22.000000000 +0000 @@ -3783,7 +3783,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; @@ -3793,49 +3797,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.21pre5/arch/ia64/mm/fault.c linux.21pre5-ac1/arch/ia64/mm/fault.c --- linux.21pre5/arch/ia64/mm/fault.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/m68k/config.in linux.21pre5-ac1/arch/m68k/config.in --- linux.21pre5/arch/m68k/config.in 2003-02-27 18:40:16.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/m68k/kernel/m68k_ksyms.c linux.21pre5-ac1/arch/m68k/kernel/m68k_ksyms.c --- linux.21pre5/arch/m68k/kernel/m68k_ksyms.c 2003-02-27 18:40:17.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/m68k/kernel/setup.c linux.21pre5-ac1/arch/m68k/kernel/setup.c --- linux.21pre5/arch/m68k/kernel/setup.c 2003-02-27 18:40:17.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/m68k/q40/config.c linux.21pre5-ac1/arch/m68k/q40/config.c --- linux.21pre5/arch/m68k/q40/config.c 2003-02-27 18:40:17.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/mips/mm/fault.c linux.21pre5-ac1/arch/mips/mm/fault.c --- linux.21pre5/arch/mips/mm/fault.c 2003-02-27 18:40:12.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/mips64/mm/fault.c linux.21pre5-ac1/arch/mips64/mm/fault.c --- linux.21pre5/arch/mips64/mm/fault.c 2003-02-27 18:40:22.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/parisc/config.in linux.21pre5-ac1/arch/parisc/config.in --- linux.21pre5/arch/parisc/config.in 2003-02-27 18:40:22.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/parisc/kernel/lasimap.map linux.21pre5-ac1/arch/parisc/kernel/lasimap.map --- linux.21pre5/arch/parisc/kernel/lasimap.map 2003-02-27 18:40:22.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/ppc/config.in linux.21pre5-ac1/arch/ppc/config.in --- linux.21pre5/arch/ppc/config.in 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ppc/config.in 2003-02-27 20:05:11.000000000 +0000 @@ -196,12 +196,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.21pre5/arch/ppc/kernel/entry.S linux.21pre5-ac1/arch/ppc/kernel/entry.S --- linux.21pre5/arch/ppc/kernel/entry.S 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ppc/kernel/entry.S 2003-02-27 20:05:11.000000000 +0000 @@ -260,7 +260,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.21pre5/arch/ppc/kernel/idle.c linux.21pre5-ac1/arch/ppc/kernel/idle.c --- linux.21pre5/arch/ppc/kernel/idle.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ppc/kernel/idle.c 2003-02-27 20:05:11.000000000 +0000 @@ -48,9 +48,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) { @@ -70,11 +67,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.21pre5/arch/ppc/kernel/mk_defs.c linux.21pre5-ac1/arch/ppc/kernel/mk_defs.c --- linux.21pre5/arch/ppc/kernel/mk_defs.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ppc/kernel/mk_defs.c 2003-02-27 20:05:11.000000000 +0000 @@ -34,8 +34,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.21pre5/arch/ppc/kernel/ppc_defs.h linux.21pre5-ac1/arch/ppc/kernel/ppc_defs.h --- linux.21pre5/arch/ppc/kernel/ppc_defs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/arch/ppc/kernel/smp.c linux.21pre5-ac1/arch/ppc/kernel/smp.c --- linux.21pre5/arch/ppc/kernel/smp.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ppc/kernel/smp.c 2003-02-27 20:05:11.000000000 +0000 @@ -291,8 +291,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; @@ -345,7 +343,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.21pre5/arch/ppc/mm/fault.c linux.21pre5-ac1/arch/ppc/mm/fault.c --- linux.21pre5/arch/ppc/mm/fault.c 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/arch/ppc/mm/fault.c 2003-02-27 20:06:45.000000000 +0000 @@ -141,42 +141,40 @@ goto bad_area; if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - if (!is_write) - goto bad_area; - - /* - * N.B. The rs6000/xcoff ABI allows programs to access up to - * a few hundred bytes below the stack pointer. - * The kernel signal delivery code writes up to about 1.5kB - * below the stack pointer (r1) before decrementing it. - * The exec code can write slightly over 640kB to the stack - * before setting the user r1. Thus we allow the stack to - * expand to 1MB without further checks. - */ - if (address + 0x100000 < vma->vm_end) { - /* get user regs even if this fault is in kernel mode */ - struct pt_regs *uregs = current->thread.regs; - if (uregs == NULL) - goto bad_area; - - /* - * A user-mode access to an address a long way below - * the stack pointer is only valid if the instruction - * is one which would update the stack pointer to the - * address accessed if the instruction completed, - * i.e. either stwu rs,n(r1) or stwux rs,r1,rb - * (or the byte, halfword, float or double forms). - * - * If we don't check this then any write to the area - * between the last mapped region and the stack will - * expand the stack rather than segfaulting. - */ - if (address + 2048 < uregs->gpr[1] - && (!user_mode(regs) || !store_updates_sp(regs))) - goto bad_area; - } + if (!is_write) + goto bad_area; + + /* + * N.B. The rs6000/xcoff ABI allows programs to access up to + * a few hundred bytes below the stack pointer. + * The kernel signal delivery code writes up to about 1.5kB + * below the stack pointer (r1) before decrementing it. + * The exec code can write slightly over 640kB to the stack + * before setting the user r1. Thus we allow the stack to + * expand to 1MB without further checks. + */ + if (address + 0x100000 < vma->vm_end) { + /* get user regs even if this fault is in kernel mode */ + struct pt_regs *uregs = current->thread.regs; + if (uregs == NULL) + goto bad_area; + + /* + * A user-mode access to an address a long way below + * the stack pointer is only valid if the instruction + * is one which would update the stack pointer to the + * address accessed if the instruction completed, + * i.e. either stwu rs,n(r1) or stwux rs,r1,rb + * (or the byte, halfword, float or double forms). + * + * If we don't check this then any write to the area + * between the last mapped region and the stack will + * expand the stack rather than segfaulting. + */ + if (address + 2048 < uregs->gpr[1] + && (!user_mode(regs) || !store_updates_sp(regs))) + goto bad_area; + } if (expand_stack(vma, address)) goto bad_area; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/arch/s390/kernel/entry.S linux.21pre5-ac1/arch/s390/kernel/entry.S --- linux.21pre5/arch/s390/kernel/entry.S 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/arch/s390/kernel/entry.S 2003-02-27 20:07:22.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.21pre5/arch/s390x/kernel/entry.S linux.21pre5-ac1/arch/s390x/kernel/entry.S --- linux.21pre5/arch/s390x/kernel/entry.S 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/arch/s390x/kernel/entry.S 2003-02-27 20:07:32.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.21pre5/arch/s390x/kernel/linux32.c linux.21pre5-ac1/arch/s390x/kernel/linux32.c --- linux.21pre5/arch/s390x/kernel/linux32.c 2003-02-27 18:40:23.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sh/mm/fault.c linux.21pre5-ac1/arch/sh/mm/fault.c --- linux.21pre5/arch/sh/mm/fault.c 2003-02-27 18:40:18.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sparc/kernel/sunos_ioctl.c linux.21pre5-ac1/arch/sparc/kernel/sunos_ioctl.c --- linux.21pre5/arch/sparc/kernel/sunos_ioctl.c 2003-02-27 18:40:12.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sparc/mm/fault.c linux.21pre5-ac1/arch/sparc/mm/fault.c --- linux.21pre5/arch/sparc/mm/fault.c 2003-02-27 18:40:12.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sparc64/kernel/sunos_ioctl32.c linux.21pre5-ac1/arch/sparc64/kernel/sunos_ioctl32.c --- linux.21pre5/arch/sparc64/kernel/sunos_ioctl32.c 2003-02-27 18:40:17.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sparc64/kernel/sys_sparc32.c linux.21pre5-ac1/arch/sparc64/kernel/sys_sparc32.c --- linux.21pre5/arch/sparc64/kernel/sys_sparc32.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sparc64/mm/fault.c linux.21pre5-ac1/arch/sparc64/mm/fault.c --- linux.21pre5/arch/sparc64/mm/fault.c 2003-02-27 18:40:17.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/sparc64/solaris/timod.c linux.21pre5-ac1/arch/sparc64/solaris/timod.c --- linux.21pre5/arch/sparc64/solaris/timod.c 2003-02-27 18:40:17.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/arch/x86_64/boot/bootsect.S linux.21pre5-ac1/arch/x86_64/boot/bootsect.S --- linux.21pre5/arch/x86_64/boot/bootsect.S 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/arch/x86_64/boot/bootsect.S 2003-02-27 20:07:59.000000000 +0000 @@ -395,9 +395,9 @@ # NOTE: Doesn't save %ax or %dx; do it yourself if you need to. kill_motor: - xorw %ax, %ax # reset FDC - xorb %dl, %dl - int $0x13 + xorw %ax, %ax # reset FDC + xorb %dl, %dl + int $0x13 ret sectors: .word 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/CREDITS linux.21pre5-ac1/CREDITS --- linux.21pre5/CREDITS 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/CREDITS 2003-02-27 20:08:15.000000000 +0000 @@ -2556,6 +2556,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.21pre5/Documentation/00-INDEX linux.21pre5-ac1/Documentation/00-INDEX --- linux.21pre5/Documentation/00-INDEX 2003-02-27 18:40:26.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/Documentation/Configure.help linux.21pre5-ac1/Documentation/Configure.help --- linux.21pre5/Documentation/Configure.help 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/Documentation/Configure.help 2003-02-27 20:59:18.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. - 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... + 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. - If you need support for G450 or G550 secondary head, say Y to - "Matrox G450/G550 second head support" below. + 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). + + G450/G550 hardware can display TV picture only from secondary CRTC, + and it performs no scaling, so picture must have 525 or 625 lines. + +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 @@ -12734,12 +12765,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 @@ -15347,7 +15410,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 @@ -15750,6 +15813,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 @@ -16146,7 +16233,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. @@ -16161,8 +16248,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. @@ -16235,8 +16321,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 @@ -17078,17 +17165,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 @@ -17398,6 +17504,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 @@ -17547,6 +17666,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 @@ -19052,6 +19175,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 @@ -19118,6 +19250,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 @@ -23100,6 +23260,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 @@ -25852,6 +26029,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 @@ -25897,9 +26082,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 @@ -26272,6 +26459,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 @@ -26285,7 +26562,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 @@ -26455,6 +26732,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.21pre5/Documentation/cpufreq linux.21pre5-ac1/Documentation/cpufreq --- linux.21pre5/Documentation/cpufreq 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/Documentation/DocBook/kernel-api.tmpl linux.21pre5-ac1/Documentation/DocBook/kernel-api.tmpl --- linux.21pre5/Documentation/DocBook/kernel-api.tmpl 2003-02-27 18:40:27.000000000 +0000 +++ linux.21pre5-ac1/Documentation/DocBook/kernel-api.tmpl 2003-03-03 15:21:43.000000000 +0000 @@ -85,7 +85,11 @@ Memory Management in Linux The Slab Cache !Emm/slab.c - + + User Space Memory Access +!Iinclude/asm-i386/uaccess.h +!Iarch/i386/lib/usercopy.c + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/Documentation/DriverFixers linux.21pre5-ac1/Documentation/DriverFixers --- linux.21pre5/Documentation/DriverFixers 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/Documentation/i386/zero-page.txt linux.21pre5-ac1/Documentation/i386/zero-page.txt --- linux.21pre5/Documentation/i386/zero-page.txt 2003-02-27 18:40:27.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/Documentation/IPMI.txt linux.21pre5-ac1/Documentation/IPMI.txt --- linux.21pre5/Documentation/IPMI.txt 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/Documentation/networking/generic-hdlc.txt linux.21pre5-ac1/Documentation/networking/generic-hdlc.txt --- linux.21pre5/Documentation/networking/generic-hdlc.txt 2003-02-27 19:13:38.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/Documentation/sched-coding.txt linux.21pre5-ac1/Documentation/sched-coding.txt --- linux.21pre5/Documentation/sched-coding.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/Documentation/sched-design.txt linux.21pre5-ac1/Documentation/sched-design.txt --- linux.21pre5/Documentation/sched-design.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/Documentation/vm/overcommit-accounting linux.21pre5-ac1/Documentation/vm/overcommit-accounting --- linux.21pre5/Documentation/vm/overcommit-accounting 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/acpi/acpi_ksyms.c linux.21pre5-ac1/drivers/acpi/acpi_ksyms.c --- linux.21pre5/drivers/acpi/acpi_ksyms.c 2003-02-27 18:40:08.000000000 +0000 +++ linux.21pre5-ac1/drivers/acpi/acpi_ksyms.c 2003-02-27 00:06:47.000000000 +0000 @@ -68,6 +68,7 @@ EXPORT_SYMBOL(acpi_get_next_object); EXPORT_SYMBOL(acpi_evaluate_object); EXPORT_SYMBOL(acpi_get_table); +EXPORT_SYMBOL(acpi_get_firmware_table); EXPORT_SYMBOL(acpi_install_notify_handler); EXPORT_SYMBOL(acpi_remove_notify_handler); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/block/cciss.c linux.21pre5-ac1/drivers/block/cciss.c --- linux.21pre5/drivers/block/cciss.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/block/cciss.c 2003-03-03 15:21:22.000000000 +0000 @@ -94,7 +94,8 @@ }; /* How long to wait (in millesconds) for board to go into simple mode */ -#define MAX_CONFIG_WAIT 1000 +#define MAX_CONFIG_WAIT 30000 +#define MAX_IOCTL_CONFIG_WAIT 1000 /*define how many times we will try a command because of bus resets */ #define MAX_CMD_RETRIES 3 @@ -578,7 +579,7 @@ &(c->cfgtable->HostWrite.CoalIntCount)); writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; @@ -586,8 +587,11 @@ udelay(1000); } spin_unlock_irqrestore(&io_request_lock, flags); - if (i >= MAX_CONFIG_WAIT) - return -EFAULT; + if (i >= MAX_IOCTL_CONFIG_WAIT) + /* there is an unlikely case where this can happen, + * involving hot replacing a failed 144 GB drive in a + * RAID 5 set just as we attempt this ioctl. */ + return -EAGAIN; return 0; } case CCISS_GETNODENAME: @@ -627,7 +631,7 @@ writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; @@ -635,8 +639,11 @@ udelay(1000); } spin_unlock_irqrestore(&io_request_lock, flags); - if (i >= MAX_CONFIG_WAIT) - return -EFAULT; + if (i >= MAX_IOCTL_CONFIG_WAIT) + /* there is an unlikely case where this can happen, + * involving hot replacing a failed 144 GB drive in a + * RAID 5 set just as we attempt this ioctl. */ + return -EAGAIN; return 0; } @@ -2583,11 +2590,17 @@ &(c->cfgtable->HostWrite.TransportRequest)); writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); + /* Here, we wait, possibly for a long time, (4 secs or more). + * In some unlikely cases, (e.g. A failed 144 GB drive in a + * RAID 5 set was hot replaced just as we're coming in here) it + * can take that long. Normally (almost always) we will wait + * less than 1 sec. */ for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; /* delay and try again */ - udelay(1000); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); } #ifdef CCISS_DEBUG @@ -3021,12 +3034,8 @@ printk(KERN_INFO DRIVER_NAME "\n"); /* Register for out PCI devices */ - if (pci_register_driver(&cciss_pci_driver) > 0 ) - return 0; - else - return -ENODEV; - - } + return pci_module_init(&cciss_pci_driver); +} EXPORT_NO_SYMBOLS; static int __init init_cciss_module(void) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/block/elevator.c linux.21pre5-ac1/drivers/block/elevator.c --- linux.21pre5/drivers/block/elevator.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/block/elevator.c 2003-02-26 23:55:43.000000000 +0000 @@ -27,6 +27,25 @@ #include #include + +static int compatible(struct request *req, struct buffer_head *bh, + request_queue_t *q, int rw, + int count, int max_sectors) +{ + if (q->head_active) + return 0; + if (req->waiting) + return 0; + if (req->rq_dev != bh->b_rdev) + return 0; + if (req->cmd != rw) + return 0; + if (req->nr_sectors + count > max_sectors) + return 0; + return 1; +} + + /* * This is a bit tricky. It's given that bh and rq are for the same * device, but the next request might of course not be. Run through @@ -83,22 +102,38 @@ struct list_head *entry = &q->queue_head; unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE; struct request *__rq; - int backmerge_only = 0; + + /* + * Quick one-entry cache of last merge + * nb. we do no latency accounting this way. + */ + + if (q->last_request) { + struct request *__rq = q->last_request; - while (!backmerge_only && (entry = entry->prev) != head) { + if (compatible(__rq, bh, q, rw, count, max_sectors)) { + if (__rq->sector + __rq->nr_sectors == bh->b_rsector) { + *req = __rq; + return ELEVATOR_BACK_MERGE; + } + } + } + + + while ((entry = entry->prev) != head) { __rq = blkdev_entry_to_request(entry); /* * we can't insert beyond a zero sequence point */ if (__rq->elevator_sequence <= 0) - backmerge_only = 1; + break; if (__rq->waiting) continue; if (__rq->rq_dev != bh->b_rdev) continue; - if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head) && !backmerge_only) + if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head)) *req = __rq; if (__rq->cmd != rw) continue; @@ -108,7 +143,7 @@ ret = ELEVATOR_BACK_MERGE; *req = __rq; break; - } else if (__rq->sector - count == bh->b_rsector && !backmerge_only) { + } else if (__rq->sector - count == bh->b_rsector) { ret = ELEVATOR_FRONT_MERGE; __rq->elevator_sequence--; *req = __rq; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/block/ll_rw_blk.c linux.21pre5-ac1/drivers/block/ll_rw_blk.c --- linux.21pre5/drivers/block/ll_rw_blk.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/block/ll_rw_blk.c 2003-02-26 23:55:43.000000000 +0000 @@ -360,8 +360,12 @@ { if (q->plugged) { q->plugged = 0; - if (!list_empty(&q->queue_head)) + if (!list_empty(&q->queue_head)) { + if (q->last_request == + blkdev_entry_next_request(&q->queue_head)) + q->last_request = NULL; q->request_fn(q); + } } } @@ -491,6 +495,7 @@ q->plug_tq.routine = &generic_unplug_device; q->plug_tq.data = q; q->plugged = 0; + q->last_request = NULL; /* * These booleans describe the queue properties. We set the * default (and most common) values here. Other drivers can @@ -810,6 +815,7 @@ * inserted at elevator_merge time */ list_add(&req->queue, insert_here); + q->last_request = req; } /* @@ -829,6 +835,9 @@ */ if (q) { list_add(&req->queue, &q->rq[rw].free); + if (q->last_request == req) + q->last_request = NULL; + if (++q->rq[rw].count >= q->batch_requests && waitqueue_active(&q->wait_for_requests[rw])) wake_up(&q->wait_for_requests[rw]); @@ -867,6 +876,7 @@ req->bhtail = next->bhtail; req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; list_del(&next->queue); + q->last_request = req; /* One last thing: we have removed a request, so we now have one less expected IO to complete for accounting purposes. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/cdrom/cdu31a.c linux.21pre5-ac1/drivers/cdrom/cdu31a.c --- linux.21pre5/drivers/cdrom/cdu31a.c 2003-02-27 18:40:01.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/agp/agpgart_be.c linux.21pre5-ac1/drivers/char/agp/agpgart_be.c --- linux.21pre5/drivers/char/agp/agpgart_be.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/agp/agpgart_be.c 2003-03-03 15:15:30.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< +#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.21pre5/drivers/char/cd1865/cdsiolx.h linux.21pre5-ac1/drivers/char/cd1865/cdsiolx.h --- linux.21pre5/drivers/char/cd1865/cdsiolx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/char/cd1865/cdsiolx.h 2003-02-27 00:32:08.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.21pre5/drivers/char/cd1865/Makefile linux.21pre5-ac1/drivers/char/cd1865/Makefile --- linux.21pre5/drivers/char/cd1865/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/cd1865/plx9060.h linux.21pre5-ac1/drivers/char/cd1865/plx9060.h --- linux.21pre5/drivers/char/cd1865/plx9060.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/cd1865/siolx.h linux.21pre5-ac1/drivers/char/cd1865/siolx.h --- linux.21pre5/drivers/char/cd1865/siolx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/Config.in linux.21pre5-ac1/drivers/char/Config.in --- linux.21pre5/drivers/char/Config.in 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/Config.in linux.21pre5-ac1/drivers/char/drm/Config.in --- linux.21pre5/drivers/char/drm/Config.in 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/drm_agpsupport.h linux.21pre5-ac1/drivers/char/drm/drm_agpsupport.h --- linux.21pre5/drivers/char/drm/drm_agpsupport.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_agpsupport.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_bufs.h linux.21pre5-ac1/drivers/char/drm/drm_bufs.h --- linux.21pre5/drivers/char/drm/drm_bufs.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_bufs.h 2003-03-03 15:41:19.000000000 +0000 @@ -136,6 +136,7 @@ } map->offset = (unsigned long)map->handle; if ( map->flags & _DRM_CONTAINS_LOCK ) { + dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ } break; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/char/drm/drm_context.h linux.21pre5-ac1/drivers/char/drm/drm_context.h --- linux.21pre5/drivers/char/drm/drm_context.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_context.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_dma.h linux.21pre5-ac1/drivers/char/drm/drm_dma.h --- linux.21pre5/drivers/char/drm/drm_dma.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_dma.h 2003-03-03 15:41:19.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,18 @@ 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 ); + + dev->vbl_pending = 0; +#endif + /* Before installing handler */ - DRIVER_PREINSTALL(); + DRM(driver_irq_preinstall)(dev); /* Install handler */ ret = request_irq( dev->irq, DRM(dma_service), @@ -551,7 +561,7 @@ } /* After installing handler */ - DRIVER_POSTINSTALL(); + DRM(driver_irq_postinstall)(dev); return 0; } @@ -570,7 +580,7 @@ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - DRIVER_UNINSTALL(); + DRM(driver_irq_uninstall)( dev ); free_irq( irq, dev ); @@ -597,6 +607,142 @@ } } +#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 ); + vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; + 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; + + vblwait.reply.sequence = atomic_read( &dev->vbl_received ); + + spin_lock_irqsave( &dev->vbl_lock, irqflags ); + + /* Check if this task has already scheduled the same signal + * for the same vblank sequence number; nothing to be done in + * that case + */ + list_for_each( ( (struct list_head *) vbl_sig ), &dev->vbl_sigs.head ) { + if (vbl_sig->sequence == vblwait.request.sequence + && vbl_sig->info.si_signo == vblwait.request.signal + && vbl_sig->task == current) + { + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + goto done; + } + } + + if ( dev->vbl_pending >= 100 ) { + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + return -EBUSY; + } + + dev->vbl_pending++; + + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + + if ( !( vbl_sig = kmalloc(sizeof(drm_vbl_sig_t), GFP_KERNEL) ) ) + 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; + + 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; + } + +done: + 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 *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( ( (struct list_head *) vbl_sig ), tmp, &dev->vbl_sigs.head ) { + if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + vbl_sig->info.si_code = vbl_seq; + send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); + + list_del( (struct list_head *) vbl_sig ); + + + kfree( vbl_sig ); + dev->vbl_pending--; + } + } + + 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.21pre5/drivers/char/drm/drm_drv.h linux.21pre5-ac1/drivers/char/drm/drm_drv.h --- linux.21pre5/drivers/char/drm/drm_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/drm_fops.h linux.21pre5-ac1/drivers/char/drm/drm_fops.h --- linux.21pre5/drivers/char/drm/drm_fops.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_fops.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm.h linux.21pre5-ac1/drivers/char/drm/drm.h --- linux.21pre5/drivers/char/drm/drm.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm.h 2003-02-24 19:16:31.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 = 0x40000000 /* 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.21pre5/drivers/char/drm/drm_ioctl.h linux.21pre5-ac1/drivers/char/drm/drm_ioctl.h --- linux.21pre5/drivers/char/drm/drm_ioctl.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_ioctl.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_lock.h linux.21pre5-ac1/drivers/char/drm/drm_lock.h --- linux.21pre5/drivers/char/drm/drm_lock.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_lock.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_memory.h linux.21pre5-ac1/drivers/char/drm/drm_memory.h --- linux.21pre5/drivers/char/drm/drm_memory.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_memory.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_os_linux.h linux.21pre5-ac1/drivers/char/drm/drm_os_linux.h --- linux.21pre5/drivers/char/drm/drm_os_linux.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/char/drm/drm_os_linux.h 2003-02-28 00:48:06.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.21pre5/drivers/char/drm/drmP.h linux.21pre5-ac1/drivers/char/drm/drmP.h --- linux.21pre5/drivers/char/drm/drmP.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drmP.h 2003-03-03 15:41:19.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,13 @@ 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; + unsigned int vbl_pending; +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -725,16 +759,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 +790,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 +920,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.21pre5/drivers/char/drm/drm_proc.h linux.21pre5-ac1/drivers/char/drm/drm_proc.h --- linux.21pre5/drivers/char/drm/drm_proc.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_proc.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_sarea.h linux.21pre5-ac1/drivers/char/drm/drm_sarea.h --- linux.21pre5/drivers/char/drm/drm_sarea.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/drm_stub.h linux.21pre5-ac1/drivers/char/drm/drm_stub.h --- linux.21pre5/drivers/char/drm/drm_stub.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_stub.h 2003-03-03 15:41:19.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.21pre5/drivers/char/drm/drm_vm.h linux.21pre5-ac1/drivers/char/drm/drm_vm.h --- linux.21pre5/drivers/char/drm/drm_vm.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/drm_vm.h 2003-03-03 15:41:19.000000000 +0000 @@ -57,7 +57,7 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused) + int write_access) { #if __REALLY_HAVE_AGP drm_file_t *priv = vma->vm_file->private_data; @@ -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.21pre5/drivers/char/drm/gamma_dma.c linux.21pre5-ac1/drivers/char/drm/gamma_dma.c --- linux.21pre5/drivers/char/drm/gamma_dma.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/gamma_dma.c 2003-02-24 19:16:31.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 long)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.21pre5/drivers/char/drm/gamma_drm.h linux.21pre5-ac1/drivers/char/drm/gamma_drm.h --- linux.21pre5/drivers/char/drm/gamma_drm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/gamma_drv.c linux.21pre5-ac1/drivers/char/drm/gamma_drv.c --- linux.21pre5/drivers/char/drm/gamma_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/gamma_drv.h linux.21pre5-ac1/drivers/char/drm/gamma_drv.h --- linux.21pre5/drivers/char/drm/gamma_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/gamma.h linux.21pre5-ac1/drivers/char/drm/gamma.h --- linux.21pre5/drivers/char/drm/gamma.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i810_dma.c linux.21pre5-ac1/drivers/char/drm/i810_dma.c --- linux.21pre5/drivers/char/drm/i810_dma.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/i810_dma.c 2003-02-24 19:16:40.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; @@ -311,13 +316,12 @@ end = jiffies + (HZ*3); iters++; - if((signed)(end - jiffies) <= 0) { + if(time_before(end, jiffies)) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; } - - for (i = 0 ; i < 2000 ; i++) ; + udelay(1); } out_wait_ring: @@ -405,9 +409,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 +441,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 +453,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 +534,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 +551,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 +571,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 +581,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 +613,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 +700,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 +712,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 +724,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 +749,6 @@ int i; RING_LOCALS; - DRM_DEBUG("swapbuffers\n"); - i810_kernel_lost_context(dev); if (nbox > I810_NR_SAREA_CLIPRECTS) @@ -776,10 +767,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 +791,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 +799,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 +841,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 +908,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 +948,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 +978,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 +1026,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 +1061,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 +1073,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 +1080,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; } @@ -1371,7 +1211,8 @@ data.offset = dev_priv->overlay_offset; data.physical = dev_priv->overlay_physical; - copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data)); + if (copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data))) + return -EFAULT; return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/char/drm/i810_drm.h linux.21pre5-ac1/drivers/char/drm/i810_drm.h --- linux.21pre5/drivers/char/drm/i810_drm.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i810_drv.c linux.21pre5-ac1/drivers/char/drm/i810_drv.c --- linux.21pre5/drivers/char/drm/i810_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i810_drv.h linux.21pre5-ac1/drivers/char/drm/i810_drv.h --- linux.21pre5/drivers/char/drm/i810_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/i810_drv.h 2003-02-24 19:16:40.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); @@ -196,6 +198,7 @@ #define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) #define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) +#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23)) #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/char/drm/i810.h linux.21pre5-ac1/drivers/char/drm/i810.h --- linux.21pre5/drivers/char/drm/i810.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i830_dma.c linux.21pre5-ac1/drivers/char/drm/i830_dma.c --- linux.21pre5/drivers/char/drm/i830_dma.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i830_drm.h linux.21pre5-ac1/drivers/char/drm/i830_drm.h --- linux.21pre5/drivers/char/drm/i830_drm.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i830_drv.c linux.21pre5-ac1/drivers/char/drm/i830_drv.c --- linux.21pre5/drivers/char/drm/i830_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i830_drv.h linux.21pre5-ac1/drivers/char/drm/i830_drv.h --- linux.21pre5/drivers/char/drm/i830_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i830.h linux.21pre5-ac1/drivers/char/drm/i830.h --- linux.21pre5/drivers/char/drm/i830.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/i830_irq.c linux.21pre5-ac1/drivers/char/drm/i830_irq.c --- linux.21pre5/drivers/char/drm/i830_irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/Makefile linux.21pre5-ac1/drivers/char/drm/Makefile --- linux.21pre5/drivers/char/drm/Makefile 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga_dma.c linux.21pre5-ac1/drivers/char/drm/mga_dma.c --- linux.21pre5/drivers/char/drm/mga_dma.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga_drm.h linux.21pre5-ac1/drivers/char/drm/mga_drm.h --- linux.21pre5/drivers/char/drm/mga_drm.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga_drv.c linux.21pre5-ac1/drivers/char/drm/mga_drv.c --- linux.21pre5/drivers/char/drm/mga_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga_drv.h linux.21pre5-ac1/drivers/char/drm/mga_drv.h --- linux.21pre5/drivers/char/drm/mga_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga.h linux.21pre5-ac1/drivers/char/drm/mga.h --- linux.21pre5/drivers/char/drm/mga.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga_state.c linux.21pre5-ac1/drivers/char/drm/mga_state.c --- linux.21pre5/drivers/char/drm/mga_state.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/mga_warp.c linux.21pre5-ac1/drivers/char/drm/mga_warp.c --- linux.21pre5/drivers/char/drm/mga_warp.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/r128_cce.c linux.21pre5-ac1/drivers/char/drm/r128_cce.c --- linux.21pre5/drivers/char/drm/r128_cce.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/r128_drm.h linux.21pre5-ac1/drivers/char/drm/r128_drm.h --- linux.21pre5/drivers/char/drm/r128_drm.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/r128_drv.c linux.21pre5-ac1/drivers/char/drm/r128_drv.c --- linux.21pre5/drivers/char/drm/r128_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/r128_drv.h linux.21pre5-ac1/drivers/char/drm/r128_drv.h --- linux.21pre5/drivers/char/drm/r128_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/r128_drv.h 2003-02-28 00:48:06.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.21pre5/drivers/char/drm/r128.h linux.21pre5-ac1/drivers/char/drm/r128.h --- linux.21pre5/drivers/char/drm/r128.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/r128_state.c linux.21pre5-ac1/drivers/char/drm/r128_state.c --- linux.21pre5/drivers/char/drm/r128_state.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/radeon_cp.c linux.21pre5-ac1/drivers/char/drm/radeon_cp.c --- linux.21pre5/drivers/char/drm/radeon_cp.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/radeon_drm.h linux.21pre5-ac1/drivers/char/drm/radeon_drm.h --- linux.21pre5/drivers/char/drm/radeon_drm.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/radeon_drv.c linux.21pre5-ac1/drivers/char/drm/radeon_drv.c --- linux.21pre5/drivers/char/drm/radeon_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/radeon_drv.h linux.21pre5-ac1/drivers/char/drm/radeon_drv.h --- linux.21pre5/drivers/char/drm/radeon_drv.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/radeon_drv.h 2003-02-26 00:25:54.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,12 +839,17 @@ * Ring control */ -#define radeon_flush_write_combine() mb() +#if defined(__powerpc__) +#define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else +#define radeon_flush_write_combine() wmb() +#warning PCI posting bug +#endif #define RADEON_VERBOSE 0 -#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; +#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ @@ -707,9 +857,10 @@ 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 +871,22 @@ 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 ); \ + 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 */ \ + rmb(); \ + 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 +898,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.21pre5/drivers/char/drm/radeon.h linux.21pre5-ac1/drivers/char/drm/radeon.h --- linux.21pre5/drivers/char/drm/radeon.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/radeon_irq.c linux.21pre5-ac1/drivers/char/drm/radeon_irq.c --- linux.21pre5/drivers/char/drm/radeon_irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/char/drm/radeon_irq.c 2003-02-24 19:16:58.000000000 +0000 @@ -0,0 +1,258 @@ +/* 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) + & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT); + 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 ) + & (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT); + 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<<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.21pre5/drivers/char/drm/radeon_mem.c linux.21pre5-ac1/drivers/char/drm/radeon_mem.c --- linux.21pre5/drivers/char/drm/radeon_mem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/radeon_state.c linux.21pre5-ac1/drivers/char/drm/radeon_state.c --- linux.21pre5/drivers/char/drm/radeon_state.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/radeon_state.c 2003-02-26 00:42:37.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(); } +} - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); +/* Emit 1.2 state + */ +static void radeon_emit_state2( drm_radeon_private_t *dev_priv, + drm_radeon_state_t *state ) +{ + RING_LOCALS; + + 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(); + + 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(); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; - RADEON_WAIT_UNTIL_2D_IDLE(); + 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] ); - 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 ); + 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 ); + 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 ( buf->used ) { - buf_priv->dispatched = 1; - - 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); + int start = prim->start + RADEON_INDEX_PRIM_OFFSET; + int count = (prim->finish - start) / sizeof(u16); - 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 ); - - 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,35 @@ { 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; + BEGIN_RING( 4 ); + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_IDLE(); + ADVANCE_RING(); - 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 ); +#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 +1114,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; @@ -1017,56 +1131,46 @@ return -EINVAL; } - 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(); + DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); - ADVANCE_RING(); + 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 ); - /* Make a copy of the parameters in case we have to update them - * for a multi-pass texture blit. + /* Make a copy of some parameters in case we have to + * update them for a multi-pass texture blit. */ - y = image->y; height = image->height; - data = (u8 *)image->data; + data = (const u8 *)image->data; size = height * blit_width; if ( size > RADEON_MAX_TEXTURE_SIZE ) { - /* Texture image is too large, do a multipass upload */ - ret = -EAGAIN; - - /* Adjust the blit size to fit the indirect buffer */ height = RADEON_MAX_TEXTURE_SIZE / blit_width; size = height * blit_width; - - /* Update the input parameters for next time */ - image->y += height; - image->height -= height; - image->data = (char *)image->data + size; - - if ( copy_to_user( tex->image, image, sizeof(*image) ) ) { - DRM_ERROR( "EFAULT on tex->image\n" ); - return -EFAULT; - } } else if ( size < 4 && size > 0 ) { size = 4; + } else if ( size == 0 ) { + return 0; + } + + 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; } - dwords = size / 4; /* Dispatch the indirect buffer. */ - buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); - + 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 | @@ -1080,7 +1184,7 @@ buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); buffer[3] = 0xffffffff; buffer[4] = 0xffffffff; - buffer[5] = (y << 16) | image->x; + buffer[5] = (image->y << 16) | image->x; buffer[6] = (height << 16) | image->width; buffer[7] = dwords; @@ -1112,30 +1216,34 @@ buf->pid = current->pid; buf->used = (dwords + 8) * sizeof(u32); - buf_priv->discard = 1; radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); + radeon_cp_discard_buffer( dev, buf ); + + /* 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 +1266,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 +1365,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 +1374,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 +1387,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 +1404,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 +1423,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 +1434,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 +1476,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 +1513,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 +1537,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 +1579,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 +1599,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 +1627,7 @@ radeon_cp_dispatch_stipple( dev, mask ); + COMMIT_RING(); return 0; } @@ -1413,7 +1639,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 +1664,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 +1685,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 +1700,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.21pre5/drivers/char/drm/sis_drm.h linux.21pre5-ac1/drivers/char/drm/sis_drm.h --- linux.21pre5/drivers/char/drm/sis_drm.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/sis_drv.c linux.21pre5-ac1/drivers/char/drm/sis_drv.c --- linux.21pre5/drivers/char/drm/sis_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/sis_ds.c linux.21pre5-ac1/drivers/char/drm/sis_ds.c --- linux.21pre5/drivers/char/drm/sis_ds.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/drm/sis_ds.c 2003-02-24 19:16:58.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.21pre5/drivers/char/drm/sis.h linux.21pre5-ac1/drivers/char/drm/sis.h --- linux.21pre5/drivers/char/drm/sis.h 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm/tdfx_drv.c linux.21pre5-ac1/drivers/char/drm/tdfx_drv.c --- linux.21pre5/drivers/char/drm/tdfx_drv.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm-4.0/agpsupport.c linux.21pre5-ac1/drivers/char/drm-4.0/agpsupport.c --- linux.21pre5/drivers/char/drm-4.0/agpsupport.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/drm-4.0/tdfx_drv.c linux.21pre5-ac1/drivers/char/drm-4.0/tdfx_drv.c --- linux.21pre5/drivers/char/drm-4.0/tdfx_drv.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/epca.c linux.21pre5-ac1/drivers/char/epca.c --- linux.21pre5/drivers/char/epca.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/genrtc.c linux.21pre5-ac1/drivers/char/genrtc.c --- linux.21pre5/drivers/char/genrtc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/char/ipmi/ipmi_kcs_sm.c linux.21pre5-ac1/drivers/char/ipmi/ipmi_kcs_sm.c --- linux.21pre5/drivers/char/ipmi/ipmi_kcs_sm.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/ipmi/ipmi_kcs_sm.c 2003-02-21 15:41:39.000000000 +0000 @@ -220,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; @@ -331,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 @@ -398,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.21pre5/drivers/char/ipmi/ipmi_msghandler.c linux.21pre5-ac1/drivers/char/ipmi/ipmi_msghandler.c --- linux.21pre5/drivers/char/ipmi/ipmi_msghandler.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/Makefile linux.21pre5-ac1/drivers/char/Makefile --- linux.21pre5/drivers/char/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/Makefile 2003-01-28 16:35:25.000000000 +0000 @@ -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.21pre5/drivers/char/mem.c linux.21pre5-ac1/drivers/char/mem.c --- linux.21pre5/drivers/char/mem.c 2003-02-27 18:39:53.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/mwave/mwavedd.c linux.21pre5-ac1/drivers/char/mwave/mwavedd.c --- linux.21pre5/drivers/char/mwave/mwavedd.c 2003-02-27 18:39:56.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/n_hdlc.c linux.21pre5-ac1/drivers/char/n_hdlc.c --- linux.21pre5/drivers/char/n_hdlc.c 2003-02-27 18:39:54.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/nwflash.c linux.21pre5-ac1/drivers/char/nwflash.c --- linux.21pre5/drivers/char/nwflash.c 2003-02-27 18:39:54.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/pc_keyb.c linux.21pre5-ac1/drivers/char/pc_keyb.c --- linux.21pre5/drivers/char/pc_keyb.c 2003-02-27 18:39:54.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/char/raw.c linux.21pre5-ac1/drivers/char/raw.c --- linux.21pre5/drivers/char/raw.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/char/raw.c 2003-02-27 00:06:05.000000000 +0000 @@ -86,12 +86,6 @@ filp->f_op = &raw_ctl_fops; return 0; } - - if (!filp->f_iobuf) { - err = alloc_kiovec(1, &filp->f_iobuf); - if (err) - return err; - } down(&raw_devices[minor].mutex); /* @@ -292,7 +286,6 @@ size_t size, loff_t *offp) { struct kiobuf * iobuf; - int new_iobuf; int err = 0; unsigned long blocknr, blocks; size_t transferred; @@ -311,18 +304,10 @@ minor = MINOR(filp->f_dentry->d_inode->i_rdev); - new_iobuf = 0; - iobuf = filp->f_iobuf; - if (test_and_set_bit(0, &filp->f_iobuf_lock)) { - /* - * A parallel read/write is using the preallocated iobuf - * so just run slow and allocate a new one. - */ - err = alloc_kiovec(1, &iobuf); - if (err) - goto out; - new_iobuf = 1; - } + err = alloc_kiovec(1, &iobuf); + if (err) + return err; + dev = to_kdev_t(raw_devices[minor].binding->bd_dev); sector_size = raw_devices[minor].sector_size; @@ -395,10 +380,6 @@ } out_free: - if (!new_iobuf) - clear_bit(0, &filp->f_iobuf_lock); - else - free_kiovec(1, &iobuf); - out: + free_kiovec(1, &iobuf); return err; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/char/serial.c linux.21pre5-ac1/drivers/char/serial.c --- linux.21pre5/drivers/char/serial.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/hotplug/Config.in linux.21pre5-ac1/drivers/hotplug/Config.in --- linux.21pre5/drivers/hotplug/Config.in 2003-02-27 18:40:08.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/hotplug/Makefile linux.21pre5-ac1/drivers/hotplug/Makefile --- linux.21pre5/drivers/hotplug/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/hotplug/tp600.c linux.21pre5-ac1/drivers/hotplug/tp600.c --- linux.21pre5/drivers/hotplug/tp600.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/hotplug/tp600.h linux.21pre5-ac1/drivers/hotplug/tp600.h --- linux.21pre5/drivers/hotplug/tp600.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/i2c/i2c-proc.c linux.21pre5-ac1/drivers/i2c/i2c-proc.c --- linux.21pre5/drivers/i2c/i2c-proc.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/i2c/i2c-proc.c 2003-03-03 15:20:09.000000000 +0000 @@ -729,7 +729,7 @@ || ((address_data-> ignore_range[i] == - SENSORS_ANY_I2C_BUS) & !is_isa)) + SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr >= address_data->ignore_range[i + 1]) && (addr <= address_data->ignore_range[i + 2])) { #ifdef DEBUG @@ -818,7 +818,7 @@ i += 2) { if (((adapter_id == address_data->probe[i]) || ((address_data-> - probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) + probe[i] == SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr == address_data->probe[i + 1])) { #ifdef DEBUG printk @@ -835,7 +835,7 @@ ((adapter_id == address_data->probe_range[i]) || ((address_data->probe_range[i] == - SENSORS_ANY_I2C_BUS) & !is_isa)) + SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr >= address_data->probe_range[i + 1]) && (addr <= address_data->probe_range[i + 2])) { found = 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/Config.in linux.21pre5-ac1/drivers/ide/Config.in --- linux.21pre5/drivers/ide/Config.in 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/Config.in 2003-02-05 17:39:46.000000000 +0000 @@ -61,7 +61,6 @@ 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.21pre5/drivers/ide/ide.c linux.21pre5-ac1/drivers/ide/ide.c --- linux.21pre5/drivers/ide/ide.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide.c 2003-03-03 16:37:27.000000000 +0000 @@ -217,6 +217,8 @@ EXPORT_SYMBOL(idetape); EXPORT_SYMBOL(idescsi); +extern ide_driver_t idedefault_driver; + /* * Do not even *think* about calling this! */ @@ -273,6 +275,8 @@ drive->max_failures = IDE_DEFAULT_MAX_FAILURES; drive->using_dma = 0; drive->is_flash = 0; + drive->driver = &idedefault_driver; + setup_driver_defaults(drive); init_waitqueue_head(&drive->wqueue); } } @@ -350,9 +354,7 @@ { if (!drive->present) return 0; - if (drive->driver != NULL) - return DRIVER(drive)->capacity(drive); - return 0; + return DRIVER(drive)->capacity(drive); } EXPORT_SYMBOL(current_capacity); @@ -486,7 +488,7 @@ drive->part[p].nr_sects = 0; }; - if (DRIVER(drive) && DRIVER(drive)->revalidate) + if (DRIVER(drive)->revalidate) DRIVER(drive)->revalidate(drive); drive->busy = 0; @@ -555,9 +557,9 @@ if ((drive = get_info_ptr(inode->i_rdev)) == NULL) return -ENXIO; - if (drive->driver == NULL) + if (drive->driver == &idedefault_driver) ide_driver_module(1); - if (drive->driver == NULL) { + if (drive->driver == &idedefault_driver) { if (drive->media == ide_disk) (void) request_module("ide-disk"); if (drive->scsi) @@ -575,7 +577,7 @@ while (drive->busy) sleep_on(&drive->wqueue); drive->usage++; - if (drive->driver != NULL && !drive->dead) + if (!drive->dead) return DRIVER(drive)->open(inode, filp, drive); printk(KERN_WARNING "%s: driver not present\n", drive->name); drive->usage--; @@ -592,8 +594,7 @@ if ((drive = get_info_ptr(inode->i_rdev)) != NULL) { drive->usage--; - if (drive->driver != NULL) - DRIVER(drive)->release(inode, file, drive); + DRIVER(drive)->release(inode, file, drive); } return 0; } @@ -666,7 +667,7 @@ continue; if (drive->busy || drive->usage) goto abort; - if (drive->driver != NULL && DRIVER(drive)->shutdown(drive)) + if (DRIVER(drive)->shutdown(drive)) goto abort; } hwif->present = 0; @@ -679,8 +680,7 @@ drive = &hwif->drives[unit]; if (!drive->present) continue; - if (drive->driver != NULL) - DRIVER(drive)->cleanup(drive); + DRIVER(drive)->cleanup(drive); minor = drive->select.b.unit << PARTN_BITS; for (p = 0; p < (1<part[p].nr_sects > 0) { @@ -1022,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) @@ -1044,33 +1079,78 @@ setting->div_factor = div_factor; setting->data = data; setting->set = set; + setting->next = *p; - if (drive->driver) + if (drive->driver != &idedefault_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; @@ -1080,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; @@ -1095,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; @@ -1157,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) { @@ -1211,9 +1338,9 @@ static int set_using_dma (ide_drive_t *drive, int arg) { - if (!drive->driver || !DRIVER(drive)->supports_dma) + if (!DRIVER(drive)->supports_dma) return -EPERM; - if (!drive->id || !(drive->id->capability & 1)) + if (!(drive->id->capability & 1)) return -EPERM; if (HWIF(drive)->ide_dma_check == NULL) return -EPERM; @@ -1259,11 +1386,9 @@ drive->scsi = 0; return 0; } - if (drive->driver != NULL) { - if (DRIVER(drive)->cleanup(drive)) { - drive->scsi = 0; - return 0; - } + if (DRIVER(drive)->cleanup(drive)) { + drive->scsi = 0; + return 0; } drive->scsi = (u8) arg; ide_attach_drive(drive); @@ -1320,13 +1445,13 @@ { if (!drive->present || drive->busy || drive->usage || drive->dead) goto abort; - if (drive->driver != NULL && DRIVER(drive)->cleanup(drive)) + if (DRIVER(drive)->cleanup(drive)) goto abort; strncpy(drive->driver_req, driver, 9); ide_driver_module(0); drive->driver_req[0] = 0; ide_driver_module(0); - if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver)) + if (!strcmp(DRIVER(drive)->name, driver)) return 0; abort: return 1; @@ -1386,7 +1511,12 @@ } #endif /* CONFIG_BLK_DEV_IDETAPE */ default: + { + extern int idedefault_attach(ide_drive_t *drive); + if(idedefault_attach(drive)) + printk(KERN_CRIT "ide: failed to attach default driver.\n"); return 1; + } } return 0; } @@ -1408,16 +1538,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) { @@ -1471,7 +1607,7 @@ case HDIO_GET_IDENTITY: if (MINOR(inode->i_rdev) & PARTN_MASK) return -EINVAL; - if (drive->id == NULL) + if (drive->id_read == 0) return -ENOMSG; if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142)) return -EFAULT; @@ -1530,8 +1666,6 @@ return 0; case HDIO_SET_NICE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (drive->driver == NULL) - return -EPERM; if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) return -EPERM; drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; @@ -1598,8 +1732,7 @@ return 0; default: - if (drive->driver != NULL) - return DRIVER(drive)->ioctl(drive, inode, file, cmd, arg); + return DRIVER(drive)->ioctl(drive, inode, file, cmd, arg); return -EPERM; } } @@ -1610,9 +1743,7 @@ if ((drive = get_info_ptr(i_rdev)) == NULL) return -ENODEV; - if (drive->driver != NULL) - return DRIVER(drive)->media_change(drive); - return 0; + return DRIVER(drive)->media_change(drive); } /* @@ -2168,6 +2299,7 @@ void __init ide_init_builtin_subdrivers (void) { + idedefault_init(); #ifdef CONFIG_BLK_DEV_IDEDISK (void) idedisk_init(); #endif /* CONFIG_BLK_DEV_IDEDISK */ @@ -2265,8 +2397,7 @@ static int default_shutdown(ide_drive_t *drive) { - if (drive->usage || drive->busy || - drive->driver == NULL || DRIVER(drive)->busy) { + if (drive->usage || drive->busy || DRIVER(drive)->busy) { return 1; } drive->dead = 1; @@ -2394,6 +2525,9 @@ ide_drive_t *ide_scan_devices (u8 media, const char *name, ide_driver_t *driver, int n) { unsigned int unit, index, i; + + if(driver == NULL) /* No driver is actually &idedefault_driver */ + driver = &idedefault_driver; for (index = 0, i = 0; index < MAX_HWIFS; ++index) { ide_hwif_t *hwif = &ide_hwifs[index]; @@ -2418,14 +2552,17 @@ { unsigned long flags; + BUG_ON(drive->driver == NULL); + spin_lock_irqsave(&io_request_lock, flags); if (version != IDE_SUBDRIVER_VERSION || !drive->present || - drive->driver != NULL || drive->busy || drive->usage) { + drive->driver != &idedefault_driver || drive->busy || drive->usage) { spin_unlock_irqrestore(&io_request_lock, flags); return 1; } drive->driver = driver; setup_driver_defaults(drive); + printk("%s: attached %s driver.\n", drive->name, driver->name); spin_unlock_irqrestore(&io_request_lock, flags); if (drive->autotune != 2) { /* DMA timings and setup moved to ide-probe.c */ @@ -2451,8 +2588,7 @@ unsigned long flags; spin_lock_irqsave(&io_request_lock, flags); - if (drive->usage || drive->busy || - drive->driver == NULL || DRIVER(drive)->busy) { + if (drive->usage || drive->busy || DRIVER(drive)->busy) { spin_unlock_irqrestore(&io_request_lock, flags); return 1; } @@ -2464,7 +2600,8 @@ ide_remove_proc_entries(drive->proc, generic_subdriver_entries); #endif auto_remove_settings(drive); - drive->driver = NULL; + drive->driver = &idedefault_driver; + setup_driver_defaults(drive); spin_unlock_irqrestore(&io_request_lock, flags); return 0; } @@ -2574,14 +2711,11 @@ /* set the drive to standby */ printk("%s ", drive->name); if (event != SYS_RESTART) - if (drive->driver != NULL && DRIVER(drive)->standby(drive)) - continue; + if (DRIVER(drive)->standby(drive)) + continue; - if (drive->driver != NULL) - { - DRIVER(drive)->cleanup(drive); - continue; - } + DRIVER(drive)->cleanup(drive); + continue; } } printk("\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-cd.c linux.21pre5-ac1/drivers/ide/ide-cd.c --- linux.21pre5/drivers/ide/ide-cd.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-cd.c 2003-03-02 22:55:14.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 */ @@ -2732,11 +2729,9 @@ * ACER50 (and others?) require the full spec length mode sense * page capabilities size, but older drives break. */ - if (drive->id) { - if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || - !strcmp(drive->id->model, "WPI CDS-32X"))) - size -= sizeof(cap->pad); - } + if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || + !strcmp(drive->id->model, "WPI CDS-32X"))) + size -= sizeof(cap->pad); /* we have to cheat a little here. the packet will eventually * be queued with ide_cdrom_packet(), which extracts the @@ -2819,7 +2814,7 @@ } /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ - if (drive->id && !drive->id->model[0] && + if (!drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) { CDROM_STATE_FLAGS(drive)->current_speed = (((unsigned int)cap.curspeed) + (176/2)) / 176; @@ -2903,11 +2898,8 @@ CDROM_CONFIG_FLAGS(drive)->no_doorlock = 0; #endif - if (drive->id != NULL) - CDROM_CONFIG_FLAGS(drive)->drq_interrupt = - ((drive->id->config & 0x0060) == 0x20); - else - CDROM_CONFIG_FLAGS(drive)->drq_interrupt = 0; + CDROM_CONFIG_FLAGS(drive)->drq_interrupt = + ((drive->id->config & 0x0060) == 0x20); CDROM_CONFIG_FLAGS(drive)->is_changer = 0; CDROM_CONFIG_FLAGS(drive)->cd_r = 0; @@ -2923,16 +2915,15 @@ /* limit transfer size per interrupt. */ CDROM_CONFIG_FLAGS(drive)->limit_nframes = 0; - if (drive->id != NULL) { - /* a testament to the nice quality of Samsung drives... */ - if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430")) - CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; - else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432")) - CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; - /* the 3231 model does not support the SET_CD_SPEED command */ - else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231")) - cdi->mask |= CDC_SELECT_SPEED; - } + + /* a testament to the nice quality of Samsung drives... */ + if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430")) + CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; + else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432")) + CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; + /* the 3231 model does not support the SET_CD_SPEED command */ + else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231")) + cdi->mask |= CDC_SELECT_SPEED; #if ! STANDARD_ATAPI /* by default Sanyo 3 CD changer support is turned off and @@ -2945,54 +2936,47 @@ CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 0; CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 0; - if (drive->id != NULL) { - if (strcmp (drive->id->model, "V003S0DS") == 0 && - drive->id->fw_rev[4] == '1' && - drive->id->fw_rev[6] <= '2') { - /* Vertos 300. - Some versions of this drive like to talk BCD. */ - CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1; - } - - else if (strcmp (drive->id->model, "V006E0DS") == 0 && - drive->id->fw_rev[4] == '1' && - drive->id->fw_rev[6] <= '2') { - /* Vertos 600 ESD. */ - CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1; - } - - else if (strcmp(drive->id->model, - "NEC CD-ROM DRIVE:260") == 0 && - strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */ - /* Old NEC260 (not R). - This drive was released before the 1.2 version - of the spec. */ - CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->nec260 = 1; - } - - else if (strcmp(drive->id->model, "WEARNES CDD-120") == 0 && - strncmp(drive->id->fw_rev, "A1.1", 4) == 0) { /* FIXME */ - /* Wearnes */ - CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1; - CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1; - } - - /* Sanyo 3 CD changer uses a non-standard command - for CD changing */ - else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) || - (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) || - (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) { - /* uses CD in slot 0 when value is set to 3 */ - cdi->sanyo_slot = 3; - } - - + if (strcmp (drive->id->model, "V003S0DS") == 0 && + drive->id->fw_rev[4] == '1' && + drive->id->fw_rev[6] <= '2') { + /* Vertos 300. + Some versions of this drive like to talk BCD. */ + CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1; + } + else if (strcmp (drive->id->model, "V006E0DS") == 0 && + drive->id->fw_rev[4] == '1' && + drive->id->fw_rev[6] <= '2') { + /* Vertos 600 ESD. */ + CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1; + } + + else if (strcmp(drive->id->model, + "NEC CD-ROM DRIVE:260") == 0 && + strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */ + /* Old NEC260 (not R). + This drive was released before the 1.2 version + of the spec. */ + CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->nec260 = 1; + } + else if (strcmp(drive->id->model, "WEARNES CDD-120") == 0 && + strncmp(drive->id->fw_rev, "A1.1", 4) == 0) { /* FIXME */ + /* Wearnes */ + CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1; + CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1; + } + /* Sanyo 3 CD changer uses a non-standard command + for CD changing */ + else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) || + (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) || + (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) { + /* uses CD in slot 0 when value is set to 3 */ + cdi->sanyo_slot = 3; } #endif /* not STANDARD_ATAPI */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-default.c linux.21pre5-ac1/drivers/ide/ide-default.c --- linux.21pre5/drivers/ide/ide-default.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/ide/ide-default.c 2003-03-03 15:46:33.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * ide-default - Driver for unbound ide devices + * + * This provides a clean way to bind a device to default operations + * by having an actual driver class that rather than special casing + * "no driver" all over the IDE code + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IDEDEFAULT_VERSION "0.9.newide" +/* + * Driver initialization. + */ + +static void idedefault_setup (ide_drive_t *drive) +{ +} + +int idedefault_init (void); +int idedefault_attach(ide_drive_t *drive); + +/* + * IDE subdriver functions, registered with ide.c + */ + +ide_driver_t idedefault_driver = { + name: "ide-default", + version: IDEDEFAULT_VERSION, + media: 0, + busy: 0, + supports_dma: 1, + supports_dsc_overlap: 0, + init: idedefault_init, + attach: idedefault_attach, +}; + +static ide_module_t idedefault_module = { + IDE_DRIVER_MODULE, + idedefault_init, + &idedefault_driver, + NULL +}; + +int idedefault_attach (ide_drive_t *drive) +{ + int ret = 0; + MOD_INC_USE_COUNT; + if (ide_register_subdriver(drive, + &idedefault_driver, IDE_SUBDRIVER_VERSION)) { + printk(KERN_ERR "ide-default: %s: Failed to register the " + "driver with ide.c\n", drive->name); + ret = 1; + goto bye_game_over; + } + DRIVER(drive)->busy++; + idedefault_setup(drive); + DRIVER(drive)->busy--; + +bye_game_over: + MOD_DEC_USE_COUNT; + return ret; +} + +MODULE_DESCRIPTION("IDE Default Driver"); + +int idedefault_init (void) +{ + ide_register_module(&idedefault_module); + return 0; +} + +module_init(idedefault_init); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-disk.c linux.21pre5-ac1/drivers/ide/ide-disk.c --- linux.21pre5/drivers/ide/ide-disk.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-disk.c 2003-03-03 00:03:32.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; } @@ -1216,7 +1242,7 @@ } } else if (s->b.set_multmode) { s->b.set_multmode = 0; - if (drive->id && drive->mult_req > drive->id->max_multsect) + if (drive->mult_req > drive->id->max_multsect) drive->mult_req = drive->id->max_multsect; if (!IS_PDC4030_DRIVE) { ide_task_t args; @@ -1301,7 +1327,7 @@ char *out = page; int len; - if (drive->id) + if (drive->id_read) len = sprintf(out,"%i\n", drive->id->buf_size / 2); else len = sprintf(out,"(none)\n"); @@ -1435,7 +1461,7 @@ { if (drive->suspend_reset) return 1; - + ide_cacheflush_p(drive); return call_idedisk_suspend(drive, 0); } @@ -1573,7 +1599,7 @@ idedisk_add_settings(drive); - if (id == NULL) + if (drive->id_read == 0) return; /* @@ -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.21pre5/drivers/ide/ide-dma.c linux.21pre5-ac1/drivers/ide/ide-dma.c --- linux.21pre5/drivers/ide/ide-dma.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-dma.c 2003-03-02 22:57:21.000000000 +0000 @@ -490,7 +490,7 @@ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); - if (id && (id->capability & 1) && hwif->autodma) { + if ((id->capability & 1) && hwif->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) return hwif->ide_dma_off(drive); @@ -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.21pre5/drivers/ide/ide-floppy.c linux.21pre5-ac1/drivers/ide/ide-floppy.c --- linux.21pre5/drivers/ide/ide-floppy.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/ide/ide-geometry.c linux.21pre5-ac1/drivers/ide/ide-geometry.c --- linux.21pre5/drivers/ide/ide-geometry.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/ide/ide-io.c linux.21pre5-ac1/drivers/ide/ide-io.c --- linux.21pre5/drivers/ide/ide-io.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-io.c 2003-03-03 15:45:22.000000000 +0000 @@ -331,10 +331,7 @@ hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); } if (rq->errors >= ERROR_MAX) { - if (drive->driver != NULL) - DRIVER(drive)->end_request(drive, 0); - else - ide_end_request(drive, 0); + DRIVER(drive)->end_request(drive, 0); } else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -363,14 +360,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); @@ -432,13 +426,10 @@ s->b.set_tune = 0; if (HWIF(drive)->tuneproc != NULL) HWIF(drive)->tuneproc(drive, drive->tune_req); - } else if (drive->driver != NULL) { - return DRIVER(drive)->special(drive); - } else if (s->all) { - printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, s->all); - s->all = 0; + return ide_stopped; } - return ide_stopped; + else + return DRIVER(drive)->special(drive); } EXPORT_SYMBOL(do_special); @@ -621,18 +612,11 @@ default: break; } - if (drive->driver != NULL) { - return (DRIVER(drive)->do_request(drive, rq, block)); - } - printk(KERN_WARNING "%s: media type %d not supported\n", drive->name, drive->media); - goto kill_rq; + return (DRIVER(drive)->do_request(drive, rq, block)); } return do_special(drive); kill_rq: - if (drive->driver != NULL) - DRIVER(drive)->end_request(drive, 0); - else - ide_end_request(drive, 0); + DRIVER(drive)->end_request(drive, 0); return ide_stopped; } @@ -1003,8 +987,9 @@ if (drive->waiting_for_dma) { startstop = ide_stopped; ide_dma_timeout_retry(drive); - } else + } else { startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); + } } set_recovery_timer(hwif); drive->service_time = jiffies - drive->service_start; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-iops.c linux.21pre5-ac1/drivers/ide/ide-iops.c --- linux.21pre5/drivers/ide/ide-iops.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-iops.c 2003-03-03 01:11:42.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; @@ -766,13 +856,12 @@ local_irq_enable(); local_irq_restore(flags); ide_fix_driveid(id); - if (id) { - drive->id->dma_ultra = id->dma_ultra; - drive->id->dma_mword = id->dma_mword; - drive->id->dma_1word = id->dma_1word; - /* anything more ? */ - kfree(id); - } + + drive->id->dma_ultra = id->dma_ultra; + drive->id->dma_mword = id->dma_mword; + drive->id->dma_1word = id->dma_1word; + /* anything more ? */ + kfree(id); return 1; #endif @@ -959,7 +1048,7 @@ hwgroup->expiry = expiry; hwgroup->timer.expires = jiffies + timeout; add_timer(&hwgroup->timer); - hwif->OUTBSYNC(cmd, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG); /* Drive takes 400nS to respond, we must avoid the IRQ being serviced before that. @@ -1090,8 +1179,7 @@ void pre_reset (ide_drive_t *drive) { - if (drive->driver != NULL) - DRIVER(drive)->pre_reset(drive); + DRIVER(drive)->pre_reset(drive); if (!drive->keep_settings) { if (drive->using_dma) { @@ -1240,6 +1328,8 @@ u8 unmask = drive->unmask; # endif + /* FIXME: seems racey check lock use */ + if (HWGROUP(drive)->handler != NULL) { unsigned long flags; spin_lock_irqsave(&io_request_lock, flags); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-probe.c linux.21pre5-ac1/drivers/ide/ide-probe.c --- linux.21pre5/drivers/ide/ide-probe.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-probe.c 2003-03-03 00:03:12.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,45 @@ #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 + */ + +static void generic_id(ide_drive_t *drive) +{ + 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; +} + +/** + * 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 */ -inline int drive_is_flashcard (ide_drive_t *drive) + +static inline int drive_is_flashcard (ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -88,6 +113,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); @@ -95,16 +130,12 @@ struct hd_driveid *id; /* called with interrupts disabled! */ - id = drive->id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); - if (!id) { - printk(KERN_WARNING "(ide-probe::do_identify) " - "Out of memory.\n"); - goto err_kmalloc; - } + id = drive->id; /* read 512 bytes of id info */ hwif->ata_input_data(drive, id, SECTOR_WORDS); - + drive->id_read = 1; local_irq_enable(); + ide_fix_driveid(id); if (!drive->forced_lun) @@ -207,6 +238,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 +246,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; @@ -228,21 +265,25 @@ err_misc: kfree(id); -err_kmalloc: drive->present = 0; 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 +298,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 +357,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 +416,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 +436,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 +552,90 @@ } } -/* - * 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 * - * Returns: 0 no device was found - * 1 device was found (note: drive->present might still be 0) + * 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) */ + 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->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 */ + /* + * In order to keep things simple we have an id + * block for all drives at all times. If the device + * is pre ATA or refuses ATA/ATAPI identify we + * will add faked data to this. + * + * Also note that 0 everywhere means "can't do X" + */ + + drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL); + drive->id_read = 0; + if(drive->id == NULL) + { + printk(KERN_ERR "ide: out of memory for id data.\n"); 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 */ - drive->present = 0; + } + memset(drive->id, 0, SECTOR_WORDS * 4); + strcpy(drive->id->model, "UNKNOWN"); + + /* skip probing? */ + 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 (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_read) { + 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 */ + printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name); + drive->present = 0; + } + } + /* drive was found */ } - /* drive was found */ - return 1; + if(!drive->present) + return 0; + /* The drive wasn't being helpful. Add generic info only */ + if(!drive->id_read) + generic_id(drive); + 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 +687,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 +781,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 +801,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 +848,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.21pre5/drivers/ide/ide-proc.c linux.21pre5-ac1/drivers/ide/ide-proc.c --- linux.21pre5/drivers/ide/ide-proc.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-proc.c 2003-03-03 01:14:45.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 = (unsigned short *)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; @@ -598,11 +625,8 @@ ide_driver_t *driver = (ide_driver_t *) drive->driver; int len; - if (!driver) - len = sprintf(page, "(none)\n"); - else - len = sprintf(page,"%llu\n", - (u64) ((ide_driver_t *)drive->driver)->capacity(drive)); + len = sprintf(page,"%llu\n", + (u64) ((ide_driver_t *)drive->driver)->capacity(drive)); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } @@ -647,11 +671,8 @@ ide_driver_t *driver = (ide_driver_t *) drive->driver; int len; - if (!driver) - len = sprintf(page, "(none)\n"); - else - len = sprintf(page, "%s version %s\n", - driver->name, driver->version); + len = sprintf(page, "%s version %s\n", + driver->name, driver->version); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } @@ -803,8 +824,7 @@ ide_driver_t *driver = drive->driver; if (drive->proc) { - if (driver) - ide_remove_proc_entries(drive->proc, driver->proc); + ide_remove_proc_entries(drive->proc, driver->proc); ide_remove_proc_entries(drive->proc, generic_drive_entries); remove_proc_entry(drive->name, proc_ide_root); remove_proc_entry(drive->name, hwif->proc); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-tape.c linux.21pre5-ac1/drivers/ide/ide-tape.c --- linux.21pre5/drivers/ide/ide-tape.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-tape.c 2003-03-03 00:04:12.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); @@ -5841,15 +5838,16 @@ * * 0 If this tape driver is not currently supported by us. */ -static int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id) +static int idetape_identify_device (ide_drive_t *drive) { struct idetape_id_gcw gcw; + struct hd_driveid *id = drive->id; #if IDETAPE_DEBUG_INFO unsigned short mask,i; #endif /* IDETAPE_DEBUG_INFO */ - if (!id) - return 0; + if(drive->id_read == 0) + return 1; *((unsigned short *) &gcw) = id->config; @@ -6513,7 +6511,7 @@ MOD_INC_USE_COUNT; - if (!idetape_identify_device(drive, drive->id)) { + if (idetape_identify_device(drive)) { printk(KERN_ERR "ide-tape: %s: not supported by this " "version of ide-tape\n", drive->name); ret = 1; @@ -6624,7 +6622,7 @@ return -EBUSY; } do { - if (!idetape_identify_device(drive, drive->id)) { + if (!idetape_identify_device(drive)) { printk(KERN_ERR "ide-tape: %s: not supported by this " "version of ide-tape\n", drive->name); continue; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/ide-taskfile.c linux.21pre5-ac1/drivers/ide/ide-taskfile.c --- linux.21pre5/drivers/ide/ide-taskfile.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/ide/ide-timing.h linux.21pre5-ac1/drivers/ide/ide-timing.h --- linux.21pre5/drivers/ide/ide-timing.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ide-timing.h 2003-02-27 00:32:08.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.21pre5/drivers/ide/Makefile linux.21pre5-ac1/drivers/ide/Makefile --- linux.21pre5/drivers/ide/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/Makefile 2003-03-03 00:46:52.000000000 +0000 @@ -29,7 +29,7 @@ # Core IDE code - must come before legacy -obj-$(CONFIG_BLK_DEV_IDE) += ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o +obj-$(CONFIG_BLK_DEV_IDE) += ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o ide-default.o obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/aec62xx.c linux.21pre5-ac1/drivers/ide/pci/aec62xx.c --- linux.21pre5/drivers/ide/pci/aec62xx.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/aec62xx.c 2003-03-02 23:04:28.000000000 +0000 @@ -324,7 +324,7 @@ ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -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.21pre5/drivers/ide/pci/alim15x3.c linux.21pre5-ac1/drivers/ide/pci/alim15x3.c --- linux.21pre5/drivers/ide/pci/alim15x3.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/alim15x3.c 2003-03-03 15:22:17.000000000 +0000 @@ -300,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; @@ -328,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); @@ -514,10 +515,10 @@ drive->init_speed = 0; - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { + if ((id->capability & 1) != 0 && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) - goto fast_ata_pio; + goto ata_pio; if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { if (id->dma_ultra & hwif->ultra_mask) { /* Force if Capable UltraDMA */ @@ -539,12 +540,12 @@ if (!config_chipset_for_dma(drive)) goto no_dma_set; } else { - goto fast_ata_pio; + goto ata_pio; } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + } else { +ata_pio: + hwif->tuneproc(drive, 255); no_dma_set: - hwif->tuneproc(drive, 5); return hwif->ide_dma_off_quietly(drive); } return hwif->ide_dma_on(drive); @@ -752,6 +753,8 @@ return; } + hwif->atapi_dma = 1; + if (m5229_revision > 0x20) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/amd74xx.c linux.21pre5-ac1/drivers/ide/pci/amd74xx.c --- linux.21pre5/drivers/ide/pci/amd74xx.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/amd74xx.c 2003-03-03 16:52:08.000000000 +0000 @@ -1,411 +1,441 @@ /* - * linux/drivers/ide/pci/amd74xx.c Version 0.05 June 9, 2000 + * Version 2.10 * - * 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. * - * Documentation - * Publically available from AMD + * Copyright (c) 2000-2002 Vojtech Pavlik * - * Errata - * AMD 756: Errata #1 - * Single word DMA is not supported by old AMD IDE devices - * - * AMD 766: Errata #15 - * IDE may hang if prefetch is enabled. The BIOS does not enable - * prefetch. - * - * AMD 766: Errata #19 - * Poor UDMA100 performance - * - * AMD 761: Errata #55 - * AMD 762: Errata #56 - * A problem exists with IDE prefetch and the last page before the - * 640K boundary. Users hitting this problem can add a PS/2 mouse - * to the system, causing that page to become an EBDA page and not - * used by the OS. A full work around is under investigation. - * BIOS updates should also avoid this. + * 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.10"); + 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); + + pci_write_config_byte(dev, AMD_8BIT_TIMING + (1 - (dn >> 1)), + ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); + 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; + } - return mode; + 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); + + T = 1000000000 / amd_clock; + UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); + + 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); + } + + if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; - pio_timing |= (0x03 << drive->dn); + amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); - 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); + if (!drive->init_speed) + drive->init_speed = speed; + drive->current_speed = speed; - return (ide_config_drive_speed(drive, 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); + pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); + amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 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; } -#endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */ + + 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; + } + +/* + * 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; @@ -417,13 +447,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) @@ -439,8 +471,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.21pre5/drivers/ide/pci/amd74xx.h linux.21pre5-ac1/drivers/ide/pci/amd74xx.h --- linux.21pre5/drivers/ide/pci/amd74xx.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/amd74xx.h 2003-03-03 15:44:19.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.21pre5/drivers/ide/pci/cmd64x.c linux.21pre5-ac1/drivers/ide/pci/cmd64x.c --- linux.21pre5/drivers/ide/pci/cmd64x.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/cmd64x.c 2003-03-02 23:05:44.000000000 +0000 @@ -458,7 +458,7 @@ ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { + if ((id->capability & 1) != 0 && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -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.21pre5/drivers/ide/pci/cs5530.c linux.21pre5-ac1/drivers/ide/pci/cs5530.c --- linux.21pre5/drivers/ide/pci/cs5530.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/cs5530.c 2003-03-02 23:06:27.000000000 +0000 @@ -180,7 +180,7 @@ */ if (mate->present) { struct hd_driveid *mateid = mate->id; - if (mateid && (mateid->capability & 1) && + if ((mateid->capability & 1) && !hwif->ide_dma_bad_drive(mate)) { if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) @@ -197,7 +197,7 @@ * Now see what the current drive is capable of, * selecting UDMA only if the mate said it was ok. */ - if (id && (id->capability & 1) && drive->autodma && + if ((id->capability & 1) && drive->autodma && !hwif->ide_dma_bad_drive(drive)) { if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { if (id->dma_ultra & 4) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/cy82c693.c linux.21pre5-ac1/drivers/ide/pci/cy82c693.c --- linux.21pre5/drivers/ide/pci/cy82c693.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/cy82c693.c 2003-03-02 23:07:12.000000000 +0000 @@ -192,23 +192,21 @@ printk (KERN_INFO "dma_on: %s\n", drive->name); #endif /* CY82C693_DEBUG_INFO */ - if (id != NULL) { - /* Enable DMA on any drive that has DMA - * (multi or single) enabled - */ - if (id->field_valid & 2) { /* regular DMA */ - int mmode, smode; + /* Enable DMA on any drive that has DMA + * (multi or single) enabled + */ + if (id->field_valid & 2) { /* regular DMA */ + int mmode, smode; - mmode = id->dma_mword & (id->dma_mword >> 8); - smode = id->dma_1word & (id->dma_1word >> 8); + mmode = id->dma_mword & (id->dma_mword >> 8); + smode = id->dma_1word & (id->dma_1word >> 8); - if (mmode != 0) { - /* enable multi */ - cy82c693_dma_enable(drive, (mmode >> 1), 0); - } else if (smode != 0) { - /* enable single */ - cy82c693_dma_enable(drive, (smode >> 1), 1); - } + if (mmode != 0) { + /* enable multi */ + cy82c693_dma_enable(drive, (mmode >> 1), 0); + } else if (smode != 0) { + /* enable single */ + cy82c693_dma_enable(drive, (smode >> 1), 1); } } return __ide_dma_on(drive); @@ -335,7 +333,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 +385,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.21pre5/drivers/ide/pci/cy82c693.h linux.21pre5-ac1/drivers/ide/pci/cy82c693.h --- linux.21pre5/drivers/ide/pci/cy82c693.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/cy82c693.h 2003-03-03 15:44:19.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.21pre5/drivers/ide/pci/hpt34x.c linux.21pre5-ac1/drivers/ide/pci/hpt34x.c --- linux.21pre5/drivers/ide/pci/hpt34x.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/hpt34x.c 2003-03-02 23:08:11.000000000 +0000 @@ -185,7 +185,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/hpt366.c linux.21pre5-ac1/drivers/ide/pci/hpt366.c --- linux.21pre5/drivers/ide/pci/hpt366.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/hpt366.c 2003-03-02 23:08:25.000000000 +0000 @@ -509,7 +509,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -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.21pre5/drivers/ide/pci/it8172.c linux.21pre5-ac1/drivers/ide/pci/it8172.c --- linux.21pre5/drivers/ide/pci/it8172.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/it8172.c 2003-03-02 23:08:46.000000000 +0000 @@ -201,7 +201,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/Makefile linux.21pre5-ac1/drivers/ide/pci/Makefile --- linux.21pre5/drivers/ide/pci/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/ide/pci/nvidia.c linux.21pre5-ac1/drivers/ide/pci/nvidia.c --- linux.21pre5/drivers/ide/pci/nvidia.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/nvidia.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,373 +0,0 @@ -/* - * linux/drivers/ide/pci/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.21pre5/drivers/ide/pci/nvidia.h linux.21pre5-ac1/drivers/ide/pci/nvidia.h --- linux.21pre5/drivers/ide/pci/nvidia.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/ide/pci/pdc202xx_new.c linux.21pre5-ac1/drivers/ide/pci/pdc202xx_new.c --- linux.21pre5/drivers/ide/pci/pdc202xx_new.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/pdc202xx_new.c 2003-03-02 23:09:11.000000000 +0000 @@ -383,7 +383,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/pdc202xx_old.c linux.21pre5-ac1/drivers/ide/pci/pdc202xx_old.c --- linux.21pre5/drivers/ide/pci/pdc202xx_old.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/pdc202xx_old.c 2003-03-02 23:09:22.000000000 +0000 @@ -487,7 +487,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/piix.c linux.21pre5-ac1/drivers/ide/pci/piix.c --- linux.21pre5/drivers/ide/pci/piix.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/piix.c 2003-03-02 23:09:43.000000000 +0000 @@ -147,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; @@ -280,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 */ @@ -551,7 +553,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -606,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; @@ -794,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, }, }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/piix.h linux.21pre5-ac1/drivers/ide/pci/piix.h --- linux.21pre5/drivers/ide/pci/piix.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/piix.h 2003-03-03 15:44:19.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.21pre5/drivers/ide/pci/sc1200.c linux.21pre5-ac1/drivers/ide/pci/sc1200.c --- linux.21pre5/drivers/ide/pci/sc1200.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/sc1200.c 2003-03-02 23:10:22.000000000 +0000 @@ -161,7 +161,7 @@ */ if (mate->present) { struct hd_driveid *mateid = mate->id; - if (mateid && (mateid->capability & 1) && !hwif->ide_dma_bad_drive(mate)) { + if ((mateid->capability & 1) && !hwif->ide_dma_bad_drive(mate)) { if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) udma_ok = 1; else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) @@ -174,7 +174,7 @@ * Now see what the current drive is capable of, * selecting UDMA only if the mate said it was ok. */ - if (id && (id->capability & 1) && hwif->autodma && !hwif->ide_dma_bad_drive(drive)) { + if ((id->capability & 1) && hwif->autodma && !hwif->ide_dma_bad_drive(drive)) { if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { if (id->dma_ultra & 4) mode = XFER_UDMA_2; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/serverworks.c linux.21pre5-ac1/drivers/ide/pci/serverworks.c --- linux.21pre5/drivers/ide/pci/serverworks.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/serverworks.c 2003-03-02 23:11:12.000000000 +0000 @@ -436,7 +436,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/siimage.c linux.21pre5-ac1/drivers/ide/pci/siimage.c --- linux.21pre5/drivers/ide/pci/siimage.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/siimage.c 2003-03-02 23:11:37.000000000 +0000 @@ -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->capability & 1) != 0 && drive->autodma) { if (!(hwif->atapi_dma)) goto fast_ata_pio; /* Consult the list of known "bad" drives */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/sis5513.c linux.21pre5-ac1/drivers/ide/pci/sis5513.c --- linux.21pre5/drivers/ide/pci/sis5513.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/sis5513.c 2003-03-02 23:11:56.000000000 +0000 @@ -819,7 +819,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/sl82c105.c linux.21pre5-ac1/drivers/ide/pci/sl82c105.c --- linux.21pre5/drivers/ide/pci/sl82c105.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/sl82c105.c 2003-03-02 23:12:27.000000000 +0000 @@ -155,7 +155,7 @@ if (!drive->autodma) break; - if (!id || !(id->capability & 1)) + if (!(id->capability & 1)) break; /* Consult the list of known "bad" drives */ @@ -470,7 +470,7 @@ */ hwif->drives[0].pio_speed = XFER_PIO_0; hwif->drives[0].autotune = 1; - hwif->drives[1].pio_speed = XFER_PIO_1; + hwif->drives[1].pio_speed = XFER_PIO_0; hwif->drives[1].autotune = 1; pci_read_config_dword(dev, 0x40, &val); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/slc90e66.c linux.21pre5-ac1/drivers/ide/pci/slc90e66.c --- linux.21pre5/drivers/ide/pci/slc90e66.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/slc90e66.c 2003-03-02 23:12:43.000000000 +0000 @@ -269,7 +269,7 @@ drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/triflex.c linux.21pre5-ac1/drivers/ide/pci/triflex.c --- linux.21pre5/drivers/ide/pci/triflex.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/pci/triflex.c 2003-03-02 23:13:02.000000000 +0000 @@ -167,7 +167,7 @@ ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { if (hwif->ide_dma_bad_drive(drive)) goto tune_pio; if (id->field_valid & 2) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ide/pci/via82cxxx.c linux.21pre5-ac1/drivers/ide/pci/via82cxxx.c --- linux.21pre5/drivers/ide/pci/via82cxxx.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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: * @@ -71,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. @@ -86,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 }, @@ -156,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); @@ -296,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.21pre5/drivers/ide/ppc/pmac.c linux.21pre5-ac1/drivers/ide/ppc/pmac.c --- linux.21pre5/drivers/ide/ppc/pmac.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ide/ppc/pmac.c 2003-03-03 01:03:57.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; } @@ -1582,7 +1898,7 @@ * Problem: This can schedule. I moved the block device * wakeup almost late by priority because of that. */ - if (DRIVER(drive) && DRIVER(drive)->media_change) + if (DRIVER(drive)->media_change) DRIVER(drive)->media_change(drive); /* We kick the VFS too (see fix in ide.c revalidate) */ @@ -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.21pre5/drivers/ide/setup-pci.c linux.21pre5-ac1/drivers/ide/setup-pci.c --- linux.21pre5/drivers/ide/setup-pci.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/ieee1394/amdtp.h linux.21pre5-ac1/drivers/ieee1394/amdtp.h --- linux.21pre5/drivers/ieee1394/amdtp.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/amdtp.h 2003-02-27 00:32:08.000000000 +0000 @@ -3,8 +3,8 @@ #ifndef __AMDTP_H #define __AMDTP_H +#include #include -#include "ieee1394-ioctl.h" /* The userspace interface for the Audio & Music Data Transmission * Protocol driver is really simple. First, open /dev/amdtp, use the @@ -57,6 +57,13 @@ * */ +/* We use '#' for our ioctl magic number because it's cool. */ + +#define AMDTP_IOC_CHANNEL _IOW('#', 0, sizeof (struct amdtp_ioctl)) +#define AMDTP_IOC_PLUG _IOW('#', 1, sizeof (struct amdtp_ioctl)) +#define AMDTP_IOC_PING _IOW('#', 2, sizeof (struct amdtp_ioctl)) +#define AMDTP_IOC_ZAP _IO('#', 3) + enum { AMDTP_FORMAT_RAW, AMDTP_FORMAT_IEC958_PCM, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/csr.c linux.21pre5-ac1/drivers/ieee1394/csr.c --- linux.21pre5/drivers/ieee1394/csr.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/csr.c 2003-02-26 23:57:33.000000000 +0000 @@ -102,7 +102,8 @@ int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom, size_t size, unsigned char rom_version) { - int ret,flags; + int ret; + unsigned long flags; spin_lock_irqsave(&host->csr.lock, flags); if (rom_version != host->csr.rom_version) ret = -1; @@ -121,7 +122,8 @@ int hpsb_get_config_rom(struct hpsb_host *host, quadlet_t *buffer, size_t buffersize, size_t *rom_size, unsigned char *rom_version) { - int ret,flags; + int ret; + unsigned long flags; spin_lock_irqsave(&host->csr.lock, flags); *rom_version=host->csr.rom_version; *rom_size=host->csr.rom_size; @@ -142,7 +144,7 @@ { int csraddr = addr - CSR_REGISTER_BASE; const char *src; - int flags; + unsigned long flags; spin_lock_irqsave(&host->csr.lock, flags); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/dma.c linux.21pre5-ac1/drivers/ieee1394/dma.c --- linux.21pre5/drivers/ieee1394/dma.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/dma.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,236 +0,0 @@ -/* - * DMA region bookkeeping routines - * - * Copyright (C) 2002 Maas Digital LLC - * - * This code is licensed under the GPL. See the file COPYING in the root - * directory of the kernel sources for details. - */ - -#include -#include -#include -#include "dma.h" - -/* dma_prog_region */ - -void dma_prog_region_init(struct dma_prog_region *prog) -{ - prog->kvirt = NULL; - prog->dev = NULL; - prog->n_pages = 0; - prog->bus_addr = 0; -} - -int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev) -{ - /* round up to page size */ - n_bytes = round_up_to_page(n_bytes); - - prog->n_pages = n_bytes / PAGE_SIZE; - - prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr); - if(!prog->kvirt) { - printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n"); - dma_prog_region_free(prog); - return -ENOMEM; - } - - prog->dev = dev; - - return 0; -} - -void dma_prog_region_free(struct dma_prog_region *prog) -{ - if(prog->kvirt) { - pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr); - } - - prog->kvirt = NULL; - prog->dev = NULL; - prog->n_pages = 0; - prog->bus_addr = 0; -} - -/* dma_region */ - -void dma_region_init(struct dma_region *dma) -{ - dma->kvirt = NULL; - dma->dev = NULL; - dma->n_pages = 0; - dma->n_dma_pages = 0; - dma->sglist = NULL; -} - -int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction) -{ - unsigned int i, n_pages; - - /* round up to page size */ - n_bytes = round_up_to_page(n_bytes); - - n_pages = n_bytes / PAGE_SIZE; - - dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE); - if(!dma->kvirt) { - printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n"); - goto err; - } - - dma->n_pages = n_pages; - - /* Clear the ram out, no junk to the user */ - memset(dma->kvirt, 0, n_pages * PAGE_SIZE); - - /* allocate scatter/gather list */ - dma->sglist = kmalloc(dma->n_pages * sizeof(struct scatterlist), GFP_KERNEL); - if(!dma->sglist) { - printk(KERN_ERR "dma_region_alloc: kmalloc(sglist) failed\n"); - goto err; - } - - /* just to be safe - this will become unnecessary once sglist->address goes away */ - memset(dma->sglist, 0, dma->n_pages * sizeof(struct scatterlist)); - - /* fill scatter/gather list with pages */ - for(i = 0; i < dma->n_pages; i++) { - unsigned long va = (unsigned long) dma->kvirt + i * PAGE_SIZE; - - dma->sglist[i].page = vmalloc_to_page((void *)va); - dma->sglist[i].length = PAGE_SIZE; - } - - /* map sglist to the IOMMU */ - dma->n_dma_pages = pci_map_sg(dev, &dma->sglist[0], dma->n_pages, direction); - - if(dma->n_dma_pages == 0) { - printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n"); - goto err; - } - - dma->dev = dev; - dma->direction = direction; - - return 0; - -err: - dma_region_free(dma); - return -ENOMEM; -} - -void dma_region_free(struct dma_region *dma) -{ - if(dma->n_dma_pages) { - pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction); - dma->n_dma_pages = 0; - dma->dev = NULL; - } - - if(dma->sglist) { - kfree(dma->sglist); - dma->sglist = NULL; - } - - if(dma->kvirt) { - vfree(dma->kvirt); - dma->kvirt = NULL; - dma->n_pages = 0; - } -} - -/* find the scatterlist index and remaining offset corresponding to a - given offset from the beginning of the buffer */ -static inline int dma_region_find(struct dma_region *dma, unsigned long offset, unsigned long *rem) -{ - int i; - unsigned long off = offset; - - for(i = 0; i < dma->n_dma_pages; i++) { - if(off < sg_dma_len(&dma->sglist[i])) { - *rem = off; - return i; - } - - off -= sg_dma_len(&dma->sglist[i]); - } - - panic("dma_region_find: offset %lu beyond end of DMA mapping\n", offset); -} - -dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset) -{ - unsigned long rem; - - struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)]; - return sg_dma_address(sg) + rem; -} - -void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long len) -{ - int first, last; - unsigned long rem; - - if(!len) - len = 1; - - first = dma_region_find(dma, offset, &rem); - last = dma_region_find(dma, offset + len - 1, &rem); - - pci_dma_sync_sg(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); -} - -/* nopage() handler for mmap access */ - -static struct page* -dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int write_access) -{ - unsigned long offset; - unsigned long kernel_virt_addr; - struct page *ret = NOPAGE_SIGBUS; - - struct dma_region *dma = (struct dma_region*) area->vm_private_data; - - if(!dma->kvirt) - goto out; - - if( (address < (unsigned long) area->vm_start) || - (address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) ) - goto out; - - offset = address - area->vm_start; - kernel_virt_addr = (unsigned long) dma->kvirt + offset; - ret = vmalloc_to_page((void*) kernel_virt_addr); - get_page(ret); -out: - return ret; -} - -static struct vm_operations_struct dma_region_vm_ops = { - .nopage = dma_region_pagefault, -}; - -int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma) -{ - unsigned long size; - - if(!dma->kvirt) - return -EINVAL; - - /* must be page-aligned */ - if(vma->vm_pgoff != 0) - return -EINVAL; - - /* check the length */ - size = vma->vm_end - vma->vm_start; - if(size > (PAGE_SIZE * dma->n_pages)) - return -EINVAL; - - vma->vm_ops = &dma_region_vm_ops; - vma->vm_private_data = dma; - vma->vm_file = file; - vma->vm_flags |= VM_RESERVED; - - return 0; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/dma.h linux.21pre5-ac1/drivers/ieee1394/dma.h --- linux.21pre5/drivers/ieee1394/dma.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/dma.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,84 +0,0 @@ -/* - * DMA region bookkeeping routines - * - * Copyright (C) 2002 Maas Digital LLC - * - * This code is licensed under the GPL. See the file COPYING in the root - * directory of the kernel sources for details. - */ - -#ifndef IEEE1394_DMA_H -#define IEEE1394_DMA_H - -#include -#include - -/* struct dma_prog_region - - a small, physically-contiguous DMA buffer with random-access, - synchronous usage characteristics -*/ - -struct dma_prog_region { - unsigned char *kvirt; /* kernel virtual address */ - struct pci_dev *dev; /* PCI device */ - unsigned int n_pages; /* # of kernel pages */ - dma_addr_t bus_addr; /* base bus address */ -}; - -/* clear out all fields but do not allocate any memory */ -void dma_prog_region_init(struct dma_prog_region *prog); -int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev); -void dma_prog_region_free(struct dma_prog_region *prog); - -static inline dma_addr_t dma_prog_region_offset_to_bus(struct dma_prog_region *prog, unsigned long offset) -{ - return prog->bus_addr + offset; -} - -/* struct dma_region - - a large, non-physically-contiguous DMA buffer with streaming, - asynchronous usage characteristics -*/ - -struct dma_region { - unsigned char *kvirt; /* kernel virtual address */ - struct pci_dev *dev; /* PCI device */ - unsigned int n_pages; /* # of kernel pages */ - unsigned int n_dma_pages; /* # of IOMMU pages */ - struct scatterlist *sglist; /* IOMMU mapping */ - int direction; /* PCI_DMA_TODEVICE, etc */ -}; - -/* clear out all fields but do not allocate anything */ -void dma_region_init(struct dma_region *dma); - -/* allocate the buffer and map it to the IOMMU */ -int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction); - -/* unmap and free the buffer */ -void dma_region_free(struct dma_region *dma); - -/* sync the IO bus' view of the buffer with the CPU's view */ -void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long len); - -/* map the buffer into a user space process */ -int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma); - -/* macro to index into a DMA region (or dma_prog_region) */ -#define dma_region_i(_dma, _type, _index) ( ((_type*) ((_dma)->kvirt)) + (_index) ) - -/* return the DMA bus address of the byte with the given offset - relative to the beginning of the dma_region */ -dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset); - -/* round up a number of bytes to be a multiple of the PAGE_SIZE */ -static inline unsigned long round_up_to_page(unsigned long len) -{ - if(len % PAGE_SIZE) - len += PAGE_SIZE - (len % PAGE_SIZE); - return len; -} - -#endif /* IEEE1394_DMA_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/dv1394.c linux.21pre5-ac1/drivers/ieee1394/dv1394.c --- linux.21pre5/drivers/ieee1394/dv1394.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/dv1394.c 2003-01-06 15:38:25.000000000 +0000 @@ -53,12 +53,6 @@ via pci_alloc_consistent() DONE: - - during reception, better handling of dropped frames and continuity errors - - during reception, prevent DMA from bypassing the irq tasklets - - reduce irq rate during reception (1/250 packets). - - add many more internal buffers during reception with scatter/gather dma. - - add dbc (continuity) checking on receive, increment status.dropped_frames - if not continuous. - restart IT DMA after a bus reset - safely obtain and release ISO Tx channels in cooperation with OHCI driver - map received DIF blocks to their proper location in DV frame (ensure @@ -97,9 +91,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -138,7 +132,7 @@ (will cause undeflows if your machine is too slow!) */ -#define DV1394_DEBUG_LEVEL 1 +#define DV1394_DEBUG_LEVEL 0 /* for debugging use ONLY: allow more than one open() of the device */ /* #define DV1394_ALLOW_MORE_THAN_ONE_OPEN 1 */ @@ -191,6 +185,39 @@ return (struct video_card*) file->private_data; } + +/*******************************/ +/* Memory management functions */ +/*******************************/ + +/* note: we no longer use mem_map_reserve, because it causes a memory + leak, and setting vma->vm_flags to VM_RESERVED should be sufficient + to pin the pages in memory anyway. */ + +static void * rvmalloc(unsigned long size) +{ + void * mem; + + mem = vmalloc_32(size); + + if(mem) + memset(mem, 0, size); /* Clear the ram out, + no junk to the user */ + return mem; +} + +static void rvfree(void * mem, unsigned long size) +{ + if (mem) { + vfree(mem); + } +} + +/***********************************/ +/* END Memory management functions */ +/***********************************/ + + /*** FRAME METHODS *********************************************************/ static void frame_reset(struct frame *f) @@ -419,7 +446,11 @@ /******************************/ /* first descriptor - OUTPUT_MORE_IMMEDIATE, for the controller's IT header */ - fill_output_more_immediate( &(block->u.out.omi), 1, video->channel, 0, payload_size); + fill_output_more_immediate( &(block->u.out.omi), + /* tag - what is this??? */ 1, + video->channel, + /* sync tag - what is this??? */ 0, + payload_size); if(empty_packet) { /* second descriptor - OUTPUT_LAST for CIP header */ @@ -470,8 +501,8 @@ PAGE_SIZE - (data_p % PAGE_SIZE), /* DMA address of data_p */ - dma_region_offset_to_bus(&video->dv_buf, - data_p - (unsigned long) video->dv_buf.kvirt)); + dma_offset_to_bus(&f->video->user_dma, + data_p - (unsigned long) f->video->user_buf)); fill_output_last( &(block->u.out.u.full.u.cross.ol), @@ -485,8 +516,8 @@ 480 - (PAGE_SIZE - (data_p % PAGE_SIZE)), /* DMA address of data_p + PAGE_SIZE - (data_p % PAGE_SIZE) */ - dma_region_offset_to_bus(&video->dv_buf, - data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) video->dv_buf.kvirt)); + dma_offset_to_bus(&f->video->user_dma, + data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) f->video->user_buf)); if(first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); @@ -520,8 +551,8 @@ /* DMA address of data_p */ - dma_region_offset_to_bus(&video->dv_buf, - data_p - (unsigned long) video->dv_buf.kvirt)); + dma_offset_to_bus(&f->video->user_dma, + data_p - (unsigned long) f->video->user_buf)); if(first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); @@ -562,8 +593,13 @@ to loop back up to the top */ *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors); - /* make the latest version of this frame visible to the PCI card */ - dma_region_sync(&video->dv_buf, f->data - (unsigned long) video->dv_buf.kvirt, video->frame_size); + + /* make the latest version of the frame buffer visible to the PCI card */ + /* could optimize this by only syncing the pages associated with this frame */ + pci_dma_sync_sg(video->ohci->dev, + &video->user_dma.sglist[0], + video->user_dma.n_dma_pages, + PCI_DMA_TODEVICE); /* lock against DMA interrupt */ spin_lock_irqsave(&video->spinlock, irq_flags); @@ -762,9 +798,6 @@ int dif_sequence = p->data[1] >> 4; /* dif sequence number is in bits 4 - 7 */ int dif_block = p->data[2]; - /* sanity check */ - if (dif_sequence > 11 || dif_block > 149) return; - switch (section_type) { case 0: /* 1 Header block */ memcpy( (void *) f->data + dif_sequence * 150 * 80, p->data, 480); @@ -792,64 +825,47 @@ } -static void start_dma_receive(struct video_card *video) +static void start_dma_receive(struct video_card *video, struct frame *frame) { - if (video->first_run == 1) { - video->first_run = 0; - - /* start DMA once all of the frames are READY */ - video->n_clear_frames = 0; - video->first_clear_frame = -1; - video->current_packet = 0; - video->active_frame = 0; - - /* reset iso recv control register */ - reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, 0xFFFFFFFF); - wmb(); - - /* clear bufferFill, set isochHeader and speed (0=100) */ - reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x40000000); + /* reset iso recv control register */ + reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, 0xFFFFFFFF); + wmb(); - /* match on all tags, listen on channel */ - reg_write(video->ohci, video->ohci_IsoRcvContextMatch, 0xf0000000 | video->channel); - - /* address and first descriptor block + Z=1 */ - reg_write(video->ohci, video->ohci_IsoRcvCommandPtr, - video->frames[0]->descriptor_pool_dma | 1); /* Z=1 */ - wmb(); - - /* run */ - reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x8000); - flush_pci_write(video->ohci); - - debug_printk("dv1394: DMA started\n"); + /* clear bufferFill, set isochHeader and speed (0=100) */ + reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x40000000); + + /* match on all tags, listen on channel */ + reg_write(video->ohci, video->ohci_IsoRcvContextMatch, 0xf0000000 | video->channel); + + /* address and first descriptor block + Z=1 */ + reg_write(video->ohci, video->ohci_IsoRcvCommandPtr, + frame->descriptor_pool_dma | 1); /* Z=1 */ + wmb(); + /* run */ + reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x8000); + flush_pci_write(video->ohci); + + debug_printk("dv1394: DMA started\n"); + #if DV1394_DEBUG_LEVEL >= 2 - { - int i; - - for(i = 0; i < 1000; ++i) { - mdelay(1); - if(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { - printk("DMA ACTIVE after %d msec\n", i); - break; - } + { + int i; + + for(i = 0; i < 1000; ++i) { + mdelay(1); + if(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { + printk("DMA ACTIVE after %d msec\n", i); + break; } - if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { - printk("DEAD, event = %x\n", - reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); - } else - printk("RUNNING!\n"); } -#endif - } - else if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { - debug_printk("DEAD, event = %x\n", - reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); - - /* wake */ - reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12)); + if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + printk("DEAD, event = %x\n", + reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); + } else + printk("RUNNING!\n"); } +#endif } @@ -857,7 +873,7 @@ receive_packets() - build the DMA program for receiving */ -static void receive_packets(struct video_card *video) +static void receive_packets(struct video_card *video, struct frame *f) { struct DMA_descriptor_block *block = NULL; dma_addr_t block_dma = 0; @@ -865,46 +881,52 @@ dma_addr_t data_dma = 0; u32 *last_branch_address = NULL; unsigned long irq_flags; - int want_interrupt = 0; - struct frame *f = NULL; - int i, j; spin_lock_irqsave(&video->spinlock, irq_flags); - for (j = 0; j < video->n_frames; j++) { + video->n_clear_frames = 0; + video->first_clear_frame = -1; - /* connect frames */ - if (j > 0 && f != NULL && f->frame_end_branch != NULL) - *(f->frame_end_branch) = cpu_to_le32(video->frames[j]->descriptor_pool_dma | 1); /* set Z=1 */ + for (video->current_packet = 0; video->current_packet < MAX_PACKET_BUFFER; ++video->current_packet) { + /* locate a descriptor block and packet from the buffer */ + block = &(f->descriptor_pool[video->current_packet]); + block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma; + + data = &(video->packet_buffer[video->current_packet]); + data_dma = ((unsigned long) data - (unsigned long) video->packet_buffer) + video->packet_buffer_dma; + + /* setup DMA descriptor block */ + fill_input_last( &(block->u.in.il), 512, data_dma); - f = video->frames[j]; + /* link descriptors */ + last_branch_address = f->frame_end_branch; - for (i = 0; i < MAX_PACKETS; i++) { - /* locate a descriptor block and packet from the buffer */ - block = &(f->descriptor_pool[i]); - block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma; - - data = ((struct packet*)video->packet_buf.kvirt) + f->frame_num * MAX_PACKETS + i; - data_dma = dma_region_offset_to_bus( &video->packet_buf, - ((unsigned long) data - (unsigned long) video->packet_buf.kvirt) ); - - /* setup DMA descriptor block */ - want_interrupt = ((i % (MAX_PACKETS/2)) == 0 || i == (MAX_PACKETS-1)); - fill_input_last( &(block->u.in.il), want_interrupt, 512, data_dma); - - /* link descriptors */ - last_branch_address = f->frame_end_branch; - - if (last_branch_address != NULL) - *(last_branch_address) = cpu_to_le32(block_dma | 1); /* set Z=1 */ - - f->frame_end_branch = &(block->u.in.il.q[2]); - } + if (last_branch_address) + *(last_branch_address) = cpu_to_le32(block_dma | 1); /* set Z=1 */ + + f->frame_end_branch = &(block->u.in.il.q[2]); + } - } /* next j */ + /* loop tail to head */ + if (f->frame_end_branch) + *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | 1); /* set Z=1 */ spin_unlock_irqrestore(&video->spinlock, irq_flags); + if (video->first_run) { + /* start DMA once all of the frames are READY */ + video->first_run = 0; + video->current_packet = 0; + video->active_frame = f->frame_num; + start_dma_receive(video, f); + } + else if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + debug_printk("DEAD, event = %x\n", + reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); + + /* wake */ + reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12)); + } } @@ -918,7 +940,6 @@ u64 chan_mask; int retval = -EINVAL; - debug_printk( "dv1394: initialising %d\n", video->id ); if(init->api_version != DV1394_API_VERSION) goto err; @@ -948,8 +969,10 @@ if(new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE); /* don't allow the user to allocate the DMA buffer more than once */ - if(video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) + if( (video->user_buf) && + (video->user_buf_size != new_buf_size) ) { goto err; + } /* shutdown the card if it's currently active */ /* (the card should not be reset if the parameters are screwy) */ @@ -1053,39 +1076,93 @@ } } - if(!video->dv_buf.kvirt) { + + + if(video->user_buf == NULL) { + unsigned int i; + /* allocate the ringbuffer */ - retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE); - if(retval) + video->user_buf = rvmalloc(new_buf_size); + if(!video->user_buf) { + printk(KERN_ERR "dv1394: Cannot allocate frame buffers\n"); goto err_frames; - - video->dv_buf_size = new_buf_size; + } + video->user_buf_size = new_buf_size; + + /* allocate the sglist to hold the DMA addresses */ + video->user_dma.n_pages = video->user_buf_size / PAGE_SIZE; + video->user_dma.sglist = kmalloc(video->user_dma.n_pages * sizeof(struct scatterlist), GFP_KERNEL); + if(!video->user_dma.sglist) { + printk(KERN_ERR "dv1394: Cannot allocate sglist for user buffer\n"); + goto err_user_buf; + } + + /* initialize all fields of all sglist entries to zero + (new requirement due to PCI changes in 2.4.13) */ + + memset(video->user_dma.sglist, 0, video->user_dma.n_pages * sizeof(struct scatterlist)); + + /* fill the sglist with the kernel addresses of pages in the non-contiguous buffer */ + for(i = 0; i < video->user_dma.n_pages; i++) { + unsigned long va = (unsigned long) video->user_buf + i * PAGE_SIZE; + + video->user_dma.sglist[i].page = vmalloc_to_page((void *)va); + video->user_dma.sglist[i].length = PAGE_SIZE; + } + + /* map the buffer in the IOMMU */ + /* the user_data buffer only allows DMA *to* the card for transmission; + incoming DV data comes through the packet_buffer first, and then is copied to user_data */ + video->user_dma.n_dma_pages = pci_map_sg(video->ohci->dev, + &video->user_dma.sglist[0], + video->user_dma.n_pages, + PCI_DMA_TODEVICE); + if(video->user_dma.n_dma_pages == 0) { + printk(KERN_ERR "dv1394: Error mapping user buffer to the IOMMU\n"); + goto err_user_buf; + } + debug_printk("dv1394: Allocated %d frame buffers, total %u pages (%u DMA pages), %lu bytes\n", - video->n_frames, video->dv_buf.n_pages, - video->dv_buf.n_dma_pages, video->dv_buf_size); + video->n_frames, video->user_dma.n_pages, + video->user_dma.n_dma_pages, video->user_buf_size); } /* set up the frame->data pointers */ for(i = 0; i < video->n_frames; i++) - video->frames[i]->data = (unsigned long) video->dv_buf.kvirt + i * video->frame_size; + video->frames[i]->data = (unsigned long) video->user_buf + i * video->frame_size; - if(!video->packet_buf.kvirt) { - /* allocate packet buffer */ - video->packet_buf_size = sizeof(struct packet) * video->n_frames * MAX_PACKETS; - if (video->packet_buf_size % PAGE_SIZE) - video->packet_buf_size += PAGE_SIZE - (video->packet_buf_size % PAGE_SIZE); - - retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size, - video->ohci->dev, PCI_DMA_FROMDEVICE); - if(retval) - goto err_dv_buf; - - debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n", - video->n_frames*MAX_PACKETS, video->packet_buf.n_pages, - video->packet_buf.n_dma_pages, video->packet_buf_size); - } + /* allocate packet buffers */ + video->packet_buffer_size = sizeof(struct packet) * MAX_PACKET_BUFFER; + if (video->packet_buffer_size % PAGE_SIZE) + video->packet_buffer_size += PAGE_SIZE - (video->packet_buffer_size % PAGE_SIZE); + + + video->packet_buffer = kmalloc(video->packet_buffer_size, GFP_KERNEL); + if(!video->packet_buffer) { + printk(KERN_ERR "dv1394: Cannot allocate packet buffers"); + retval = -ENOMEM; + goto err_user_buf; + } + + /* map the packet buffer into the IOMMU */ + video->packet_buffer_dma = pci_map_single(video->ohci->dev, + video->packet_buffer, + video->packet_buffer_size, + PCI_DMA_FROMDEVICE); + if(!video->packet_buffer_dma) { + printk(KERN_ERR "dv1394: Cannot map packet buffer to IOMMU"); + kfree(video->packet_buffer); + video->packet_buffer = NULL; + retval = -ENOMEM; + goto err_user_buf; + } + + debug_printk("dv1394: Allocated %d packet buffers for receive, total %lu bytes\n", + MAX_PACKET_BUFFER, video->packet_buffer_size); + + /* set up register offsets for IT context */ /* IT DMA context registers are spaced 16 bytes apart */ video->ohci_IsoXmitContextControlSet = OHCI1394_IsoXmitContextControlSet+16*video->ohci_it_ctx; @@ -1109,9 +1186,26 @@ return 0; - err_dv_buf: - dma_region_free(&video->dv_buf); - + err_user_buf: + if(video->user_buf) { + if(video->user_dma.sglist) { + if(video->user_dma.n_dma_pages > 0) { + /* unmap it from the IOMMU */ + pci_unmap_sg(video->ohci->dev, + video->user_dma.sglist, + video->user_dma.n_pages, + PCI_DMA_TODEVICE); + video->user_dma.n_dma_pages = 0; + } + kfree(video->user_dma.sglist); + video->user_dma.sglist = NULL; + video->user_dma.n_pages = 0; + } + rvfree(video->user_buf, video->user_buf_size); + video->user_buf = NULL; + video->user_buf_size = 0; + } + err_frames: for(i = 0; i < DV1394_MAX_FRAMES; i++) { if(video->frames[i]) @@ -1144,7 +1238,7 @@ struct dv1394_init init; init.api_version = DV1394_API_VERSION; - init.n_frames = DV1394_MAX_FRAMES / 4; + init.n_frames = 2; /* the following are now set via proc_fs or devfs */ init.channel = video->channel; init.format = video->pal_or_ntsc; @@ -1176,6 +1270,7 @@ video->active_frame = -1; video->first_run = 1; + /* wait until DMA really stops */ i = 0; @@ -1187,7 +1282,6 @@ if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { /* still active */ - debug_printk("dv1394: stop_dma: DMA not stopped yet\n" ); mb(); } else { debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10); @@ -1201,15 +1295,13 @@ printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10); } } - else - debug_printk("dv1394: stop_dma: already stopped.\n"); - + spin_unlock_irqrestore(&video->spinlock, flags); } -static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf) +static int do_dv1394_shutdown(struct video_card *video, int free_user_buf) { int i; unsigned long flags; @@ -1230,8 +1322,7 @@ /* disable interrupts for IT context */ reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx)); - /* remove tasklet */ - ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet); + clear_bit(video->ohci_it_ctx, &video->ohci->it_ctx_usage); debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx); video->ohci_it_ctx = -1; } @@ -1245,14 +1336,13 @@ /* disable interrupts for IR context */ reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx)); - /* remove tasklet */ - ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet); + clear_bit(video->ohci_ir_ctx, &video->ohci->ir_ctx_usage); debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx); video->ohci_ir_ctx = -1; } spin_unlock_irqrestore(&video->spinlock, flags); - + /* release the ISO channel */ if(video->channel != -1) { u64 chan_mask; @@ -1279,20 +1369,42 @@ /* we can't free the DMA buffer unless it is guaranteed that no more user-space mappings exist */ - if(free_dv_buf) { - dma_region_free(&video->dv_buf); - video->dv_buf_size = 0; + if(free_user_buf && video->user_buf) { + if(video->user_dma.sglist) { + if(video->user_dma.n_dma_pages > 0) { + /* unmap it from the IOMMU */ + pci_unmap_sg(video->ohci->dev, + video->user_dma.sglist, + video->user_dma.n_pages, + PCI_DMA_TODEVICE); + video->user_dma.n_dma_pages = 0; + } + kfree(video->user_dma.sglist); + video->user_dma.sglist = NULL; + video->user_dma.n_pages = 0; + } + rvfree(video->user_buf, video->user_buf_size); + video->user_buf = NULL; + video->user_buf_size = 0; + } + + if (video->packet_buffer) { + pci_unmap_single(video->ohci->dev, + video->packet_buffer_dma, + video->packet_buffer_size, + PCI_DMA_FROMDEVICE); + kfree(video->packet_buffer); + video->packet_buffer = NULL; + video->packet_buffer_size = 0; } - /* free packet buffer */ - dma_region_free(&video->packet_buf); - video->packet_buf_size = 0; - debug_printk("dv1394: shutdown complete\n"); return 0; } + + /* ********************************** *** MMAP() THEORY OF OPERATION *** @@ -1315,28 +1427,96 @@ force the user to choose one buffer size and stick with it. This small sacrifice is worth the huge reduction in error-prone code in dv1394. + + Note: dv1394_mmap does no page table manipulation. The page + table entries are created by the dv1394_nopage() handler as + page faults are taken by the user. +*/ + +static struct page * dv1394_nopage(struct vm_area_struct * area, unsigned long address, int write_access) +{ + unsigned long offset; + unsigned long kernel_virt_addr; + struct page *ret = NOPAGE_SIGBUS; + + struct video_card *video = (struct video_card*) area->vm_private_data; + + /* guard against process-context operations and the interrupt */ + /* (by definition page faults are taken in interrupt context) */ + spin_lock(&video->spinlock); + + if(!video->user_buf) + goto out; + + if( (address < (unsigned long) area->vm_start) || + (address > (unsigned long) area->vm_start + video->user_buf_size) ) + goto out; + + offset = address - area->vm_start; + kernel_virt_addr = (unsigned long) video->user_buf + offset; + ret = vmalloc_to_page((void *)kernel_virt_addr); + get_page(ret); + + out: + spin_unlock(&video->spinlock); + return ret; +} + +static struct vm_operations_struct dv1394_vm_ops = { + .nopage = dv1394_nopage +}; + +/* + dv1394_mmap does no page table manipulation. The page table entries + are created by the dv1394_nopage() handler as page faults are taken + by the user. */ int dv1394_mmap(struct file *file, struct vm_area_struct *vma) { struct video_card *video = file_to_video_card(file); - int retval = -EINVAL; + unsigned long size; + int res = -EINVAL; /* serialize mmap */ down(&video->sem); if( ! video_card_initialized(video) ) { - retval = do_dv1394_init_default(video); - if(retval) - goto out; + res = do_dv1394_init_default(video); + if(res) + goto err; } - retval = dma_region_mmap(&video->dv_buf, file, vma); -out: + /* region must be page-aligned */ + if(vma->vm_pgoff != 0) + goto err; + + /* check the size the user is trying to map */ + size = vma->vm_end - vma->vm_start; + if(size > video->user_buf_size) + goto err; + + /* + we don't actually mess with the page tables here. + (nopage() takes care of that from the page fault handler) + Just set up the vma->vm_ops. + */ + + vma->vm_ops = &dv1394_vm_ops; + vma->vm_private_data = video; + vma->vm_file = file; + + /* don't try to swap this out =) */ + vma->vm_flags |= VM_RESERVED; + up(&video->sem); - return retval; + return 0; + err: + up(&video->sem); + return res; } + /*** DEVICE FILE INTERFACE *************************************************/ /* no need to serialize, multiple threads OK */ @@ -1452,7 +1632,7 @@ continue; /* start over from 'while(count > 0)...' */ } - if(copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) { + if(copy_from_user(video->user_buf + video->write_off, buffer, cnt)) { if(!ret) ret = -EFAULT; break; @@ -1499,11 +1679,7 @@ up(&video->sem); return ret; } - video->continuity_counter = -1; - - receive_packets(video); - - start_dma_receive(video); + receive_packets(video, video->frames[video->first_clear_frame]); } ret = 0; @@ -1556,7 +1732,7 @@ continue; /* start over from 'while(count > 0)...' */ } - if(copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) { + if(copy_to_user(buffer, video->user_buf + video->write_off, cnt)) { if(!ret) ret = -EFAULT; break; @@ -1608,8 +1784,7 @@ switch(cmd) { - case DV1394_SUBMIT_FRAMES: - case DV1394_IOC_SUBMIT_FRAMES: { + case DV1394_SUBMIT_FRAMES: { unsigned int n_submit; if( !video_card_initialized(video) ) { @@ -1662,8 +1837,8 @@ ret = 0; break; } - case DV1394_WAIT_FRAMES: - case DV1394_IOC_WAIT_FRAMES: { + + case DV1394_WAIT_FRAMES: { unsigned int n_wait; if( !video_card_initialized(video) ) { @@ -1711,8 +1886,8 @@ ret = 0; break; } - case DV1394_RECEIVE_FRAMES: - case DV1394_IOC_RECEIVE_FRAMES: { + + case DV1394_RECEIVE_FRAMES: { unsigned int n_recv; if( !video_card_initialized(video) ) { @@ -1744,25 +1919,22 @@ ret = 0; break; } - case DV1394_START_RECEIVE: - case DV1394_IOC_START_RECEIVE: { + + case DV1394_START_RECEIVE: { + if( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); if(ret) goto out; } - video->continuity_counter = -1; - - receive_packets(video); - - start_dma_receive(video); + receive_packets(video, video->frames[video->first_clear_frame]); ret = 0; break; } - case DV1394_INIT: - case DV1394_IOC_INIT: { + + case DV1394_INIT: { struct dv1394_init init; if(arg == (unsigned long) NULL) { ret = do_dv1394_init_default(video); @@ -1775,13 +1947,13 @@ } break; } + case DV1394_SHUTDOWN: - case DV1394_IOC_SHUTDOWN: ret = do_dv1394_shutdown(video, 0); break; - case DV1394_GET_STATUS: - case DV1394_IOC_GET_STATUS: { + + case DV1394_GET_STATUS: { struct dv1394_status status; if( !video_card_initialized(video) ) { @@ -1854,7 +2026,7 @@ struct video_card *p; list_for_each(lh, &dv1394_cards) { p = list_entry(lh, struct video_card, list); - if((p->id) == ieee1394_file_to_instance(file)) { + if((p->id >> 2) == ieee1394_file_to_instance(file)) { video = p; break; } @@ -2146,7 +2318,9 @@ struct video_card *video = (struct video_card*) data; spin_lock(&video->spinlock); - + + irq_printk("INTERRUPT! Video = %08lx Iso event Recv: %08x Xmit: %08x\n", + (unsigned long) video, isoRecvIntEvent, isoXmitIntEvent); irq_printk("ContextControl = %08x, CommandPtr = %08x\n", reg_read(video->ohci, video->ohci_IsoXmitContextControlSet), reg_read(video->ohci, video->ohci_IsoXmitCommandPtr) @@ -2288,149 +2462,82 @@ int wake = 0; struct video_card *video = (struct video_card*) data; - spin_lock(&video->spinlock); - - if( (video->ohci_ir_ctx != -1) - && (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) - { + if( (video->ohci_ir_ctx != -1) && + (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { int sof=0; /* start-of-frame flag */ struct frame *f; u16 packet_length, packet_time; - int i, dbc=0; - struct DMA_descriptor_block *block = NULL; - u16 xferstatus; - - int next_i, prev_i; - struct DMA_descriptor_block *next = NULL; - dma_addr_t next_dma = 0; - struct DMA_descriptor_block *prev = NULL; - - /* loop over all descriptors in all frames */ - for (i = 0; i < video->n_frames*MAX_PACKETS; i++) { - struct packet *p = dma_region_i(&video->packet_buf, struct packet, video->current_packet); - - /* make sure we are seeing the latest changes to p */ - dma_region_sync(&video->packet_buf, - (unsigned long) p - (unsigned long) video->packet_buf.kvirt, - sizeof(struct packet)); - - packet_length = le16_to_cpu(p->data_length); - packet_time = le16_to_cpu(p->timestamp); - - irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet, - packet_time, packet_length, - p->data[0], p->data[1]); - - /* get the descriptor based on packet_buffer cursor */ - f = video->frames[video->current_packet / MAX_PACKETS]; - block = &(f->descriptor_pool[video->current_packet % MAX_PACKETS]); - xferstatus = le16_to_cpu(block->u.in.il.q[3] >> 16); - xferstatus &= 0x1F; - - /* get the current frame */ - f = video->frames[video->active_frame]; - - /* exclude empty packet */ - if (packet_length > 8 && xferstatus == 0x11) { - irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) ); - - /* check for start of frame */ - /* DRD> Changed to check section type ([0]>>5==0) - and dif sequence ([1]>>4==0) */ - sof = ( (p->data[0] >> 5) == 0 && (p->data[1] >> 4) == 0); - - dbc = (int) (p->cip_h1 >> 24); - if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) ) - { - printk(KERN_WARNING "dv1394: discontinuity detected, dropping all frames\n" ); - video->dropped_frames += video->n_clear_frames + 1; - video->first_frame = 0; - video->n_clear_frames = 0; - video->first_clear_frame = -1; - } - video->continuity_counter = dbc; - - if (!video->first_frame) { - if (sof) { - video->first_frame = 1; - } - - } else if (sof) { - /* close current frame */ - frame_reset(f); /* f->state = STATE_CLEAR */ - video->n_clear_frames++; - if (video->n_clear_frames > video->n_frames) { - video->dropped_frames++; - printk(KERN_WARNING "dv1394: dropped a frame during reception\n" ); - video->n_clear_frames = video->n_frames-1; - video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; - } - if (video->first_clear_frame == -1) - video->first_clear_frame = video->active_frame; - - /* get the next frame */ - video->active_frame = (video->active_frame + 1) % video->n_frames; - f = video->frames[video->active_frame]; - irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n", - video->active_frame, video->n_clear_frames, video->first_clear_frame); + + packet_length = le16_to_cpu(video->packet_buffer[video->current_packet].data_length); + packet_time = le16_to_cpu(video->packet_buffer[video->current_packet].timestamp); + + irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet, + packet_time, packet_length, + video->packet_buffer[video->current_packet].data[0], video->packet_buffer[video->current_packet].data[1]); + + f = video->frames[video->active_frame]; + + /* exclude empty packet */ + if (packet_length > 8) { + + /* check for start of frame */ + sof = (video->packet_buffer[video->current_packet].data[0] == 0x1f && + video->packet_buffer[video->current_packet].data[1] == 0x07); + + if (!video->first_frame) { + if (sof) { + video->first_frame = 1; } - if (video->first_frame) { - if (sof) { - /* open next frame */ - f->state = FRAME_READY; - } - - /* copy to buffer */ - if (f->n_packets > (video->frame_size / 480)) { - printk(KERN_ERR "frame buffer overflow during receive\n"); - } - - frame_put_packet(f, p); - - } /* first_frame */ - } - - /* stop, end of ready packets */ - else if (xferstatus == 0) { - break; - } - - /* reset xferStatus & resCount */ - block->u.in.il.q[3] = cpu_to_le32(512); - /* terminate dma chain at this (next) packet */ - next_i = video->current_packet; - f = video->frames[next_i / MAX_PACKETS]; - next = &(f->descriptor_pool[next_i % MAX_PACKETS]); - next_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma; - next->u.in.il.q[0] |= 3 << 20; /* enable interrupt */ - next->u.in.il.q[2] = 0; /* disable branch */ - - /* link previous to next */ - prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1); - f = video->frames[prev_i / MAX_PACKETS]; - prev = &(f->descriptor_pool[prev_i % MAX_PACKETS]); - if(prev_i % (MAX_PACKETS/2)) { - prev->u.in.il.q[0] &= ~(3 << 20); /* no interrupt */ - } else { - prev->u.in.il.q[0] |= 3 << 20; /* enable interrupt */ - } - prev->u.in.il.q[2] = (cpu_to_le32(next_dma) | 1); /* set Z=1 */ - wmb(); + } else if (sof) { + /* close current frame */ + frame_reset(f); /* f->state = STATE_CLEAR */ + video->n_clear_frames++; + if (video->n_clear_frames > video->n_frames) { + video->n_clear_frames = video->n_frames; + video->dropped_frames++; + } + if (video->first_clear_frame == -1) + video->first_clear_frame = video->active_frame; - /* wake up DMA in case it fell asleep */ - reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12)); + /* get the next frame */ + video->active_frame = (video->active_frame + 1) % video->n_frames; + f = video->frames[video->active_frame]; + + irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n", + video->active_frame, video->n_clear_frames, video->first_clear_frame); + } + if (video->first_frame) { + if (sof) { + /* open next frame */ + f->state = FRAME_READY; + } + + /* copy to buffer */ + if (f->n_packets > (video->frame_size / 480)) { + printk(KERN_ERR "frame buffer overflow during receive\n"); + } - /* advance packet_buffer cursor */ - video->current_packet = (video->current_packet + 1) % (MAX_PACKETS * video->n_frames); - - } /* for all packets */ + /* make sure we are seeing the latest changes to packet_buffer */ + pci_dma_sync_single(video->ohci->dev, + video->packet_buffer_dma, + video->packet_buffer_size, + PCI_DMA_FROMDEVICE); + + frame_put_packet( f, &video->packet_buffer[video->current_packet]); + + } /* first_frame */ + + } /* not empty packet */ + + /* advance packet_buffer cursor */ + video->current_packet = (video->current_packet + 1) % MAX_PACKET_BUFFER; wake = 1; /* why the hell not? */ - + } /* receive interrupt */ - + spin_unlock(&video->spinlock); if(wake) { @@ -2609,10 +2716,6 @@ /* lower 2 bits of id indicate which of four "plugs" per host */ video->id = ohci->id << 2; - if (format == DV1394_NTSC) - video->id |= mode; - else - video->id |= 2 + mode; video->ohci_it_ctx = -1; video->ohci_ir_ctx = -1; @@ -2645,10 +2748,8 @@ for(i = 0; i < DV1394_MAX_FRAMES; i++) video->frames[i] = NULL; - dma_region_init(&video->dv_buf); - video->dv_buf_size = 0; - dma_region_init(&video->packet_buf); - video->packet_buf_size = 0; + video->user_buf = NULL; + video->user_buf_size = 0; clear_bit(0, &video->open); spin_lock_init(&video->spinlock); @@ -2661,6 +2762,10 @@ list_add_tail(&video->list, &dv1394_cards); spin_unlock_irqrestore(&dv1394_cards_lock, flags); + if (format == DV1394_NTSC) + video->id |= mode; + else video->id |= 2 + mode; + #ifdef CONFIG_DEVFS_FS if (dv1394_devfs_add_entry(video) < 0) goto err_free; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/dv1394.h linux.21pre5-ac1/drivers/ieee1394/dv1394.h --- linux.21pre5/drivers/ieee1394/dv1394.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/dv1394.h 2003-02-06 16:04:53.000000000 +0000 @@ -242,7 +242,6 @@ DV1394_GET_STATUS, }; -#include "ieee1394-ioctl.h" enum pal_or_ntsc { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/dv1394-private.h linux.21pre5-ac1/drivers/ieee1394/dv1394-private.h --- linux.21pre5/drivers/ieee1394/dv1394-private.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/dv1394-private.h 2003-02-28 00:48:06.000000000 +0000 @@ -28,7 +28,8 @@ #include "ieee1394.h" #include "ohci1394.h" -#include "dma.h" +#include +#include /* data structures private to the dv1394 driver */ /* none of this is exposed to user-space */ @@ -166,14 +167,12 @@ } static inline void fill_input_last(struct input_last *il, - int want_interrupt, unsigned int data_size, unsigned long data_phys_addr) { u32 temp = 3 << 28; /* INPUT_LAST */ temp |= 8 << 24; /* s = 1, update xferStatus and resCount */ - if (want_interrupt) - temp |= 3 << 20; /* enable interrupts */ + temp |= 3 << 20; /* enable interrupts */ temp |= 0xC << 16; /* enable branch to address */ /* disable wait on sync field, not used in DV :-( */ temp |= data_size; @@ -302,7 +301,8 @@ unsigned long data; /* Max # of packets per frame */ -#define MAX_PACKETS 500 + /* 320 is enough for NTSC, need to check what PAL is */ + #define MAX_PACKETS 500 /* a PAGE_SIZE memory pool for allocating CIP headers @@ -383,6 +383,35 @@ /* reset f so that it can be used again */ static void frame_reset(struct frame *f); + +/* structure for bookkeeping of a large non-physically-contiguous DMA buffer */ + +struct dma_region { + unsigned int n_pages; + unsigned int n_dma_pages; + struct scatterlist *sglist; +}; + +/* return the DMA bus address of the byte with the given offset + relative to the beginning of the dma_region */ + +static inline dma_addr_t dma_offset_to_bus(struct dma_region *dma, unsigned long offset) +{ + int i; + struct scatterlist *sg; + + for(i = 0, sg = &dma->sglist[0]; i < dma->n_dma_pages; i++, sg++) { + if(offset < sg_dma_len(sg)) { + return sg_dma_address(sg) + offset; + } + offset -= sg_dma_len(sg); + } + + printk(KERN_ERR "dv1394: dma_offset_to_bus failed for offset %lu!\n", offset); + return 0; +} + + /* struct video_card contains all data associated with one instance of the dv1394 driver */ @@ -479,8 +508,9 @@ /* the large, non-contiguous (rvmalloc()) ringbuffer for DV data, exposed to user-space via mmap() */ - unsigned long dv_buf_size; - struct dma_region dv_buf; + unsigned char *user_buf; + unsigned long user_buf_size; + struct dma_region user_dma; /* next byte in the ringbuffer that a write() call will fill */ size_t write_off; @@ -549,8 +579,10 @@ /* physically contiguous packet ringbuffer for receive */ - struct dma_region packet_buf; - unsigned long packet_buf_size; +#define MAX_PACKET_BUFFER 30 + struct packet *packet_buffer; + dma_addr_t packet_buffer_dma; + unsigned long packet_buffer_size; unsigned int current_packet; int first_frame; /* received first start frame marker? */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/eth1394.c linux.21pre5-ac1/drivers/ieee1394/eth1394.c --- linux.21pre5/drivers/ieee1394/eth1394.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/eth1394.c 2003-02-26 23:57:33.000000000 +0000 @@ -77,7 +77,7 @@ printk(KERN_ERR fmt, ## args) static char version[] __devinitdata = - "$Rev: 771 $ Ben Collins "; + "$Rev: 601 $ Ben Collins "; /* Our ieee1394 highlevel driver */ #define ETHER1394_DRIVER_NAME "ether1394" @@ -368,7 +368,6 @@ if (register_netdev (dev)) { ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n"); kfree (dev); - kfree (hi); return; } @@ -626,7 +625,7 @@ /* Transmit a packet (called by kernel) */ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) { - int kmflags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL; + int kmflags = GFP_ATOMIC; struct ethhdr *eth; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; int proto; @@ -683,8 +682,8 @@ ptask->skb = skb; ptask->addr = addr; ptask->dest_node = dest_node; - INIT_TQUEUE(&ptask->tq, hpsb_write_sched, ptask); - schedule_task(&ptask->tq); + HPSB_INIT_WORK(&ptask->tq, hpsb_write_sched, ptask); + hpsb_schedule_work(&ptask->tq); return 0; fail: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/eth1394.h linux.21pre5-ac1/drivers/ieee1394/eth1394.h --- linux.21pre5/drivers/ieee1394/eth1394.h 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/eth1394.h 2003-02-27 00:32:08.000000000 +0000 @@ -56,7 +56,7 @@ struct sk_buff *skb; /* Socket buffer we are sending */ nodeid_t dest_node; /* Destination of the packet */ u64 addr; /* Address */ - struct tq_struct tq; /* The task */ + struct hpsb_queue_struct tq; /* The task */ }; /* IP1394 headers */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/hosts.c linux.21pre5-ac1/drivers/ieee1394/hosts.c --- linux.21pre5/drivers/ieee1394/hosts.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/hosts.c 2003-01-06 15:38:25.000000000 +0000 @@ -138,7 +138,7 @@ atomic_set(&h->generation, 0); - INIT_TQUEUE(&h->timeout_tq, (void (*)(void*))abort_timedouts, h); + HPSB_INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h); h->topology_map = h->csr.topology_map + 3; h->speed_map = (u8 *)(h->csr.speed_map + 2); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/hosts.h linux.21pre5-ac1/drivers/ieee1394/hosts.h --- linux.21pre5/drivers/ieee1394/hosts.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/hosts.h 2003-02-28 00:48:06.000000000 +0000 @@ -3,7 +3,6 @@ #include #include -#include #include #include "ieee1394_types.h" @@ -31,7 +30,7 @@ struct list_head pending_packets; spinlock_t pending_pkt_lock; - struct tq_struct timeout_tq; + struct hpsb_queue_struct timeout_tq; /* A bitmask where a set bit means that this tlabel is in use. * FIXME - should be handled per node instead of per bus. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/ieee1394_core.c linux.21pre5-ac1/drivers/ieee1394/ieee1394_core.c --- linux.21pre5/drivers/ieee1394/ieee1394_core.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/ieee1394_core.c 2003-02-26 23:57:33.000000000 +0000 @@ -42,7 +42,6 @@ #include "csr.h" #include "nodemgr.h" #include "ieee1394_hotplug.h" -#include "dma.h" /* * Disable the nodemgr detection and config rom reading functionality. @@ -82,10 +81,10 @@ struct list_head *lh, *next; list_for_each_safe(lh, next, &packet->complete_tq) { - struct tq_struct *tq = - list_entry(lh, struct tq_struct, list); - list_del(&tq->list); - schedule_task(tq); + struct hpsb_queue_struct *tq = + list_entry(lh, struct hpsb_queue_struct, hpsb_queue_list); + list_del(&tq->hpsb_queue_list); + hpsb_schedule_work(tq); } return; @@ -94,11 +93,11 @@ /** * hpsb_add_packet_complete_task - add a new task for when a packet completes * @packet: the packet whose completion we want the task added to - * @tq: the tq_struct describing the task to add + * @tq: the hpsb_queue_struct describing the task to add */ -void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct tq_struct *tq) +void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct hpsb_queue_struct *tq) { - list_add_tail(&tq->list, &packet->complete_tq); + list_add_tail(&tq->hpsb_queue_list, &packet->complete_tq); return; } @@ -126,7 +125,7 @@ { struct hpsb_packet *packet = NULL; void *data = NULL; - int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; + int kmflags = GFP_ATOMIC; packet = kmem_cache_alloc(hpsb_packet_cache, kmflags); if (packet == NULL) @@ -438,7 +437,7 @@ spin_unlock_irqrestore(&host->pending_pkt_lock, flags); up(&packet->state_change); - schedule_task(&host->timeout_tq); + hpsb_schedule_work(&host->timeout_tq); } /** @@ -471,7 +470,7 @@ quadlet_t *data; size_t size=packet->data_size+packet->header_size; - int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; + int kmflags = GFP_ATOMIC; data = kmalloc(packet->header_size + packet->data_size, kmflags); if (!data) { HPSB_ERR("unable to allocate memory for concatenating header and data"); @@ -882,7 +881,7 @@ } if (!list_empty(&host->pending_packets)) - schedule_task(&host->timeout_tq); + hpsb_schedule_work(&host->timeout_tq); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); @@ -1031,7 +1030,7 @@ to get the index of the ieee1394_driver we want */ - blocknum = (MINOR(inode->i_rdev) >> 4) & 0xF; + blocknum = (minor(inode->i_rdev) >> 4) & 0xF; /* look up the driver */ @@ -1219,15 +1218,3 @@ EXPORT_SYMBOL(ieee1394_devfs_handle); EXPORT_SYMBOL(ieee1394_procfs_entry); - -/** dma.c **/ -EXPORT_SYMBOL(dma_prog_region_init); -EXPORT_SYMBOL(dma_prog_region_alloc); -EXPORT_SYMBOL(dma_prog_region_free); -EXPORT_SYMBOL(dma_region_init); -EXPORT_SYMBOL(dma_region_alloc); -EXPORT_SYMBOL(dma_region_free); -EXPORT_SYMBOL(dma_region_sync); -EXPORT_SYMBOL(dma_region_mmap); -EXPORT_SYMBOL(dma_region_offset_to_bus); - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/ieee1394_core.h linux.21pre5-ac1/drivers/ieee1394/ieee1394_core.h --- linux.21pre5/drivers/ieee1394/ieee1394_core.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/ieee1394_core.h 2003-02-28 00:48:06.000000000 +0000 @@ -77,7 +77,7 @@ }; /* add a new task for when a packet completes */ -void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct tq_struct *tq); +void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct hpsb_queue_struct *tq); static inline struct hpsb_packet *driver_packet(struct list_head *l) { @@ -194,7 +194,7 @@ /* return the index (within a minor number block) of a file */ static inline unsigned char ieee1394_file_to_instance(struct file *file) { - unsigned char minor = MINOR(file->f_dentry->d_inode->i_rdev); + unsigned char minor = minor(file->f_dentry->d_inode->i_rdev); /* return lower 4 bits */ return minor & 0xF; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/ieee1394-ioctl.h linux.21pre5-ac1/drivers/ieee1394/ieee1394-ioctl.h --- linux.21pre5/drivers/ieee1394/ieee1394-ioctl.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/ieee1394-ioctl.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,71 +0,0 @@ -/* Base file for all ieee1394 ioctl's. Linux-1394 has allocated base '#' - * with a range of 0x00-0x3f. */ - -#ifndef __IEEE1394_IOCTL_H -#define __IEEE1394_IOCTL_H - -#include -#include - - -/* AMDTP Gets 6 */ -#define AMDTP_IOC_CHANNEL _IOW('#', 0x00, struct amdtp_ioctl) -#define AMDTP_IOC_PLUG _IOW('#', 0x01, struct amdtp_ioctl) -#define AMDTP_IOC_PING _IOW('#', 0x02, struct amdtp_ioctl) -#define AMDTP_IOC_ZAP _IO ('#', 0x03) - - -/* DV1394 Gets 10 */ - -/* Get the driver ready to transmit video. pass a struct dv1394_init* as - * the parameter (see below), or NULL to get default parameters */ -#define DV1394_IOC_INIT _IOW('#', 0x06, struct dv1394_init) - -/* Stop transmitting video and free the ringbuffer */ -#define DV1394_IOC_SHUTDOWN _IO ('#', 0x07) - -/* Submit N new frames to be transmitted, where the index of the first new - * frame is first_clear_buffer, and the index of the last new frame is - * (first_clear_buffer + N) % n_frames */ -#define DV1394_IOC_SUBMIT_FRAMES _IO ('#', 0x08) - -/* Block until N buffers are clear (pass N as the parameter) Because we - * re-transmit the last frame on underrun, there will at most be n_frames - * - 1 clear frames at any time */ -#define DV1394_IOC_WAIT_FRAMES _IO ('#', 0x09) - -/* Capture new frames that have been received, where the index of the - * first new frame is first_clear_buffer, and the index of the last new - * frame is (first_clear_buffer + N) % n_frames */ -#define DV1394_IOC_RECEIVE_FRAMES _IO ('#', 0x0a) - -/* Tell card to start receiving DMA */ -#define DV1394_IOC_START_RECEIVE _IO ('#', 0x0b) - -/* Pass a struct dv1394_status* as the parameter */ -#define DV1394_IOC_GET_STATUS _IOR('#', 0x0c, struct dv1394_status) - - -/* Video1394 Gets 10 */ - -#define VIDEO1394_IOC_LISTEN_CHANNEL \ - _IOWR('#', 0x10, struct video1394_mmap) -#define VIDEO1394_IOC_UNLISTEN_CHANNEL \ - _IOW ('#', 0x11, int) -#define VIDEO1394_IOC_LISTEN_QUEUE_BUFFER \ - _IOW ('#', 0x12, struct video1394_wait) -#define VIDEO1394_IOC_LISTEN_WAIT_BUFFER \ - _IOWR('#', 0x13, struct video1394_wait) -#define VIDEO1394_IOC_TALK_CHANNEL \ - _IOWR('#', 0x14, struct video1394_mmap) -#define VIDEO1394_IOC_UNTALK_CHANNEL \ - _IOW ('#', 0x15, int) -#define VIDEO1394_IOC_TALK_QUEUE_BUFFER \ - _IOW ('#', 0x16, sizeof (struct video1394_wait) + \ - sizeof (struct video1394_queue_variable)) -#define VIDEO1394_IOC_TALK_WAIT_BUFFER \ - _IOW ('#', 0x17, struct video1394_wait) -#define VIDEO1394_IOC_LISTEN_POLL_BUFFER \ - _IOWR('#', 0x18, struct video1394_wait) - -#endif /* __IEEE1394_IOCTL_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/ieee1394_types.h linux.21pre5-ac1/drivers/ieee1394/ieee1394_types.h --- linux.21pre5/drivers/ieee1394/ieee1394_types.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/ieee1394_types.h 2003-02-28 00:48:06.000000000 +0000 @@ -10,6 +10,27 @@ #include +/* The great kdev_t changeover in 2.5.x */ +#include +#ifndef minor +#define minor(dev) MINOR(dev) +#endif + +#ifndef __devexit_p +#define __devexit_p(x) x +#endif + +#include + +#ifndef list_for_each_safe +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +#endif + +#define pte_offset_kernel pte_offset + #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif @@ -19,6 +40,15 @@ #endif +/* Use task queue */ +#include +#define hpsb_queue_struct tq_struct +#define hpsb_queue_list list +#define hpsb_schedule_work(x) schedule_task(x) +#define HPSB_INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z) +#define HPSB_PREPARE_WORK(x,y,z) PREPARE_TQUEUE(x,y,z) + + typedef u32 quadlet_t; typedef u64 octlet_t; typedef u16 nodeid_t; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/Makefile linux.21pre5-ac1/drivers/ieee1394/Makefile --- linux.21pre5/drivers/ieee1394/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/Makefile 2003-01-07 15:04:25.000000000 +0000 @@ -8,7 +8,7 @@ list-multi := ieee1394.o ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \ - highlevel.o csr.o nodemgr.o dma.o + highlevel.o csr.o nodemgr.o obj-$(CONFIG_IEEE1394) += ieee1394.o obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/ohci1394.c linux.21pre5-ac1/drivers/ieee1394/ohci1394.c --- linux.21pre5/drivers/ieee1394/ohci1394.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/ohci1394.c 2003-02-26 23:57:33.000000000 +0000 @@ -153,7 +153,7 @@ printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 758 $ Ben Collins "; + "$Rev: 693 $ Ben Collins "; /* Module Parameters */ MODULE_PARM(attempt_root,"i"); @@ -1225,8 +1225,8 @@ PRINT(KERN_ERR, ohci->id, "SelfID received outside of bus reset sequence"); -selfid_not_valid: event &= ~OHCI1394_selfIDComplete; +selfid_not_valid: } /* Make sure we handle everything, just in case we accidentally @@ -1439,7 +1439,7 @@ struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci); struct hpsb_packet *packet; unsigned long flags; - u32 status, ack; + u32 ack; size_t datasize; spin_lock_irqsave(&d->lock, flags); @@ -1448,16 +1448,25 @@ packet = driver_packet(d->fifo_list.next); datasize = packet->data_size; if (datasize && packet->type != hpsb_raw) - status = le32_to_cpu( + ack = le32_to_cpu( d->prg_cpu[d->sent_ind]->end.status) >> 16; else - status = le32_to_cpu( + ack = le32_to_cpu( d->prg_cpu[d->sent_ind]->begin.status) >> 16; - if (status == 0) + if (ack == 0) /* this packet hasn't been sent yet*/ break; + if (!(ack & 0x10)) { + /* XXX: This is an OHCI evt_* code. We need to handle + * this specially! For right now, we just fake an + * ackx_send_error. */ + PRINT(KERN_DEBUG, ohci->id, "Received OHCI evt_* error 0x%x", + ack & 0xf); + ack = (ack & 0xffe0) | ACK_BUSY_A; + } + #ifdef OHCI1394_DEBUG if (datasize) DBGMSG(ohci->id, @@ -1469,7 +1478,7 @@ >>4)&0xf, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) >>10)&0x3f, - status&0x1f, (status>>5)&0x3, + ack&0x1f, (ack>>5)&0x3, le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3]) >>16, d->ctx); @@ -1483,64 +1492,13 @@ >>4)&0xf, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) >>10)&0x3f, - status&0x1f, (status>>5)&0x3, + ack&0x1f, (ack>>5)&0x3, le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3]), d->ctx); #endif - if (status & 0x10) { - ack = status & 0xf; - } else { - switch (status & 0x1f) { - case EVT_NO_STATUS: /* that should never happen */ - case EVT_RESERVED_A: /* that should never happen */ - case EVT_LONG_PACKET: /* that should never happen */ - PRINT(KERN_WARNING, ohci->id, "Received OHCI evt_* error 0x%x", status & 0x1f); - ack = ACKX_SEND_ERROR; - break; - case EVT_MISSING_ACK: - ack = ACKX_TIMEOUT; - break; - case EVT_UNDERRUN: - ack = ACKX_SEND_ERROR; - break; - case EVT_OVERRUN: /* that should never happen */ - PRINT(KERN_WARNING, ohci->id, "Received OHCI evt_* error 0x%x", status & 0x1f); - ack = ACKX_SEND_ERROR; - break; - case EVT_DESCRIPTOR_READ: - case EVT_DATA_READ: - case EVT_DATA_WRITE: - ack = ACKX_SEND_ERROR; - break; - case EVT_BUS_RESET: /* that should never happen */ - PRINT(KERN_WARNING, ohci->id, "Received OHCI evt_* error 0x%x", status & 0x1f); - ack = ACKX_SEND_ERROR; - break; - case EVT_TIMEOUT: - ack = ACKX_TIMEOUT; - break; - case EVT_TCODE_ERR: - ack = ACKX_SEND_ERROR; - break; - case EVT_RESERVED_B: /* that should never happen */ - case EVT_RESERVED_C: /* that should never happen */ - PRINT(KERN_WARNING, ohci->id, "Received OHCI evt_* error 0x%x", status & 0x1f); - ack = ACKX_SEND_ERROR; - break; - case EVT_UNKNOWN: - case EVT_FLUSHED: - ack = ACKX_SEND_ERROR; - break; - default: - PRINT(KERN_ERR, ohci->id, "Unhandled OHCI evt_* error 0x%x", status & 0x1f); - ack = ACKX_SEND_ERROR; - BUG(); - } - } - list_del(&packet->driver_list); - hpsb_packet_sent(ohci->host, packet, ack); + hpsb_packet_sent(ohci->host, packet, ack & 0xf); if (datasize) { pci_unmap_single(ohci->dev, @@ -1781,7 +1739,7 @@ /* initialize tasklet */ if (type == DMA_CTX_ISO) { ohci1394_init_iso_tasklet(&ohci->it_tasklet, OHCI_ISO_TRANSMIT, - dma_trm_tasklet, (unsigned long) d); + dma_rcv_tasklet, (unsigned long) d); if (ohci1394_register_iso_tasklet(ohci, &ohci->it_tasklet) < 0) { PRINT(KERN_ERR, ohci->id, "No IT DMA context available"); @@ -2120,7 +2078,7 @@ * will lock up the machine. Wait 50msec to make sure we have * full link enabled. */ reg_write(ohci, OHCI1394_HCControlSet, 0x00080000); - mdelay(50); + mdelay(50); /* PCI posting ? */ /* Determine the number of available IR and IT contexts. */ ohci->nb_iso_rcv_ctx = diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/ieee1394/ohci1394.h linux.21pre5-ac1/drivers/ieee1394/ohci1394.h --- linux.21pre5/drivers/ieee1394/ohci1394.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/ieee1394/ohci1394.h 2003-02-28 00:48:06.000000000 +0000 @@ -380,7 +380,7 @@ /* OHCI evt_* error types, table 3-2 of the OHCI 1.1 spec. */ #define EVT_NO_STATUS 0x0 /* No event status */ -#define EVT_RESERVED_A 0x1 /* Reserved, not used !!! */ +#define EVT_RESERVED 0x1 /* Reserved, not used !!! */ #define EVT_LONG_PACKET 0x2 /* The revc data was longer than the buf */ #define EVT_MISSING_ACK 0x3 /* A subaction gap was detected before an ack arrived, or recv'd ack had a parity error */ @@ -399,17 +399,6 @@ 16-bit host memory write */ #define EVT_BUS_RESET 0x9 /* Identifies a PHY packet in the recv buffer as being a synthesized bus reset packet */ -#define EVT_TIMEOUT 0xa /* Indicates that the asynchronous transmit response - packet expired and was not transmitted, or that an - IT DMA context experienced a skip processing overflow */ -#define EVT_TCODE_ERR 0xb /* A bad tCode is associated with this packet. - The packet was flushed */ -#define EVT_RESERVED_B 0xc /* Reserved, not used !!! */ -#define EVT_RESERVED_C 0xd /* Reserved, not used !!! */ -#define EVT_UNKNOWN 0xe /* An error condition has occurred that cannot be - represented by any other event codes defined herein. */ -#define EVT_FLUSHED 0xf /* Send by the link side of output FIFO when asynchronous - packets are being flushed due to a bus reset. */ #define OHCI1394_TCODE_PHY 0xE diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/input/joydev.c linux.21pre5-ac1/drivers/input/joydev.c --- linux.21pre5/drivers/input/joydev.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/isdn/hisax/st5481.h linux.21pre5-ac1/drivers/isdn/hisax/st5481.h --- linux.21pre5/drivers/isdn/hisax/st5481.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/isdn/hisax/st5481.h 2003-02-28 00:48:06.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.21pre5/drivers/isdn/hysdn/hysdn_boot.c linux.21pre5-ac1/drivers/isdn/hysdn/hysdn_boot.c --- linux.21pre5/drivers/isdn/hysdn/hysdn_boot.c 2003-02-27 18:40:02.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/md/Config.in linux.21pre5-ac1/drivers/md/Config.in --- linux.21pre5/drivers/md/Config.in 2003-02-27 18:40:08.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm.c linux.21pre5-ac1/drivers/md/dm.c --- linux.21pre5/drivers/md/dm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm-exception-store.c linux.21pre5-ac1/drivers/md/dm-exception-store.c --- linux.21pre5/drivers/md/dm-exception-store.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm.h linux.21pre5-ac1/drivers/md/dm.h --- linux.21pre5/drivers/md/dm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/md/dm.h 2003-03-03 15:41:19.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.21pre5/drivers/md/dm-ioctl.c linux.21pre5-ac1/drivers/md/dm-ioctl.c --- linux.21pre5/drivers/md/dm-ioctl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm-linear.c linux.21pre5-ac1/drivers/md/dm-linear.c --- linux.21pre5/drivers/md/dm-linear.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm-snapshot.c linux.21pre5-ac1/drivers/md/dm-snapshot.c --- linux.21pre5/drivers/md/dm-snapshot.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm-snapshot.h linux.21pre5-ac1/drivers/md/dm-snapshot.h --- linux.21pre5/drivers/md/dm-snapshot.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/md/dm-snapshot.h 2003-03-03 15:41:19.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.21pre5/drivers/md/dm-stripe.c linux.21pre5-ac1/drivers/md/dm-stripe.c --- linux.21pre5/drivers/md/dm-stripe.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm-table.c linux.21pre5-ac1/drivers/md/dm-table.c --- linux.21pre5/drivers/md/dm-table.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/dm-target.c linux.21pre5-ac1/drivers/md/dm-target.c --- linux.21pre5/drivers/md/dm-target.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/kcopyd.c linux.21pre5-ac1/drivers/md/kcopyd.c --- linux.21pre5/drivers/md/kcopyd.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/md/kcopyd.h linux.21pre5-ac1/drivers/md/kcopyd.h --- linux.21pre5/drivers/md/kcopyd.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/md/kcopyd.h 2003-02-27 00:32:08.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.21pre5/drivers/md/Makefile linux.21pre5-ac1/drivers/md/Makefile --- linux.21pre5/drivers/md/Makefile 2003-02-27 18:40:08.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/md/md.c linux.21pre5-ac1/drivers/md/md.c --- linux.21pre5/drivers/md/md.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/media/radio/radio-aimslab.c linux.21pre5-ac1/drivers/media/radio/radio-aimslab.c --- linux.21pre5/drivers/media/radio/radio-aimslab.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/media/radio/radio-aimslab.c 2003-03-03 15:18:57.000000000 +0000 @@ -1,6 +1,6 @@ /* radiotrack (radioreveal) driver for Linux radio support * (c) 1997 M. Kirkwood - * Coverted to new API by Alan Cox + * Converted to new API by Alan Cox * Various bugfixes and enhancements by Russell Kroll * * History: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/media/radio/radio-cadet.c linux.21pre5-ac1/drivers/media/radio/radio-cadet.c --- linux.21pre5/drivers/media/radio/radio-cadet.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/media/radio/radio-cadet.c 2003-02-11 18:07:08.000000000 +0000 @@ -538,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); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/media/radio/radio-gemtek.c linux.21pre5-ac1/drivers/media/radio/radio-gemtek.c --- linux.21pre5/drivers/media/radio/radio-gemtek.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/media/radio/radio-gemtek.c 2003-03-03 15:18:57.000000000 +0000 @@ -8,7 +8,7 @@ * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff * * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood - * Coverted to new API by Alan Cox + * Converted to new API by Alan Cox * Various bugfixes and enhancements by Russell Kroll * * TODO: Allow for more than one of these foolish entities :-) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/media/radio/radio-maxiradio.c linux.21pre5-ac1/drivers/media/radio/radio-maxiradio.c --- linux.21pre5/drivers/media/radio/radio-maxiradio.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/media/radio/radio-rtrack2.c linux.21pre5-ac1/drivers/media/radio/radio-rtrack2.c --- linux.21pre5/drivers/media/radio/radio-rtrack2.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/media/radio/radio-rtrack2.c 2003-03-03 15:18:57.000000000 +0000 @@ -1,7 +1,7 @@ /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff * * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood - * Coverted to new API by Alan Cox + * Converted to new API by Alan Cox * Various bugfixes and enhancements by Russell Kroll * * TODO: Allow for more than one of these foolish entities :-) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/media/video/bttv-driver.c linux.21pre5-ac1/drivers/media/video/bttv-driver.c --- linux.21pre5/drivers/media/video/bttv-driver.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/media/video/bttv-driver.c 2003-03-01 19:07:32.000000000 +0000 @@ -1649,28 +1649,23 @@ case VIDIOCGCHAN: { struct video_channel v; - unsigned int channel; - if(copy_from_user(&v, arg,sizeof(v))) return -EFAULT; - channel = v.channel; - if (channel>=bttv_tvcards[btv->type].video_inputs) - return -EINVAL; v.flags=VIDEO_VC_AUDIO; v.tuners=0; v.type=VIDEO_TYPE_CAMERA; v.norm = btv->win.norm; - if(channel==bttv_tvcards[btv->type].tuner) + if (v.channel < 0 || v.channel >= bttv_tvcards[btv->type].video_inputs) + return -EINVAL; + if(v.channel==bttv_tvcards[btv->type].tuner) { strcpy(v.name,"Television"); v.flags|=VIDEO_VC_TUNER; v.type=VIDEO_TYPE_TV; v.tuners=1; } - else if (channel==bttv_tvcards[btv->type].svhs) + else if(v.channel==bttv_tvcards[btv->type].svhs) strcpy(v.name,"S-Video"); - else if (bttv_tvcards[btv->type].muxsel[v.channel] < 0) - strcpy(v.name,"Digital Video"); else sprintf(v.name,"Composite%d",v.channel); @@ -1684,20 +1679,17 @@ case VIDIOCSCHAN: { struct video_channel v; - unsigned int channel; - if(copy_from_user(&v, arg,sizeof(v))) return -EFAULT; - channel = v.channel; - if (channel>bttv_tvcards[btv->type].video_inputs) + if (v.channel < 0 || v.channel >= bttv_tvcards[btv->type].video_inputs) return -EINVAL; if (v.norm > TVNORMS) return -EOPNOTSUPP; bttv_call_i2c_clients(btv,cmd,&v); down(&btv->lock); - bt848_muxsel(btv, channel); + bt848_muxsel(btv, v.channel); bttv_set_norm(btv, v.norm); up(&btv->lock); return 0; @@ -1726,13 +1718,10 @@ case VIDIOCSTUNER: { struct video_tuner v; - unsigned int tuner; - if(copy_from_user(&v, arg, sizeof(v))) return -EFAULT; - tuner = v.tuner; /* Only one channel has a tuner */ - if(tuner!=bttv_tvcards[btv->type].tuner) + if(v.tuner!=bttv_tvcards[btv->type].tuner) return -EINVAL; if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC @@ -1990,13 +1979,9 @@ case VIDIOCSAUDIO: { struct video_audio v; - unsigned int n; if(copy_from_user(&v,arg, sizeof(v))) return -EFAULT; - n = v.audio; - if(n >= bttv_tvcards[btv->type].audio_inputs) - return -EINVAL; down(&btv->lock); if(v.flags&VIDEO_AUDIO_MUTE) audio(btv, AUDIO_MUTE); @@ -2017,12 +2002,12 @@ case VIDIOCSYNC: { + int i; DECLARE_WAITQUEUE(wait, current); - unsigned int i; if(copy_from_user((void *)&i,arg,sizeof(int))) return -EFAULT; - if (i >= gbuffers) + if (i < 0 || i >= gbuffers) return -EINVAL; switch (btv->gbuf[i].stat) { case GBUFFER_UNUSED: @@ -2094,8 +2079,7 @@ case VIDIOCGMBUF: { struct video_mbuf vm; - unsigned int i; - + int i; memset(&vm, 0 , sizeof(vm)); vm.size=gbufsize*gbuffers; vm.frames=gbuffers; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/media/video/cpia.c linux.21pre5-ac1/drivers/media/video/cpia.c --- linux.21pre5/drivers/media/video/cpia.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/media/video/cpia.h linux.21pre5-ac1/drivers/media/video/cpia.h --- linux.21pre5/drivers/media/video/cpia.h 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/drivers/media/video/cpia.h 2003-03-03 15:41:19.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.21pre5/drivers/media/video/cpia_pp.c linux.21pre5-ac1/drivers/media/video/cpia_pp.c --- linux.21pre5/drivers/media/video/cpia_pp.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/media/video/cpia_usb.c linux.21pre5-ac1/drivers/media/video/cpia_usb.c --- linux.21pre5/drivers/media/video/cpia_usb.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/media/video/w9966.c linux.21pre5-ac1/drivers/media/video/w9966.c --- linux.21pre5/drivers/media/video/w9966.c 2003-02-27 18:40:07.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/message/fusion/mptbase.c linux.21pre5-ac1/drivers/message/fusion/mptbase.c --- linux.21pre5/drivers/message/fusion/mptbase.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/mtd/chips/Makefile linux.21pre5-ac1/drivers/mtd/chips/Makefile --- linux.21pre5/drivers/mtd/chips/Makefile 2003-02-27 18:40:08.000000000 +0000 +++ linux.21pre5-ac1/drivers/mtd/chips/Makefile 2003-03-01 18:56:01.000000000 +0000 @@ -17,6 +17,7 @@ obj-$(CONFIG_MTD) += chipreg.o obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o obj-$(CONFIG_MTD_CFI) += cfi_probe.o +obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/mtd/maps/Config.in linux.21pre5-ac1/drivers/mtd/maps/Config.in --- linux.21pre5/drivers/mtd/maps/Config.in 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/mtd/nftlmount.c linux.21pre5-ac1/drivers/mtd/nftlmount.c --- linux.21pre5/drivers/mtd/nftlmount.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/3c501.c linux.21pre5-ac1/drivers/net/3c501.c --- linux.21pre5/drivers/net/3c501.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/3c501.c 2003-03-03 15:19:48.000000000 +0000 @@ -1038,7 +1038,7 @@ * init_module: * * When the driver is loaded as a module this function is called. We fake up - * a device structure with the base I/O and interrupt set as if it was being + * a device structure with the base I/O and interrupt set as if it were being * called from Space.c. This minimises the extra code that would otherwise * be required. * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/net/3c59x.c linux.21pre5-ac1/drivers/net/3c59x.c --- linux.21pre5/drivers/net/3c59x.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/3c59x.c 2003-03-01 18:56:49.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, @@ -424,6 +429,7 @@ CH_3C905B_2, CH_3C905B_FX, CH_3C905C, + CH_3C905C2, CH_3C980, CH_3C9805, @@ -495,6 +501,8 @@ PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905C Tornado", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + {"3c905C Tornado 2", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c980 Cyclone", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c982 Dual Port Server Cyclone", @@ -509,7 +517,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, }, @@ -561,6 +569,7 @@ { 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 }, { 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX }, { 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C }, + { 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C2 }, { 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 }, { 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 }, @@ -578,7 +587,6 @@ { 0x10B7, 0x6564, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656_1 }, { 0x10B7, 0x4500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C450 }, - { 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C920 }, {0,} /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, vortex_pci_tbl); @@ -1190,6 +1198,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.21pre5/drivers/net/aironet4500_core.c linux.21pre5-ac1/drivers/net/aironet4500_core.c --- linux.21pre5/drivers/net/aironet4500_core.c 2003-02-27 18:39:52.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/aironet4500_core.c 2003-03-03 15:20:09.000000000 +0000 @@ -2676,10 +2676,8 @@ #endif //awc_dump_registers(dev); - if (adhoc & !max_mtu) - max_mtu= 2250; - else if (!max_mtu) - max_mtu= 1500; + if (!max_mtu) + max_mtu= adhoc ? 2250 : 1500; priv->sleeping_bap = 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/net/amd8111e.c linux.21pre5-ac1/drivers/net/amd8111e.c --- linux.21pre5/drivers/net/amd8111e.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/amd8111e.c 2003-02-27 21:40:37.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.21pre5/drivers/net/e100/e100_main.c linux.21pre5-ac1/drivers/net/e100/e100_main.c --- linux.21pre5/drivers/net/e100/e100_main.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/e100/e100_main.c 2003-02-27 20:18:41.000000000 +0000 @@ -607,7 +607,9 @@ } if (((bdp->pdev->device > 0x1030) - && (bdp->pdev->device < 0x103F)) + && (bdp->pdev->device < 0x103F)) + || ((bdp->pdev->device >= 0x1050) + && (bdp->pdev->device <= 0x1057)) || (bdp->pdev->device == 0x2449) || (bdp->pdev->device == 0x2459) || (bdp->pdev->device == 0x245D)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/net/e100/e100_test.c linux.21pre5-ac1/drivers/net/e100/e100_test.c --- linux.21pre5/drivers/net/e100/e100_test.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/e100/e100_test.c 2003-02-27 00:14:02.000000000 +0000 @@ -242,6 +242,9 @@ *dynamic_tbd = e100_config_dynamic_tbd(bdp,*dynamic_tbd); if (set_loopback) { + /* ICH PHY loopback is broken */ + if (bdp->flags & IS_ICH && loopback_mode == PHY_LOOPBACK) + loopback_mode = MAC_LOOPBACK; /* Configure loopback on MAC */ e100_config_loopback_mode(bdp,loopback_mode); } else { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/net/e100/e100_vendor.h linux.21pre5-ac1/drivers/net/e100/e100_vendor.h --- linux.21pre5/drivers/net/e100/e100_vendor.h 2003-02-27 18:39:53.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/e100/e100_vendor.h 2003-02-27 00:14:02.000000000 +0000 @@ -285,6 +285,13 @@ {0x8086, 0x2449, 0x1014, PCI_ANY_ID, 0, 0, E100_PROVE_D}, {0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS}, + {0x8086, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET}, + {0x8086, 0x1051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET}, + {0x8086, 0x1052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, + {0x8086, 0x1053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, + {0x8086, 0x1054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET}, + {0x8086, 0x1055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, + {0x8086, 0x1059, 0x1179, 0x0005, 0, 0, E100_82551QM}, {0x8086, 0x1059, 0x1033, 0x8191, 0, 0, E100_82551QM}, {0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82551QM}, @@ -303,6 +310,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.21pre5/drivers/net/pci-skeleton.c linux.21pre5-ac1/drivers/net/pci-skeleton.c --- linux.21pre5/drivers/net/pci-skeleton.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/pcnet32.c linux.21pre5-ac1/drivers/net/pcnet32.c --- linux.21pre5/drivers/net/pcnet32.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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++; @@ -1756,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.21pre5/drivers/net/r8169.c linux.21pre5-ac1/drivers/net/r8169.c --- linux.21pre5/drivers/net/r8169.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/net/sk98lin/build_no.c linux.21pre5-ac1/drivers/net/sk98lin/build_no.c --- linux.21pre5/drivers/net/sk98lin/build_no.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/net/sk98lin/build_no.c 2003-02-27 21:41:03.000000000 +0000 @@ -7,4 +7,3 @@ static const char SysKonnectBuildNumber[] = "@(#)SK-BUILD: 6.02 (20021219) PL: ALL.01"; -^Z \ No newline at end of file diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/net/tun.c linux.21pre5-ac1/drivers/net/tun.c --- linux.21pre5/drivers/net/tun.c 2003-02-27 18:39:53.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/8253x/8253xtty.c linux.21pre5-ac1/drivers/net/wan/8253x/8253xtty.c --- linux.21pre5/drivers/net/wan/8253x/8253xtty.c 2003-02-27 18:39:51.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/c101.c linux.21pre5-ac1/drivers/net/wan/c101.c --- linux.21pre5/drivers/net/wan/c101.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/comx-hw-mixcom.c linux.21pre5-ac1/drivers/net/wan/comx-hw-mixcom.c --- linux.21pre5/drivers/net/wan/comx-hw-mixcom.c 2003-02-27 18:39:51.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/Config.in linux.21pre5-ac1/drivers/net/wan/Config.in --- linux.21pre5/drivers/net/wan/Config.in 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/dscc4.c linux.21pre5-ac1/drivers/net/wan/dscc4.c --- linux.21pre5/drivers/net/wan/dscc4.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/farsync.c linux.21pre5-ac1/drivers/net/wan/farsync.c --- linux.21pre5/drivers/net/wan/farsync.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hd6457x.c linux.21pre5-ac1/drivers/net/wan/hd6457x.c --- linux.21pre5/drivers/net/wan/hd6457x.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_cisco.c linux.21pre5-ac1/drivers/net/wan/hdlc_cisco.c --- linux.21pre5/drivers/net/wan/hdlc_cisco.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_fr.c linux.21pre5-ac1/drivers/net/wan/hdlc_fr.c --- linux.21pre5/drivers/net/wan/hdlc_fr.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_generic.c linux.21pre5-ac1/drivers/net/wan/hdlc_generic.c --- linux.21pre5/drivers/net/wan/hdlc_generic.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_ppp.c linux.21pre5-ac1/drivers/net/wan/hdlc_ppp.c --- linux.21pre5/drivers/net/wan/hdlc_ppp.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_raw.c linux.21pre5-ac1/drivers/net/wan/hdlc_raw.c --- linux.21pre5/drivers/net/wan/hdlc_raw.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_raw_eth.c linux.21pre5-ac1/drivers/net/wan/hdlc_raw_eth.c --- linux.21pre5/drivers/net/wan/hdlc_raw_eth.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/hdlc_x25.c linux.21pre5-ac1/drivers/net/wan/hdlc_x25.c --- linux.21pre5/drivers/net/wan/hdlc_x25.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/net/wan/Makefile linux.21pre5-ac1/drivers/net/wan/Makefile --- linux.21pre5/drivers/net/wan/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/pci/quirks.c linux.21pre5-ac1/drivers/pci/quirks.c --- linux.21pre5/drivers/pci/quirks.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/pci/quirks.c 2003-02-27 20:53:26.000000000 +0000 @@ -698,6 +698,7 @@ * instead of 0x01. */ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master }, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/pnp/Config.in linux.21pre5-ac1/drivers/pnp/Config.in --- linux.21pre5/drivers/pnp/Config.in 2003-02-27 18:40:02.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/pnp/Makefile linux.21pre5-ac1/drivers/pnp/Makefile --- linux.21pre5/drivers/pnp/Makefile 2003-02-27 18:40:02.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/pnp/pnpbios_core.c linux.21pre5-ac1/drivers/pnp/pnpbios_core.c --- linux.21pre5/drivers/pnp/pnpbios_core.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/pnp/pnpbios_proc.c linux.21pre5-ac1/drivers/pnp/pnpbios_proc.c --- linux.21pre5/drivers/pnp/pnpbios_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aacraid/aachba.c linux.21pre5-ac1/drivers/scsi/aacraid/aachba.c --- linux.21pre5/drivers/scsi/aacraid/aachba.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7770.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7770.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7770.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7770_osm.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7770_osm.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7770_osm.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_core.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_core.c --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_core.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx.h --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_inline.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_inline.h --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_inline.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_osm.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_osm.c --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_osm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_osm.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_osm.h --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_osm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_osm.h 2003-02-28 00:48:06.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.21pre5/drivers/scsi/aic7xxx/aic79xx_osm_pci.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_osm_pci.c --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_pci.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_pci.c --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_proc.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_proc.c --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx.reg linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx.reg --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx.reg 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_reg.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_reg.h --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_reg.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_reg_print.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_reg_print.c --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_reg_print.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx.seq linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx.seq --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx.seq 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic79xx_seq.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic79xx_seq.h --- linux.21pre5/drivers/scsi/aic7xxx/aic79xx_seq.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_93cx6.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_93cx6.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_93cx6.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_93cx6.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_93cx6.h --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_93cx6.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_core.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_core.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_core.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_core.c 2003-02-27 20:23:22.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.21pre5/drivers/scsi/aic7xxx/aic7xxx.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx.h --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx.h 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx.h 2003-02-27 20:23:28.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.21pre5/drivers/scsi/aic7xxx/aic7xxx_inline.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_inline.h --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_inline.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_osm.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_osm.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_osm.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_osm.h --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_osm.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_osm.h 2003-02-28 00:48:06.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.21pre5/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_pci.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_pci.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_pci.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_proc.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_proc.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_proc.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx.reg linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx.reg --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx.reg 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_reg.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_reg.h --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_reg.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_reg_print.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_reg_print.c --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_reg_print.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx.seq linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx.seq --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx.seq 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aic7xxx_seq.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aic7xxx_seq.h --- linux.21pre5/drivers/scsi/aic7xxx/aic7xxx_seq.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm.c --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm.h --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h --- linux.21pre5/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aiclib.c linux.21pre5-ac1/drivers/scsi/aic7xxx/aiclib.c --- linux.21pre5/drivers/scsi/aic7xxx/aiclib.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/aiclib.h linux.21pre5-ac1/drivers/scsi/aic7xxx/aiclib.h --- linux.21pre5/drivers/scsi/aic7xxx/aiclib.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/cam.h linux.21pre5-ac1/drivers/scsi/aic7xxx/cam.h --- linux.21pre5/drivers/scsi/aic7xxx/cam.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/aic7xxx/cam.h 2003-02-27 00:32:08.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.21pre5/drivers/scsi/aic7xxx/CHANGELOG linux.21pre5-ac1/drivers/scsi/aic7xxx/CHANGELOG --- linux.21pre5/drivers/scsi/aic7xxx/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/Config.in linux.21pre5-ac1/drivers/scsi/aic7xxx/Config.in --- linux.21pre5/drivers/scsi/aic7xxx/Config.in 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/Makefile linux.21pre5-ac1/drivers/scsi/aic7xxx/Makefile --- linux.21pre5/drivers/scsi/aic7xxx/Makefile 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/aic7xxx/scsi_iu.h linux.21pre5-ac1/drivers/scsi/aic7xxx/scsi_iu.h --- linux.21pre5/drivers/scsi/aic7xxx/scsi_iu.h 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/ChangeLog.ips linux.21pre5-ac1/drivers/scsi/ChangeLog.ips --- linux.21pre5/drivers/scsi/ChangeLog.ips 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/ChangeLog.ips 2003-02-26 00:06:42.000000000 +0000 @@ -1,6 +1,14 @@ IBM ServeRAID driver Change Log ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 6.00.00 - Add 6x Adapters and Battery Flash + + 5.30.00 - use __devexit_p() + + 5.10.15 - remove unused code (sem, macros, etc.) + + 5.10.12 - use pci_dma interfaces, update for 2.5 kernel changes + 5.00.01 - Sarasota ( 5i ) adapters must always be scanned first - Get rid on IOCTL_NEW_COMMAND code - Add Extended DCDB Commands for Tape Support in 5I diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/scsi/cpqfcTSinit.c linux.21pre5-ac1/drivers/scsi/cpqfcTSinit.c --- linux.21pre5/drivers/scsi/cpqfcTSinit.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/dpt_i2o.c linux.21pre5-ac1/drivers/scsi/dpt_i2o.c --- linux.21pre5/drivers/scsi/dpt_i2o.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/dpt_i2o.c 2003-02-06 22:46:55.000000000 +0000 @@ -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.21pre5/drivers/scsi/ide-scsi.c linux.21pre5-ac1/drivers/scsi/ide-scsi.c --- linux.21pre5/drivers/scsi/ide-scsi.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/ide-scsi.c 2003-02-25 00:38:10.000000000 +0000 @@ -1107,7 +1107,12 @@ { ide_drive_t *drive = idescsi_drives[cmd->target]; + /* We cannot reset the interface holding the lock. We can + drop the lock here however */ + + spin_unlock(&io_request_lock); (void) ide_do_reset(drive); + spin_lock(&io_request_lock); return SCSI_RESET_SUCCESS; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/scsi/ips.c linux.21pre5-ac1/drivers/scsi/ips.c --- linux.21pre5/drivers/scsi/ips.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/ips.c 2003-02-27 20:23:50.000000000 +0000 @@ -1,11 +1,12 @@ /*****************************************************************************/ -/* ips.c -- driver for the IBM ServeRAID controller */ +/* ips.c -- driver for the Adaptec / IBM ServeRAID controller */ /* */ /* Written By: Keith Mitchell, IBM Corporation */ /* Jack Hammer, Adaptec, Inc. */ /* David Jeffery, Adaptec, Inc. */ /* */ -/* Copyright (C) 2000 IBM Corporation */ +/* Copyright (C) 2000 IBM Corporation */ +/* Copyright (C) 2003 Adaptec, 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 */ @@ -42,7 +43,7 @@ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* */ /* Bugs/Comments/Suggestions about this driver should be mailed to: */ -/* ipslinux@adaptec.com */ +/* ipslinux@adaptec.com */ /* */ /* For system support issues, contact your local IBM Customer support. */ /* Directions to find IBM Customer Support for each country can be found at: */ @@ -66,9 +67,8 @@ /* 0.99.05 - Fix an oops when we get certain passthru commands */ /* 1.00.00 - Initial Public Release */ /* Functionally equivalent to 0.99.05 */ -/* 3.60.00 - Bump max commands to 128 for use with ServeRAID firmware 3.60 */ -/* - Change version to 3.60 to coincide with ServeRAID release */ -/* numbering. */ +/* 3.60.00 - Bump max commands to 128 for use with firmware 3.60 */ +/* - Change version to 3.60 to coincide with release numbering. */ /* 3.60.01 - Remove bogus error check in passthru routine */ /* 3.60.02 - Make DCDB direction based on lookup table */ /* - Only allow one DCDB command to a SCSI ID at a time */ @@ -76,7 +76,7 @@ /* 4.00.01 - Add support for First Failure Data Capture */ /* 4.00.02 - Fix problem with PT DCDB with no buffer */ /* 4.00.03 - Add alternative passthru interface */ -/* - Add ability to flash ServeRAID BIOS */ +/* - Add ability to flash BIOS */ /* 4.00.04 - Rename structures/constants to be prefixed with IPS_ */ /* 4.00.05 - Remove wish_block from init routine */ /* - Use linux/spinlock.h instead of asm/spinlock.h for kernels */ @@ -126,6 +126,10 @@ /* 5.00.01 - Sarasota ( 5i ) adapters must always be scanned first */ /* - Get rid on IOCTL_NEW_COMMAND code */ /* - Add Extended DCDB Commands for Tape Support in 5I */ +/* 5.10.12 - use pci_dma interfaces, update for 2.5 kernel changes */ +/* 5.10.15 - remove unused code (sem, macros, etc.) */ +/* 5.30.00 - use __devexit_p() */ +/* 6.00.00 - Add 6x Adapters and Battery Flash */ /*****************************************************************************/ /* @@ -157,13 +161,10 @@ #include #include #include -#include #include -#include #include #include #include -#include #include #include @@ -198,8 +199,8 @@ /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "5.10" -#define IPS_VERSION_LOW ".21 " +#define IPS_VERSION_HIGH "6.00" +#define IPS_VERSION_LOW ".26 " #if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) @@ -223,7 +224,7 @@ dma_addr_t *dmahandle) { void * ptr = kmalloc(size, GFP_ATOMIC); if(ptr){ - *dmahandle = VIRT_TO_BUS(ptr); + *dmahandle = (uint32_t)virt_to_bus(ptr); } return ptr; } @@ -232,15 +233,34 @@ #define pci_map_sg(a,b,n,z) (n) #define pci_unmap_sg(a,b,c,d) - #define pci_map_single(a,b,c,d) (VIRT_TO_BUS(b)) + #define pci_map_single(a,b,c,d) ((uint32_t)virt_to_bus(b)) #define pci_unmap_single(a,b,c,d) #ifndef sg_dma_address - #define sg_dma_address(x) (VIRT_TO_BUS((x)->address)) + #define sg_dma_address(x) ((uint32_t)virt_to_bus((x)->address)) #define sg_dma_len(x) ((x)->length) #endif #define pci_unregister_driver(x) #endif +#if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) + #define IPS_SG_ADDRESS(sg) ((sg)->address) + #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) + #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) + #ifndef __devexit_p + #define __devexit_p(x) x + #endif +#else + #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ + page_address((sg)->page)+(sg)->offset : 0) + #define IPS_LOCK_SAVE(lock,flags) spin_lock(lock) + #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock(lock) +#endif + +#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \ + SCSI_DATA_NONE == scb->scsi_cmd->sc_data_direction) ? \ + PCI_DMA_BIDIRECTIONAL : \ + scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction)) + #ifdef IPS_DEBUG #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n"); #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n"); @@ -265,19 +285,26 @@ static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ static int ips_force_i2o = 1; /* Always use I2O command delivery */ static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */ -static int ips_cd_boot = 0; /* Booting from ServeRAID Manager CD */ +static int ips_cd_boot = 0; /* Booting from Manager CD */ static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ -static int ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */ +static long ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */ static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - /* This table describes any / all ServeRAID Adapters */ + /* This table describes all ServeRAID Adapters */ static struct pci_device_id ips_pci_table[] __devinitdata = { { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0, } + }; + + /* This table describes only Anaconda Family Adapters */ + static struct pci_device_id ips_pci_table_anaconda[] __devinitdata = { + { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0, } }; @@ -287,13 +314,25 @@ { 0x1014, 0x01BD, PCI_ANY_ID, 0x258, 0, 0 }, { 0, } }; + + /* This table describes only Sebring ( ServeRAID 6i ) Adapters */ + static struct pci_device_id ips_pci_table_6i[] __devinitdata = { + { 0x9005, 0x0250, PCI_ANY_ID, 0x28C, 0, 0 }, + { 0, } + }; - /* This table describes all i960 Adapters */ + /* This table describes all i960 ( 4M, 4Mx, 4L, 4Lx ) Adapters */ static struct pci_device_id ips_pci_table_i960[] __devinitdata = { { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0, } }; + /* This table describes all Adaptec ( 6M ) Adapters */ + static struct pci_device_id ips_pci_table_adaptec[] __devinitdata = { + { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0, } + }; + MODULE_DEVICE_TABLE( pci, ips_pci_table ); static char ips_hot_plug_name[] = "ips"; @@ -308,12 +347,26 @@ remove: __devexit_p(ips_remove_device), }; + struct pci_driver ips_pci_driver_anaconda = { + name: ips_hot_plug_name, + id_table: ips_pci_table_anaconda, + probe: ips_insert_device, + remove: __devexit_p(ips_remove_device), + }; + struct pci_driver ips_pci_driver_5i = { name: ips_hot_plug_name, id_table: ips_pci_table_5i, probe: ips_insert_device, remove: __devexit_p(ips_remove_device), }; + + struct pci_driver ips_pci_driver_6i = { + name: ips_hot_plug_name, + id_table: ips_pci_table_6i, + probe: ips_insert_device, + remove: __devexit_p(ips_remove_device), + }; struct pci_driver ips_pci_driver_i960 = { name: ips_hot_plug_name, @@ -322,6 +375,13 @@ remove: __devexit_p(ips_remove_device), }; + struct pci_driver ips_pci_driver_adaptec = { + name: ips_hot_plug_name, + id_table: ips_pci_table_adaptec, + probe: ips_insert_device, + remove: __devexit_p(ips_remove_device), + }; + #endif /* @@ -344,9 +404,17 @@ "ServeRAID 4Mx", "ServeRAID 4Lx", "ServeRAID 5i", - "ServeRAID 5i" + "ServeRAID 5i", + "ServeRAID 6M", + "ServeRAID 6i" }; +/* Init State 0 means we're only looking for a device to provide us the BIOS Adapter Ordering Table */ +/* Init State 1 is when we are actually enumerating the devices. */ +static int InitState; +/* IF BIOS wants to tell us the enumeration order, it puts a table in NVRAM Page 5 */ +static uint8_t AdapterOrder[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static struct notifier_block ips_notifier = { ips_halt, NULL, 0 }; @@ -479,6 +547,7 @@ static void ips_free(ips_ha_t *); static void ips_init_scb(ips_ha_t *, ips_scb_t *); static void ips_freescb(ips_ha_t *, ips_scb_t *); +static void ips_setup_funclist(ips_ha_t *); static void ips_statinit(ips_ha_t *); static void ips_statinit_memio(ips_ha_t *); static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t); @@ -512,10 +581,13 @@ static int copy_info(IPS_INFOSTR *, char *, ...); static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ); static void ips_version_check(ips_ha_t *ha, int intr); +static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index); static int ips_init_phase2( int index ); #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ); +#else +static int ips_init_oldphase1(Scsi_Host_Template *SHT); #endif /*--------------------------------------------------------------------------*/ @@ -578,8 +650,8 @@ #else - char *p; - char tokens[3] = {',', '.', 0}; + char *p; + char tokens[3] = {',', '.', 0}; for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) { p = key; @@ -593,7 +665,7 @@ value = p+1; } else value = NULL; - + /* * We now have key/value pairs. * Update the variables @@ -631,33 +703,9 @@ /****************************************************************************/ int ips_detect(Scsi_Host_Template *SHT) { - struct Scsi_Host *sh; - ips_ha_t *ha; - uint32_t io_addr; - uint32_t mem_addr; - uint32_t io_len; - uint32_t mem_len; - uint16_t planer; - uint8_t revision_id; - uint8_t bus; - uint8_t func; - uint8_t irq; - uint16_t deviceID[2]; - uint16_t subdevice_id; - int i; - int j; - uint32_t count; - char *ioremap_ptr; - char *mem_ptr; - struct pci_dev *dev[2]; - struct pci_dev *morpheus = NULL; - struct pci_dev *trombone = NULL; -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - uint32_t currbar; - uint32_t maskbar; - uint8_t barnum; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + int i; #endif - uint32_t IsDead; METHOD_TRACE("ips_detect", 1); @@ -670,8 +718,8 @@ #endif #endif - /* If Booting from the ServeRAID Manager CD, Allocate a large Flash */ - /* Buffer ( so we won't need to allocate one for each adapter ). */ + /* If Booting from the Manager CD, Allocate a large Flash */ + /* Buffer ( so we won't need to allocate one for each adapter ). */ if ( ips_cd_boot ) { ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); if (ips_FlashData == NULL) { @@ -679,16 +727,6 @@ printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" ); } } - - SHT->proc_info = ips_proc_info; -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - SHT->proc_dir = &proc_scsi_ips; -#else - SHT->proc_name = "ips"; -#endif - -#if defined(CONFIG_PCI) - /* initalize number of controllers */ ips_num_controllers = 0; ips_next_controller = 0; @@ -697,539 +735,569 @@ if (!pci_present()) return (0); - morpheus = pci_find_device(IPS_VENDORID, IPS_DEVICEID_MORPHEUS, morpheus); - trombone = pci_find_device(IPS_VENDORID, IPS_DEVICEID_COPPERHEAD, trombone); - - /* determine which controller to probe first */ - if (!morpheus) { - /* we only have trombone */ - dev[0] = trombone; - dev[1] = NULL; - deviceID[0] = IPS_DEVICEID_COPPERHEAD; - } else if (!trombone) { - /* we only have morpheus */ - dev[0] = morpheus; - dev[1] = NULL; - deviceID[0] = IPS_DEVICEID_MORPHEUS; - } else { - /* we have both in the system */ - if (trombone->bus->number < morpheus->bus->number) { - dev[0] = trombone; - dev[1] = morpheus; - deviceID[0] = IPS_DEVICEID_COPPERHEAD; - deviceID[1] = IPS_DEVICEID_MORPHEUS; - } else if (trombone->bus->number > morpheus->bus->number) { - dev[0] = morpheus; - dev[1] = trombone; - deviceID[0] = IPS_DEVICEID_MORPHEUS; - deviceID[1] = IPS_DEVICEID_COPPERHEAD; - } else { - /* further detection required */ - if (trombone->devfn < morpheus->devfn) { - dev[0] = trombone; - dev[1] = morpheus; - deviceID[0] = IPS_DEVICEID_COPPERHEAD; - deviceID[1] = IPS_DEVICEID_MORPHEUS; - } else { - dev[0] = morpheus; - dev[1] = trombone; - deviceID[0] = IPS_DEVICEID_MORPHEUS; - deviceID[1] = IPS_DEVICEID_COPPERHEAD; - } - } - } - /**********************************************************************************/ /* For Kernel Versions 2.4 or greater, use new PCI ( Hot Pluggable ) architecture */ /**********************************************************************************/ #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) spin_unlock_irq(&io_request_lock); + #endif + SHT->proc_info = ips_proc_info; + SHT->proc_name = "ips"; - /* By definition, a Sarasota ( 5i ) Adapter MUST be enumerated first or the */ - /* server may not boot properly. The adapters must be enumerated in exactly */ - /* the same order as ServeRAID BIOS for the machine to come up properly. */ - - pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters First */ - if (ips_num_controllers) /* If there is a 5i Adapter */ - pci_module_init(&ips_pci_driver_i960); /* Get all i960's next */ - pci_module_init(&ips_pci_driver); /* Get all remaining Adapters */ - /* ( in normal BUS order ) */ - spin_lock_irq(&io_request_lock); - if (ips_num_controllers > 0) - register_reboot_notifier(&ips_notifier); - - return (ips_num_controllers); + /* There are several special cases ( which are too complicated to enumerate here ) where, due */ + /* to System BIOS rules, the adapters must be enumerated in a certain order. If ServeRAID */ + /* BIOS tells us the order, then we will follow it. The first pass at init is simply to be */ + /* able to communicate with the first adapter to see if BIOS is telling us the order. */ + /* This does not apply to ia64 EFI BIOS. */ + +#if !defined(__ia64__) + InitState = 0; + pci_module_init(&ips_pci_driver); /* Look for Any Adapter, to fill in the Adapter Order Table */ #endif - /* Now scan the controllers */ - for (i = 0; i < 2; i++) { - if (!dev[i]) - break; + InitState = 1; + + if ( AdapterOrder[0] ) { + /* BIOS has dictated the order that we should enumerate Adapters */ + for ( i = 1; i <= AdapterOrder[0]; i++ ) { + switch (AdapterOrder[i]) { + case 'M': + pci_module_init(&ips_pci_driver_adaptec); /* Ask for Adaptec Adapters */ + break; + case 'S': + pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters */ + pci_module_init(&ips_pci_driver_6i); /* Ask for 6i Adapters */ + break; + case 'N': + pci_module_init(&ips_pci_driver_i960); /* Ask for i960 Adapters */ + break; + case 'A': + pci_module_init(&ips_pci_driver_anaconda); /* Ask for Anaconda Family Adapters */ + break; + default: + i = AdapterOrder[0] + 1; /* Premature End of List - Ensure Loop Ends */ + break; + } + } + } + else { + /* No Adapter Order Table from BIOS, so sort things the old-fashioned way */ - do { - if (ips_next_controller >= IPS_MAX_ADAPTERS) - break; + /* By definition, an Internal ( 5i or 6i ) Adapter MUST be enumerated first */ + /* or the server may not boot properly. The adapters must be enumerated in */ + /* exactly the same order as BIOS for the machine to come up properly. */ + /* NOTE: There will never be both a 5i and a 6i in the same machine. */ -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - if (pci_enable_device(dev[i])) - break; -#endif + pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters First */ + if (ips_num_controllers) { /* If there is a 5i Adapter */ + pci_module_init(&ips_pci_driver_i960); /* Get all i960's next */ + } + else { + pci_module_init(&ips_pci_driver_6i); /* Ask if any 6i Adapters */ + if (ips_num_controllers) /* If there is a 6i Adapter */ + pci_module_init(&ips_pci_driver_adaptec); /* Get all Adaptecs next */ + } - /* stuff that we get in dev */ - irq = dev[i]->irq; - bus = dev[i]->bus->number; - func = dev[i]->devfn; - - /* Init MEM/IO addresses to 0 */ - mem_addr = 0; - io_addr = 0; - mem_len = 0; - io_len = 0; + pci_module_init(&ips_pci_driver); /* Get all remaining Adapters */ + /* ( in normal BUS order ) */ + } - for (j = 0; j < 2; j++) { -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - if (!pci_resource_start(dev[i], j)) - break; + #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) + spin_lock_irq(&io_request_lock); + #endif + if (ips_num_controllers > 0) + register_reboot_notifier(&ips_notifier); - if (pci_resource_flags(dev[i], j) & IORESOURCE_IO) { - io_addr = pci_resource_start(dev[i], j); - io_len = pci_resource_len(dev[i], j); - } else { - mem_addr = pci_resource_start(dev[i], j); - mem_len = pci_resource_len(dev[i], j); - } + return (ips_num_controllers); #else - if (!dev[i]->base_address[j]) - break; - - if ((dev[i]->base_address[j] & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { - barnum = PCI_BASE_ADDRESS_0 + (j * 4); - io_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_IO_MASK; - - /* Get Size */ - pci_read_config_dword(dev[i], barnum, &currbar); - pci_write_config_dword(dev[i], barnum, ~0); - pci_read_config_dword(dev[i], barnum, &maskbar); - pci_write_config_dword(dev[i], barnum, currbar); + InitState = 1; + SHT->proc_info = ips_proc_info; + SHT->proc_dir = &proc_scsi_ips; + return ips_init_oldphase1(SHT); +#endif /* LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) */ - io_len = ~(maskbar & PCI_BASE_ADDRESS_IO_MASK) + 1; - } else { - barnum = PCI_BASE_ADDRESS_0 + (j * 4); - mem_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_MEM_MASK; +} - /* Get Size */ - pci_read_config_dword(dev[i], barnum, &currbar); - pci_write_config_dword(dev[i], barnum, ~0); - pci_read_config_dword(dev[i], barnum, &maskbar); - pci_write_config_dword(dev[i], barnum, currbar); +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - mem_len = ~(maskbar & PCI_BASE_ADDRESS_MEM_MASK) + 1; +/***********************************************************************************/ +/* Sort the Device Structures */ +/* Devices are sorted by groups ( type ) and then PCI address within each group */ +/* This also results in the same ordering that results when using the 2.4 kernel */ +/* architecture for initialization. */ +/***********************************************************************************/ + +static void +ips_sort_controllers(struct pci_dev *dev[]) { + struct pci_dev *tempdev[IPS_MAX_ADAPTERS]; + struct pci_dev *lowestdev; + int i, j; + int temp_index = 0; /* Index into tempdev[] array */ + int lowIndex = 0; + int newlowflag = 0; /* Flag to indicate when a new low address has been found */ + uint16_t subdevice_id; + unsigned char BusNumber; + + /* Clear the Temporary Dev Structure */ + for (i = 0; i < IPS_MAX_ADAPTERS; i++) + tempdev[i] = NULL; + + /* The Outer Loop goes thru each Adapter Type Supported */ + for (j = 0; j < IPS_MAX_ADAPTER_TYPES; j++) { + lowestdev = NULL; + /* The Inner Loop Checks each Device still in the List and */ + /* Finds the lowset adapter left ( by PCI boot order ) */ + for (i = 0; i < IPS_MAX_ADAPTERS; i++) { + if (dev[i]) { + if (lowestdev == NULL) { /* If this is the first one found, it must be the lowest ! */ + lowestdev = dev[i]; + lowIndex = i; } -#endif - } - - /* setup memory mapped area (if applicable) */ - if (mem_addr) { - uint32_t base; - uint32_t offs; - - DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d", - ips_name, ips_next_controller, mem_addr, mem_len); -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - if (check_mem_region(mem_addr, mem_len)) { - /* Couldn't allocate io space */ - printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n", - ips_name, ips_next_controller, io_addr, io_len); + /* If you find a Sarasota ( 5i ), it must always be treated as the first adapter */ + if (dev[i]->device == IPS_DEVICEID_MORPHEUS) { + pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id); + if ((subdevice_id == IPS_SUBDEVICEID_5I1) || + (subdevice_id == IPS_SUBDEVICEID_5I2)) { + lowestdev = dev[i]; + lowIndex = i; + break; + } + } - ips_next_controller++; + /* If you find a Sebring ( 6i ), it must always be treated as the first adapter */ + if (dev[i]->device == IPS_DEVICEID_MARCO) { + pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id); + if (subdevice_id == IPS_SUBDEVICEID_6I) { + lowestdev = dev[i]; + lowIndex = i; + break; + } + } - continue; - } + /* Determine if this device is at a lower PCI address than the current lowest device */ + newlowflag = 0; - request_mem_region(mem_addr, mem_len, "ips"); -#endif + if (dev[i]->device == IPS_DEVICEID_MARCO) /* System BIOS adds 1 to Marco Bus Number */ + BusNumber = ( dev[i]->bus->number ) - 1; /* because of Bridge Chip */ + else + BusNumber = dev[i]->bus->number; - base = mem_addr & PAGE_MASK; - offs = mem_addr - base; + if (BusNumber < lowestdev->bus->number) /* IF a lower BUS # */ + newlowflag = i; - ioremap_ptr = ioremap(base, PAGE_SIZE); - mem_ptr = ioremap_ptr + offs; - } else { - ioremap_ptr = NULL; - mem_ptr = NULL; + if ((BusNumber == lowestdev->bus->number) && /* If Same Bus #, but a lower device # */ + (dev[i]->devfn < lowestdev->devfn)) + newlowflag = i; + + if ( newlowflag ) { + lowestdev = dev[i]; + lowIndex = i; + } } - - /* setup I/O mapped area (if applicable) */ - if (io_addr) { - DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d", - ips_name, ips_next_controller, io_addr, io_len); - - if (check_region(io_addr, io_len)) { - /* Couldn't allocate io space */ - printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n", - ips_name, ips_next_controller, io_addr, io_len); - - ips_next_controller++; - - continue; + } + + if (lowestdev) { /* If we found another adapter */ + tempdev[temp_index] = lowestdev; /* Add it in the list */ + dev[lowIndex] = NULL; /* Null it out so we don't find it again */ + temp_index++; + /* Now get all the adapters that are the same type as the low one . */ + /* They will already be in order, so they don't need any further sorting.*/ + for (i = 0; i < IPS_MAX_ADAPTERS; i++) { + if (dev[i]) { + if (dev[i]->device == lowestdev->device) { + tempdev[temp_index] = dev[i]; /* Add the same type adapter to the list */ + temp_index++; + dev[i] = NULL; /* Null it out so we don't find it again */ + } } - - request_region(io_addr, io_len, "ips"); } + } + } - /* get planer status */ - if (pci_read_config_word(dev[i], 0x04, &planer)) { - printk(KERN_WARNING "(%s%d) can't get planer status.\n", - ips_name, ips_next_controller); + /* Copy the Sorted Adapter Pointers ( tempdev[] ) to the Original Structure */ + for (i = 0; i < IPS_MAX_ADAPTERS; i++) + dev[i] = tempdev[i]; - ips_next_controller++; +} - continue; - } +/****************************************************************************/ +/* Detect and initialize the driver for 2.2 kernels */ +/* */ +/* NOTE: this routine is called under the io_request_lock spinlock */ +/****************************************************************************/ +static int ips_init_oldphase1(Scsi_Host_Template *SHT){ + struct Scsi_Host *sh; + ips_ha_t *ha; + uint32_t io_addr; + uint32_t mem_addr; + uint32_t io_len; + uint32_t mem_len; + uint16_t planer; + uint8_t revision_id; + uint8_t bus; + uint8_t func; + uint8_t irq; + uint16_t subdevice_id; + int i; + int j; + uint32_t count; + char *ioremap_ptr; + char *mem_ptr; + struct pci_dev *dev[IPS_MAX_ADAPTERS]; + dma_addr_t dma_address; + uint32_t currbar; + uint32_t maskbar; + uint8_t barnum; + uint32_t IsDead; - /* check to see if an onboard planer controller is disabled */ - if (!(planer & 0x000C)) { + METHOD_TRACE("ips_init_oldphase1", 1); + + for ( i = 0; i < IPS_MAX_ADAPTERS; i++ ) + dev[i] = NULL; + + /* Find all the adapters that we support and save them in the dev[] structure */ + i = 0; + dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_MORPHEUS, NULL); + while ( dev[i] ) { + i++; + dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_MORPHEUS, dev[i-1]); + } + + dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_COPPERHEAD, NULL); + while ( dev[i] ) { + i++; + dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_COPPERHEAD, dev[i-1]); + } + + dev[i] = pci_find_device(IPS_VENDORID_ADAPTEC, IPS_DEVICEID_MARCO, NULL); + while ( dev[i] ) { + i++; + dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_MARCO, dev[i-1]); + } + + /* Sort the Adapters */ + if ( dev[0] ) + ips_sort_controllers( dev ); + else + return (0); - DEBUG_VAR(1, "(%s%d) detect, Onboard ServeRAID disabled by BIOS", - ips_name, ips_next_controller); + /* Now scan and Initialize the controllers */ + for ( i = 0; i < IPS_MAX_ADAPTERS; i++ ) { + if (!dev[i]) + break; - ips_next_controller++; + if (ips_next_controller >= IPS_MAX_ADAPTERS) + break; - continue; - } + /* stuff that we get in dev */ + irq = dev[i]->irq; + bus = dev[i]->bus->number; + func = dev[i]->devfn; + + /* Init MEM/IO addresses to 0 */ + mem_addr = 0; + io_addr = 0; + mem_len = 0; + io_len = 0; - DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %p", - ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, mem_ptr); + for (j = 0; j < 2; j++) { + if (!dev[i]->base_address[j]) + break; - /* get the revision ID */ - if (pci_read_config_byte(dev[i], PCI_REVISION_ID, &revision_id)) { - printk(KERN_WARNING "(%s%d) can't get revision id.\n", - ips_name, ips_next_controller); + if ((dev[i]->base_address[j] & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { + barnum = PCI_BASE_ADDRESS_0 + (j * 4); + io_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_IO_MASK; - ips_next_controller++; + /* Get Size */ + pci_read_config_dword(dev[i], barnum, &currbar); + pci_write_config_dword(dev[i], barnum, ~0); + pci_read_config_dword(dev[i], barnum, &maskbar); + pci_write_config_dword(dev[i], barnum, currbar); - continue; - } + io_len = ~(maskbar & PCI_BASE_ADDRESS_IO_MASK) + 1; + } else { + barnum = PCI_BASE_ADDRESS_0 + (j * 4); + mem_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_MEM_MASK; -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - /* get the subdevice id */ - if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) { - printk(KERN_WARNING "(%s%d) can't get subdevice id.\n", - ips_name, ips_next_controller); + /* Get Size */ + pci_read_config_dword(dev[i], barnum, &currbar); + pci_write_config_dword(dev[i], barnum, ~0); + pci_read_config_dword(dev[i], barnum, &maskbar); + pci_write_config_dword(dev[i], barnum, currbar); - ips_next_controller++; - - continue; + mem_len = ~(maskbar & PCI_BASE_ADDRESS_MEM_MASK) + 1; } -#else - subdevice_id = dev[i]->subsystem_device; -#endif - - /* found a controller */ - sh = scsi_register(SHT, sizeof(ips_ha_t)); - - if (sh == NULL) { - printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n", - ips_name, ips_next_controller); - - ips_next_controller++; + } - continue; - } + /* setup memory mapped area (if applicable) */ + if (mem_addr) { + uint32_t base; + uint32_t offs; - ha = IPS_HA(sh); - memset(ha, 0, sizeof(ips_ha_t)); + DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d", + ips_name, ips_next_controller, mem_addr, mem_len); - /* Initialize spin lock */ - spin_lock_init(&ha->scb_lock); - spin_lock_init(&ha->copp_lock); - spin_lock_init(&ha->ips_lock); - spin_lock_init(&ha->copp_waitlist.lock); - spin_lock_init(&ha->scb_waitlist.lock); - spin_lock_init(&ha->scb_activelist.lock); - - ips_sh[ips_next_controller] = sh; - ips_ha[ips_next_controller] = ha; - ips_num_controllers++; - ha->active = 1; + base = mem_addr & PAGE_MASK; + offs = mem_addr - base; - ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL); + ioremap_ptr = ioremap(base, PAGE_SIZE); + mem_ptr = ioremap_ptr + offs; + } else { + ioremap_ptr = NULL; + mem_ptr = NULL; + } - if (!ha->enq) { - printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n", - ips_name, ips_next_controller); + /* setup I/O mapped area (if applicable) */ + if (io_addr) { + DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d", + ips_name, ips_next_controller, io_addr, io_len); + + if (check_region(io_addr, io_len)) { + /* Couldn't allocate io space */ + printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n", + ips_name, ips_next_controller, io_addr, io_len); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; ips_next_controller++; - ips_num_controllers--; continue; } - ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL); + request_region(io_addr, io_len, "ips"); + } - if (!ha->adapt) { - printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n", - ips_name, ips_next_controller); + /* get planer status */ + if (pci_read_config_word(dev[i], 0x04, &planer)) { + printk(KERN_WARNING "(%s%d) can't get planer status.\n", + ips_name, ips_next_controller); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - ips_next_controller++; - ips_num_controllers--; + ips_next_controller++; - continue; - } + continue; + } - ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); + /* check to see if an onboard planer controller is disabled */ + if (!(planer & 0x000C)) { - if (!ha->conf) { - printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n", + DEBUG_VAR(1, "(%s%d) detect, Onboard controller disabled by BIOS", ips_name, ips_next_controller); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - ips_next_controller++; - ips_num_controllers--; + ips_next_controller++; - continue; - } + continue; + } - ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); + DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %p", + ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, mem_ptr); - if (!ha->nvram) { - printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n", - ips_name, ips_next_controller); + /* get the revision ID */ + if (pci_read_config_byte(dev[i], PCI_REVISION_ID, &revision_id)) { + printk(KERN_WARNING "(%s%d) can't get revision id.\n", + ips_name, ips_next_controller); + + ips_next_controller++; + continue; + } + + /* get the subdevice id */ + if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) { + printk(KERN_WARNING "(%s%d) can't get subdevice id.\n", + ips_name, ips_next_controller); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - ips_next_controller++; - ips_num_controllers--; + ips_next_controller++; - continue; - } + continue; + } - ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); + /* found a controller */ + sh = scsi_register(SHT, sizeof(ips_ha_t)); - if (!ha->subsys) { - printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n", - ips_name, ips_next_controller); + if (sh == NULL) { + printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n", + ips_name, ips_next_controller); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - ips_next_controller++; - ips_num_controllers--; + ips_next_controller++; - continue; - } + continue; + } - ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL); + ha = IPS_HA(sh); + memset(ha, 0, sizeof(ips_ha_t)); - if (!ha->dummy) { - printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n", - ips_name, ips_next_controller); + ips_sh[ips_next_controller] = sh; + ips_ha[ips_next_controller] = ha; + ips_num_controllers++; + ha->active = 1; + + ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL); + + if (!ha->enq) { + printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); + ips_next_controller++; + ips_num_controllers--; - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - ips_next_controller++; - ips_num_controllers--; + continue; + } - continue; - } + ha->adapt = pci_alloc_consistent(dev[i], sizeof(IPS_ADAPTER) + sizeof(IPS_IO_CMD), &dma_address); - for (count = PAGE_SIZE, ha->ioctl_order = 0; - count < ips_ioctlsize; - ha->ioctl_order++, count <<= 1); + if (!ha->adapt) { + printk(KERN_WARNING "(%s%d) Unable to allocate host adapt and dummy structure - skipping controller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); + ips_next_controller++; + ips_num_controllers--; - ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order); - ha->ioctl_datasize = count; + continue; + } + ha->adapt->hw_status_start = dma_address; + ha->dummy = (void *)ha->adapt + 1; - if (!ha->ioctl_data) { - printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data\n", - ips_name, ips_next_controller); + ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); - ha->ioctl_data = NULL; - ha->ioctl_order = 0; - ha->ioctl_datasize = 0; - } + if (!ha->conf) { + printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); + ips_next_controller++; + ips_num_controllers--; - /* Store away needed values for later use */ - sh->io_port = io_addr; - sh->n_io_port = io_addr ? 255 : 0; - sh->unique_id = (io_addr) ? io_addr : mem_addr; - sh->irq = irq; - sh->select_queue_depths = ips_select_queue_depth; - sh->sg_tablesize = sh->hostt->sg_tablesize; - sh->can_queue = sh->hostt->can_queue; - sh->cmd_per_lun = sh->hostt->cmd_per_lun; - sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; - sh->use_clustering = sh->hostt->use_clustering; + continue; + } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) - sh->max_sectors = 128; -#endif + ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - sh->wish_block = FALSE; -#endif + if (!ha->nvram) { + printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); + ips_next_controller++; + ips_num_controllers--; - /* Store info in HA structure */ - ha->irq = irq; - ha->io_addr = io_addr; - ha->io_len = io_len; - ha->mem_addr = mem_addr; - ha->mem_len = mem_len; - ha->mem_ptr = mem_ptr; - ha->ioremap_ptr = ioremap_ptr; - ha->host_num = ips_next_controller; - ha->revision_id = revision_id; - ha->slot_num = PCI_SLOT(dev[i]->devfn); - ha->device_id = deviceID[i]; - ha->subdevice_id = subdevice_id; - ha->pcidev = dev[i]; + continue; + } - /* - * Setup Functions - */ - if (IPS_IS_MORPHEUS(ha)) { - /* morpheus */ - ha->func.isintr = ips_isintr_morpheus; - ha->func.isinit = ips_isinit_morpheus; - ha->func.issue = ips_issue_i2o_memio; - ha->func.init = ips_init_morpheus; - ha->func.statupd = ips_statupd_morpheus; - ha->func.reset = ips_reset_morpheus; - ha->func.intr = ips_intr_morpheus; - ha->func.enableint = ips_enable_int_morpheus; - } else if (IPS_USE_MEMIO(ha)) { - /* copperhead w/MEMIO */ - ha->func.isintr = ips_isintr_copperhead_memio; - ha->func.isinit = ips_isinit_copperhead_memio; - ha->func.init = ips_init_copperhead_memio; - ha->func.statupd = ips_statupd_copperhead_memio; - ha->func.statinit = ips_statinit_memio; - ha->func.reset = ips_reset_copperhead_memio; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios_memio; - ha->func.programbios = ips_program_bios_memio; - ha->func.verifybios = ips_verify_bios_memio; - ha->func.enableint = ips_enable_int_copperhead_memio; + ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o_memio; - else - ha->func.issue = ips_issue_copperhead_memio; - } else { - /* copperhead */ - ha->func.isintr = ips_isintr_copperhead; - ha->func.isinit = ips_isinit_copperhead; - ha->func.init = ips_init_copperhead; - ha->func.statupd = ips_statupd_copperhead; - ha->func.statinit = ips_statinit; - ha->func.reset = ips_reset_copperhead; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios; - ha->func.programbios = ips_program_bios; - ha->func.verifybios = ips_verify_bios; - ha->func.enableint = ips_enable_int_copperhead; + if (!ha->subsys) { + printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); + ips_next_controller++; + ips_num_controllers--; - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o; - else - ha->func.issue = ips_issue_copperhead; - } - - /* If Morpheus appears dead, reset it */ - if ( IPS_IS_MORPHEUS( ha ) ) { - IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 ); - if ( IsDead == 0xDEADBEEF ) { - ips_reset_morpheus( ha ); - } - } + continue; + } - /* - * Initialize the card if it isn't already - */ + for (count = PAGE_SIZE, ha->ioctl_order = 0; + count < ips_ioctlsize; + ha->ioctl_order++, count <<= 1); + + ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order); + ha->ioctl_datasize = count; + + if (!ha->ioctl_data) { + printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data\n", + ips_name, ips_next_controller); - if (!(*ha->func.isinit)(ha)) { - if (!(*ha->func.init)(ha)) { - /* - * Initialization failed - */ - printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping controller\n", - ips_name, ips_next_controller); + ha->ioctl_data = NULL; + ha->ioctl_order = 0; + ha->ioctl_datasize = 0; + } - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - ips_next_controller++; - ips_num_controllers--; + /* Store away needed values for later use */ + sh->io_port = io_addr; + sh->n_io_port = io_addr ? 255 : 0; + sh->unique_id = (io_addr) ? io_addr : mem_addr; + sh->irq = irq; + sh->select_queue_depths = ips_select_queue_depth; + sh->sg_tablesize = sh->hostt->sg_tablesize; + sh->can_queue = sh->hostt->can_queue; + sh->cmd_per_lun = sh->hostt->cmd_per_lun; + sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; + sh->use_clustering = sh->hostt->use_clustering; + + sh->wish_block = FALSE; + + /* Store info in HA structure */ + ha->irq = irq; + ha->io_addr = io_addr; + ha->io_len = io_len; + ha->mem_addr = mem_addr; + ha->mem_len = mem_len; + ha->mem_ptr = mem_ptr; + ha->ioremap_ptr = ioremap_ptr; + ha->host_num = ips_next_controller; + ha->revision_id = revision_id; + ha->slot_num = PCI_SLOT(dev[i]->devfn); + ha->device_id = dev[i]->device; + ha->subdevice_id = subdevice_id; + ha->pcidev = dev[i]; - continue; - } - } + /* + * Setup Functions + */ + ips_setup_funclist(ha); + + /* If Morpheus appears dead, reset it */ + if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) { + IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 ); + if ( IsDead == 0xDEADBEEF ) { + ips_reset_morpheus( ha ); + } + } - /* install the interrupt handler */ - if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { - printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n", - ips_name, ips_next_controller); + /* + * Initialize the card if it isn't already + */ - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; + if (!(*ha->func.isinit)(ha)) { + if (!(*ha->func.init)(ha)) { + /* + * Initialization failed + */ + printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping controller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); ips_next_controller++; ips_num_controllers--; continue; } + } - /* - * Allocate a temporary SCB for initialization - */ - ha->max_cmds = 1; - if (!ips_allocatescbs(ha)) { - /* couldn't allocate a temp SCB */ - printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n", - ips_name, ips_next_controller); - - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[ips_next_controller] = 0; - ips_sh[ips_next_controller] = 0; - free_irq(ha->irq, ha); - ips_next_controller++; - ips_num_controllers--; + /* install the interrupt handler */ + if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { + printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n", + ips_name, ips_next_controller); + ips_abort_init(ha, sh, ips_next_controller); + ips_next_controller++; + ips_num_controllers--; - continue; - } + continue; + } + /* + * Allocate a temporary SCB for initialization + */ + ha->max_cmds = 1; + if (!ips_allocatescbs(ha)) { + /* couldn't allocate a temp SCB */ + printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n", + ips_name, ips_next_controller); + free_irq(ha->irq, ha); + ips_abort_init(ha, sh, ips_next_controller); ips_next_controller++; - } while ((dev[i] = pci_find_device(IPS_VENDORID, deviceID[i], dev[i]))); + ips_num_controllers--; + + continue; + } + + ips_next_controller++; } /* @@ -1252,12 +1320,64 @@ register_reboot_notifier(&ips_notifier); return (ips_num_controllers); +} +#endif -#else +/****************************************************************************/ +/* configure the function pointers to use the functions that will work */ +/* with the found version of the adapter */ +/****************************************************************************/ +static void ips_setup_funclist(ips_ha_t *ha){ - /* No PCI -- No ServeRAID */ - return (0); -#endif /* CONFIG_PCI */ + /* + * Setup Functions + */ + if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { + /* morpheus / marco / sebring */ + ha->func.isintr = ips_isintr_morpheus; + ha->func.isinit = ips_isinit_morpheus; + ha->func.issue = ips_issue_i2o_memio; + ha->func.init = ips_init_morpheus; + ha->func.statupd = ips_statupd_morpheus; + ha->func.reset = ips_reset_morpheus; + ha->func.intr = ips_intr_morpheus; + ha->func.enableint = ips_enable_int_morpheus; + } else if (IPS_USE_MEMIO(ha)) { + /* copperhead w/MEMIO */ + ha->func.isintr = ips_isintr_copperhead_memio; + ha->func.isinit = ips_isinit_copperhead_memio; + ha->func.init = ips_init_copperhead_memio; + ha->func.statupd = ips_statupd_copperhead_memio; + ha->func.statinit = ips_statinit_memio; + ha->func.reset = ips_reset_copperhead_memio; + ha->func.intr = ips_intr_copperhead; + ha->func.erasebios = ips_erase_bios_memio; + ha->func.programbios = ips_program_bios_memio; + ha->func.verifybios = ips_verify_bios_memio; + ha->func.enableint = ips_enable_int_copperhead_memio; + if (IPS_USE_I2O_DELIVER(ha)) + ha->func.issue = ips_issue_i2o_memio; + else + ha->func.issue = ips_issue_copperhead_memio; + } else { + /* copperhead */ + ha->func.isintr = ips_isintr_copperhead; + ha->func.isinit = ips_isinit_copperhead; + ha->func.init = ips_init_copperhead; + ha->func.statupd = ips_statupd_copperhead; + ha->func.statinit = ips_statinit; + ha->func.reset = ips_reset_copperhead; + ha->func.intr = ips_intr_copperhead; + ha->func.erasebios = ips_erase_bios; + ha->func.programbios = ips_program_bios; + ha->func.verifybios = ips_verify_bios; + ha->func.enableint = ips_enable_int_copperhead; + + if (IPS_USE_I2O_DELIVER(ha)) + ha->func.issue = ips_issue_i2o; + else + ha->func.issue = ips_issue_copperhead; + } } /****************************************************************************/ @@ -1309,13 +1429,15 @@ scb->cmd.flush_cache.reserved3 = 0; scb->cmd.flush_cache.reserved4 = 0; - printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); + if (InitState != 0) /* If Not just Searching for the Adapter Order Table */ + printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); /* send command */ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); - printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num); + if (InitState != 0) /* If Not just Searching for the Adapter Order Table */ + printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num); ips_sh[i] = NULL; ips_ha[i] = NULL; @@ -1332,12 +1454,14 @@ scsi_unregister(sh); - ips_released_controllers++; - - if (ips_num_controllers == ips_released_controllers){ - unregister_reboot_notifier(&ips_notifier); - pci_unregister_driver(&ips_pci_driver); + if (InitState != 0) { + ips_released_controllers++; + if (ips_num_controllers == ips_released_controllers){ + unregister_reboot_notifier(&ips_notifier); + pci_unregister_driver(ha->pcidev->driver); + } } + return (FALSE); } @@ -1404,12 +1528,13 @@ /* Routine Description: */ /* */ /* Abort a command (using the new error code stuff) */ -/* */ +/* Note: this routine is called under the io_request_lock */ /****************************************************************************/ int ips_eh_abort(Scsi_Cmnd *SC) { ips_ha_t *ha; ips_copp_wait_item_t *item; + int ret; METHOD_TRACE("ips_eh_abort", 1); @@ -1431,36 +1556,25 @@ return (FAILED); } - if (test_and_set_bit(IPS_IN_ABORT, &ha->flags)) - return (FAILED); - /* See if the command is on the copp queue */ - IPS_QUEUE_LOCK(&ha->copp_waitlist); item = ha->copp_waitlist.head; while ((item) && (item->scsi_cmd != SC)) item = item->next; - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); if (item) { /* Found it */ ips_removeq_copp(&ha->copp_waitlist, item); - clear_bit(IPS_IN_ABORT, &ha->flags); - - return (SUCCESS); - } + ret = (SUCCESS); /* See if the command is on the wait queue */ - if (ips_removeq_wait(&ha->scb_waitlist, SC)) { + } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) { /* command not sent yet */ - clear_bit(IPS_IN_ABORT, &ha->flags); - - return (SUCCESS); + ret = (SUCCESS); } else { /* command must have already been sent */ - clear_bit(IPS_IN_ABORT, &ha->flags); - - return (FAILED); + ret = (FAILED); } + return ret; } /****************************************************************************/ @@ -1481,7 +1595,6 @@ ips_ha_t *ha; ips_scb_t *scb; ips_copp_wait_item_t *item; - unsigned long cpu_flags; METHOD_TRACE("ips_eh_reset", 1); @@ -1506,36 +1619,27 @@ if (!ha->active) return (FAILED); - if (test_and_set_bit(IPS_IN_RESET, &ha->flags)) - return (FAILED); - /* See if the command is on the copp queue */ - IPS_QUEUE_LOCK(&ha->copp_waitlist); item = ha->copp_waitlist.head; while ((item) && (item->scsi_cmd != SC)) item = item->next; - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); if (item) { /* Found it */ ips_removeq_copp(&ha->copp_waitlist, item); - clear_bit(IPS_IN_RESET, &ha->flags); - return (SUCCESS); } /* See if the command is on the wait queue */ if (ips_removeq_wait(&ha->scb_waitlist, SC)) { /* command not sent yet */ - clear_bit(IPS_IN_RESET, &ha->flags); - return (SUCCESS); } /* An explanation for the casual observer: */ /* Part of the function of a RAID controller is automatic error */ /* detection and recovery. As such, the only problem that physically */ - /* resetting a ServeRAID adapter will ever fix is when, for some reason,*/ + /* resetting an adapter will ever fix is when, for some reason, */ /* the driver is not successfully communicating with the adapter. */ /* Therefore, we will attempt to flush this adapter. If that succeeds, */ /* then there's no real purpose in a physical reset. This will complete */ @@ -1562,13 +1666,12 @@ ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); if (ret == IPS_SUCCESS) { printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num); - clear_bit(IPS_IN_RESET, &ha->flags); return (SUCCESS); } } /* Either we can't communicate with the adapter or it's an IOCTL request */ - /* from a ServeRAID utility. A physical reset is needed at this point. */ + /* from a utility. A physical reset is needed at this point. */ ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ @@ -1607,8 +1710,6 @@ } ha->active = FALSE; - clear_bit(IPS_IN_RESET, &ha->flags); - return (FAILED); } @@ -1639,8 +1740,6 @@ } ha->active = FALSE; - clear_bit(IPS_IN_RESET, &ha->flags); - return (FAILED); } @@ -1649,10 +1748,8 @@ struct timeval tv; do_gettimeofday(&tv); - IPS_HA_LOCK(cpu_flags); ha->last_ffdc = tv.tv_sec; ha->reset_count++; - IPS_HA_UNLOCK(cpu_flags); ips_ffdc_reset(ha, IPS_INTR_IORL); } @@ -1671,25 +1768,11 @@ ha->dcdb_active[i-1] = 0; /* Reset the number of active IOCTLs */ - IPS_HA_LOCK(cpu_flags); ha->num_ioctl = 0; - IPS_HA_UNLOCK(cpu_flags); - - clear_bit(IPS_IN_RESET, &ha->flags); - if (!test_bit(IPS_IN_INTR, &ha->flags)) { - /* - * Only execute the next command when - * we are not being called from the - * interrupt handler. The interrupt - * handler wants to do this and since - * interrupts are turned off here.... - */ - ips_next(ha, IPS_INTR_IORL); - } + ips_next(ha, IPS_INTR_IORL); return (SUCCESS); - #endif /* NO_IPS_RESET */ } @@ -1709,7 +1792,6 @@ int ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { ips_ha_t *ha; - unsigned long cpu_flags; ips_passthru_t *pt; METHOD_TRACE("ips_queue", 1); @@ -1723,28 +1805,17 @@ return (DID_ERROR); if (ips_is_passthru(SC)) { - IPS_QUEUE_LOCK(&ha->copp_waitlist); if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); SC->result = DID_BUS_BUSY << 16; done(SC); return (0); - } else { - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); - } - } else { - IPS_QUEUE_LOCK(&ha->scb_waitlist); - if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { - IPS_QUEUE_UNLOCK(&ha->scb_waitlist); - SC->result = DID_BUS_BUSY << 16; - done(SC); - - return (0); - } else { - IPS_QUEUE_UNLOCK(&ha->scb_waitlist); } + } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + return (0); } SC->scsi_done = done; @@ -1769,7 +1840,7 @@ ips_copp_wait_item_t *scratch; - /* A Reset IOCTL is only sent by the ServeRAID boot CD in extreme cases. */ + /* A Reset IOCTL is only sent by the boot CD in extreme cases. */ /* There can never be any system activity ( network or disk ), but check */ /* anyway just as a good practice. */ pt = (ips_passthru_t *) SC->request_buffer; @@ -1798,27 +1869,15 @@ } scratch->scsi_cmd = SC; - sema_init(&ha->ioctl_sem, 0); - scratch->sem = &ha->ioctl_sem; scratch->next = NULL; ips_putq_copp_tail(&ha->copp_waitlist, scratch); } - else + else { ips_putq_wait_tail(&ha->scb_waitlist, SC); - - if(ha->scb_waitlist.count + ha->scb_activelist.count > 32) - mod_timer(&SC->eh_timeout, jiffies + 120 * HZ); - - IPS_HA_LOCK(cpu_flags); - if ((!test_bit(IPS_IN_INTR, &ha->flags)) && - (!test_bit(IPS_IN_ABORT, &ha->flags)) && - (!test_bit(IPS_IN_RESET, &ha->flags))) { - IPS_HA_UNLOCK(cpu_flags); - ips_next(ha, IPS_INTR_IORL); - } else { - IPS_HA_UNLOCK(cpu_flags); } + + ips_next(ha, IPS_INTR_IORL); /* If We were using the CD Boot Flash Buffer, Restore the Old Values */ if ( ips_FlashData == ha->ioctl_data ) { @@ -1938,33 +1997,24 @@ do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) { ips_ha_t *ha; unsigned long cpu_flags; + struct Scsi_Host *host; METHOD_TRACE("do_ipsintr", 2); ha = (ips_ha_t *) dev_id; if (!ha) return; - - spin_lock_irqsave(&io_request_lock, cpu_flags); - - if (test_and_set_bit(IPS_IN_INTR, &ha->flags)) { - spin_unlock_irqrestore(&io_request_lock, cpu_flags); - - return ; - } + host = ips_sh[ha->host_num]; + IPS_LOCK_SAVE(host->host_lock, cpu_flags); if (!ha->active) { - clear_bit(IPS_IN_INTR, &ha->flags); - spin_unlock_irqrestore(&io_request_lock, cpu_flags); - + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); return; } (*ha->func.intr)(ha); - clear_bit(IPS_IN_INTR, &ha->flags); - - spin_unlock_irqrestore(&io_request_lock, cpu_flags); + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* start the next command */ ips_next(ha, IPS_INTR_ON); @@ -1987,7 +2037,6 @@ ips_scb_t *scb; IPS_STATUS cstatus; int intrstatus; - unsigned long cpu_flags; METHOD_TRACE("ips_intr", 2); @@ -1997,15 +2046,12 @@ if (!ha->active) return; - IPS_HA_LOCK(cpu_flags); - intrstatus = (*ha->func.isintr)(ha); if (!intrstatus) { /* * Unexpected/Shared interrupt */ - IPS_HA_UNLOCK(cpu_flags); return; } @@ -2032,12 +2078,8 @@ * use the callback function to finish things up * NOTE: interrupts are OFF for this */ - IPS_HA_UNLOCK(cpu_flags); (*scb->callback) (ha, scb); - IPS_HA_LOCK(cpu_flags); } /* end while */ - - IPS_HA_UNLOCK(cpu_flags); } /****************************************************************************/ @@ -2057,7 +2099,6 @@ ips_scb_t *scb; IPS_STATUS cstatus; int intrstatus; - unsigned long cpu_flags; METHOD_TRACE("ips_intr_morpheus", 2); @@ -2067,15 +2108,12 @@ if (!ha->active) return; - IPS_HA_LOCK(cpu_flags); - intrstatus = (*ha->func.isintr)(ha); if (!intrstatus) { /* * Unexpected/Shared interrupt */ - IPS_HA_UNLOCK(cpu_flags); return; } @@ -2108,12 +2146,8 @@ * use the callback function to finish things up * NOTE: interrupts are OFF for this */ - IPS_HA_UNLOCK(cpu_flags); (*scb->callback) (ha, scb); - IPS_HA_LOCK(cpu_flags); } /* end while */ - - IPS_HA_UNLOCK(cpu_flags); } /****************************************************************************/ @@ -2231,7 +2265,7 @@ return 1; else if(SC->use_sg){ struct scatterlist *sg = SC->request_buffer; - char *buffer = sg[0].address; + char *buffer = IPS_SG_ADDRESS(sg); if(buffer && buffer[0] == 'C' && buffer[1] == 'O' && buffer[2] == 'P' && buffer[3] == 'P') return 1; @@ -2288,7 +2322,7 @@ ha->ioctl_order = order; ha->ioctl_datasize = count; } else { - pt = (ips_passthru_t*)sg[0].address; + pt = (ips_passthru_t*)IPS_SG_ADDRESS(sg); pt->BasicStatus = 0x0B; pt->ExtendedStatus = 0x00; SC->result = DID_ERROR << 16; @@ -2298,7 +2332,7 @@ ha->ioctl_datasize = length; length = 0; for(i = 0; i < SC->use_sg; i++){ - memcpy(&ha->ioctl_data[length], sg[i].address, sg[i].length); + memcpy(&ha->ioctl_data[length], IPS_SG_ADDRESS(&sg[i]), sg[i].length); length += sg[i].length; } pt = (ips_passthru_t *)ha->ioctl_data; @@ -2327,13 +2361,6 @@ * packet we received from the sg driver. In this * case the CmdBSize field of the pt structure is * used for the size of the buffer. - * - * IF the scsi op_code == 0x81 then we assume that - * we will need our own buffer and we will copy the - * data to/from the user buffer passed in the scsi - * command. The data address resides at offset 4 - * in the scsi command. The length of the data resides - * at offset 8 in the scsi command. */ switch (pt->CoppCmd) { @@ -2499,6 +2526,7 @@ static int ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){ IPS_SG_LIST *sg_list; + uint32_t cmd_busaddr; if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE && pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW ){ @@ -2513,11 +2541,12 @@ } /* Save the S/G list pointer so it doesn't get clobbered */ sg_list = scb->sg_list; + cmd_busaddr = scb->scb_busaddr; /* copy in the CP */ memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD)); /* FIX stuff that might be wrong */ scb->sg_list = sg_list; - scb->scb_busaddr = VIRT_TO_BUS(scb); + scb->scb_busaddr = cmd_busaddr; scb->bus = scb->scsi_cmd->channel; scb->target_id = scb->scsi_cmd->target; scb->lun = scb->scsi_cmd->lun; @@ -2527,8 +2556,13 @@ scb->op_code = 0; scb->callback = ipsintr_done; scb->timeout = ips_cmd_timeout; + + scb->data_len = ha->flash_datasize; + scb->data_busaddr = pci_map_single(ha->pcidev, ha->flash_data, scb->data_len, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flashfw.buffer_addr = VIRT_TO_BUS(ha->flash_data); + scb->cmd.flashfw.buffer_addr = scb->data_busaddr; if (pt->TimeOut) scb->timeout = pt->TimeOut; scb->scsi_cmd->result = DID_OK <<16; @@ -2561,6 +2595,7 @@ static int ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { IPS_SG_LIST *sg_list; + uint32_t cmd_busaddr; METHOD_TRACE("ips_usrcmd", 1); @@ -2569,14 +2604,14 @@ /* Save the S/G list pointer so it doesn't get clobbered */ sg_list = scb->sg_list; - + cmd_busaddr = scb->scb_busaddr; /* copy in the CP */ memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD)); memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE)); /* FIX stuff that might be wrong */ scb->sg_list = sg_list; - scb->scb_busaddr = VIRT_TO_BUS(scb); + scb->scb_busaddr = cmd_busaddr; scb->bus = scb->scsi_cmd->channel; scb->target_id = scb->scsi_cmd->target; scb->lun = scb->scsi_cmd->lun; @@ -2595,16 +2630,31 @@ return (0); if (pt->CmdBSize) { - if(!scb->scsi_cmd->use_sg) - scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t)); - else - scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data + sizeof(ips_passthru_t)); + if(!scb->scsi_cmd->use_sg){ + scb->data_len = pt->CmdBSize; + scb->data_busaddr = pci_map_single(ha->pcidev, + scb->scsi_cmd->request_buffer + + sizeof(ips_passthru_t), + pt->CmdBSize, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + } else { + scb->data_len = pt->CmdBSize; + scb->data_busaddr = pci_map_single(ha->pcidev, + ha->ioctl_data + + sizeof(ips_passthru_t), + pt->CmdBSize, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + } } else { scb->data_busaddr = 0L; } if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb)); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + + (unsigned long)&scb->dcdb - + (unsigned long)scb); if (pt->CmdBSize) { if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) @@ -2675,7 +2725,7 @@ int i, length = 0; struct scatterlist *sg = scb->scsi_cmd->request_buffer; for(i = 0; i < scb->scsi_cmd->use_sg; i++){ - memcpy(sg[i].address, &ha->ioctl_data[length], sg[i].length); + memcpy(IPS_SG_ADDRESS(&sg[i]), &ha->ioctl_data[length], sg[i].length); length += sg[i].length; } } @@ -2885,6 +2935,17 @@ } break; + + case IPS_DEVICEID_MARCO: + switch (ha->subdevice_id) { + case IPS_SUBDEVICEID_6M: + ha->ad_type = IPS_ADTYPE_SERVERAID6M; + break; + case IPS_SUBDEVICEID_6I: + ha->ad_type = IPS_ADTYPE_SERVERAID6I; + break; + } + break; } } @@ -3013,9 +3074,13 @@ scb->cmd.flashfw.type = 1; scb->cmd.flashfw.direction = 0; scb->cmd.flashfw.count = cpu_to_le32(0x800); - scb->cmd.flashfw.buffer_addr = cpu_to_le32(VIRT_TO_BUS(buffer)); scb->cmd.flashfw.total_packets = 1; scb->cmd.flashfw.packet_num = 0; + scb->data_len = 0x1000; + scb->data_busaddr = pci_map_single(ha->pcidev, buffer, scb->data_len, + IPS_DMA_DIR(scb)); + scb->cmd.flashfw.buffer_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; /* issue the command */ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || @@ -3113,6 +3178,10 @@ return (0); } + /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */ + if ( (ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1) ) + ips_clear_adapter(ha, IPS_INTR_IORL); + /* set limits on SID, LUN, BUS */ ha->ntargets = IPS_MAX_TARGETS + 1; ha->nlun = 1; @@ -3198,39 +3267,31 @@ Scsi_Cmnd *q; ips_copp_wait_item_t *item; int ret; - unsigned long cpu_flags; - unsigned long cpu_flags2 = 0; - + unsigned long cpu_flags = 0; + struct Scsi_Host *host; METHOD_TRACE("ips_next", 1); if (!ha) return ; - + host = ips_sh[ha->host_num]; /* * Block access to the queue function so * this command won't time out */ - if (intr == IPS_INTR_ON) - spin_lock_irqsave(&io_request_lock, cpu_flags2); + if(intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) { struct timeval tv; do_gettimeofday(&tv); - IPS_HA_LOCK(cpu_flags); if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { ha->last_ffdc = tv.tv_sec; - IPS_HA_UNLOCK(cpu_flags); ips_ffdc_time(ha); - } else { - IPS_HA_UNLOCK(cpu_flags); } } - if (intr == IPS_INTR_ON) - spin_unlock_irqrestore(&io_request_lock, cpu_flags2); - /* * Send passthru commands * These have priority over normal I/O @@ -3238,22 +3299,21 @@ * since we limit the number that can be active * on the card at any one time */ - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->copp_waitlist); while ((ha->num_ioctl < IPS_MAX_IOCTL) && (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) { - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); item = ips_removeq_copp_head(&ha->copp_waitlist); ha->num_ioctl++; - IPS_HA_UNLOCK(cpu_flags); + if(intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); scb->scsi_cmd = item->scsi_cmd; - scb->sem = item->sem; kfree(item); ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); + if(intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); switch (ret) { case IPS_FAILURE: if (scb->scsi_cmd) { @@ -3276,8 +3336,6 @@ } /* end case */ if (ret != IPS_SUCCESS) { - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->copp_waitlist); ha->num_ioctl--; continue; } @@ -3304,20 +3362,14 @@ break; } /* end case */ - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->copp_waitlist); } - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); - IPS_HA_UNLOCK(cpu_flags); /* * Send "Normal" I/O commands */ - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->scb_waitlist); + p = ha->scb_waitlist.head; - IPS_QUEUE_UNLOCK(&ha->scb_waitlist); while ((p) && (scb = ips_getscb(ha))) { if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) { ips_freescb(ha, scb); @@ -3327,10 +3379,9 @@ q = p; SC = ips_removeq_wait(&ha->scb_waitlist, q); - if (SC == NULL) /* Should never happen, but good to check anyway */ - continue; - IPS_HA_UNLOCK(cpu_flags); /* Unlock HA after command is taken off queue */ + if(intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */ SC->result = DID_OK; SC->host_scribble = NULL; @@ -3356,7 +3407,8 @@ int i; sg = SC->request_buffer; - scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, PCI_DMA_BIDIRECTIONAL); + scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, + scsi_to_pci_dma_dir(SC->sc_data_direction)); scb->flags |= IPS_SCB_MAP_SG; if (scb->sg_count == 1) { if (sg_dma_len(sg) > ha->max_xfer) { @@ -3416,7 +3468,8 @@ scb->dcdb.transfer_length = scb->data_len; scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer, - scb->data_len, PCI_DMA_BIDIRECTIONAL); + scb->data_len, + scsi_to_pci_dma_dir(SC->sc_data_direction)); scb->flags |= IPS_SCB_MAP_SINGLE; scb->sg_len = 0; } else { @@ -3437,13 +3490,15 @@ scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; scb->dcdb.transfer_length = 0; } - + if(intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + ret = ips_send_cmd(ha, scb); - if (ret == IPS_SUCCESS) - ips_putq_scb_head(&ha->scb_activelist, scb); - switch(ret) { + case IPS_SUCCESS: + ips_putq_scb_head(&ha->scb_activelist, scb); + break; case IPS_FAILURE: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_ERROR << 16; @@ -3470,10 +3525,10 @@ p = (Scsi_Cmnd *) p->host_scribble; - IPS_HA_LOCK(cpu_flags); } /* end while */ - IPS_HA_UNLOCK(cpu_flags); + if(intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); } /****************************************************************************/ @@ -3484,7 +3539,7 @@ /* */ /* Add an item to the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3494,8 +3549,6 @@ if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->q_next = queue->head; queue->head = item; @@ -3503,8 +3556,6 @@ queue->tail = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3515,7 +3566,7 @@ /* */ /* Add an item to the tail of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3525,8 +3576,6 @@ if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->q_next = NULL; if (queue->tail) @@ -3538,8 +3587,6 @@ queue->head = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3550,7 +3597,7 @@ /* */ /* Remove the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_scb_t * @@ -3559,13 +3606,9 @@ METHOD_TRACE("ips_removeq_scb_head", 1); - IPS_QUEUE_LOCK(queue); - item = queue->head; if (!item) { - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3577,8 +3620,6 @@ queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } @@ -3590,7 +3631,7 @@ /* */ /* Remove an item from a queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_scb_t * @@ -3602,11 +3643,7 @@ if (!item) return (NULL); - IPS_QUEUE_LOCK(queue); - if (item == queue->head) { - IPS_QUEUE_UNLOCK(queue); - return (ips_removeq_scb_head(queue)); } @@ -3625,13 +3662,9 @@ item->q_next = NULL; queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3643,7 +3676,7 @@ /* */ /* Add an item to the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3653,8 +3686,6 @@ if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->host_scribble = (char *) queue->head; queue->head = item; @@ -3662,8 +3693,6 @@ queue->tail = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3674,7 +3703,7 @@ /* */ /* Add an item to the tail of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3684,8 +3713,6 @@ if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->host_scribble = NULL; if (queue->tail) @@ -3697,8 +3724,6 @@ queue->head = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3709,7 +3734,7 @@ /* */ /* Remove the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline Scsi_Cmnd * @@ -3718,13 +3743,9 @@ METHOD_TRACE("ips_removeq_wait_head", 1); - IPS_QUEUE_LOCK(queue); - item = queue->head; if (!item) { - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3736,8 +3757,6 @@ queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } @@ -3749,7 +3768,7 @@ /* */ /* Remove an item from a queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline Scsi_Cmnd * @@ -3761,11 +3780,7 @@ if (!item) return (NULL); - IPS_QUEUE_LOCK(queue); - if (item == queue->head) { - IPS_QUEUE_UNLOCK(queue); - return (ips_removeq_wait_head(queue)); } @@ -3784,13 +3799,9 @@ item->host_scribble = NULL; queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3802,7 +3813,7 @@ /* */ /* Add an item to the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3812,8 +3823,6 @@ if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->next = queue->head; queue->head = item; @@ -3821,8 +3830,6 @@ queue->tail = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3833,7 +3840,7 @@ /* */ /* Add an item to the tail of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3843,8 +3850,6 @@ if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->next = NULL; if (queue->tail) @@ -3856,8 +3861,6 @@ queue->head = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3868,7 +3871,7 @@ /* */ /* Remove the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * @@ -3877,13 +3880,9 @@ METHOD_TRACE("ips_removeq_copp_head", 1); - IPS_QUEUE_LOCK(queue); - item = queue->head; if (!item) { - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3895,8 +3894,6 @@ queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } @@ -3908,7 +3905,7 @@ /* */ /* Remove an item from a queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * @@ -3920,11 +3917,7 @@ if (!item) return (NULL); - IPS_QUEUE_LOCK(queue); - if (item == queue->head) { - IPS_QUEUE_UNLOCK(queue); - return (ips_removeq_copp_head(queue)); } @@ -3943,13 +3936,9 @@ item->next = NULL; queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3966,6 +3955,7 @@ ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) { METHOD_TRACE("ipsintr_blocking", 2); + ips_freescb(ha, scb); if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) { ha->waitflag = FALSE; @@ -4012,12 +4002,11 @@ /* Routine Description: */ /* */ /* Do housekeeping on completed commands */ -/* */ +/* ASSUMED to be called form within the request lock */ /****************************************************************************/ static void ips_done(ips_ha_t *ha, ips_scb_t *scb) { int ret; - unsigned long cpu_flags; METHOD_TRACE("ips_done", 1); @@ -4026,9 +4015,7 @@ if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { ips_cleanup_passthru(ha, scb); - IPS_HA_LOCK(cpu_flags); ha->num_ioctl--; - IPS_HA_UNLOCK(cpu_flags); } else { /* * Check to see if this command had too much @@ -4041,7 +4028,6 @@ bk_save = scb->breakup; scb->breakup = 0; - mod_timer(&scb->scsi_cmd->eh_timeout, jiffies + 120 * HZ); if (scb->sg_count) { /* S/G request */ @@ -4128,15 +4114,21 @@ } else { /* Non S/G Request */ pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, - PCI_DMA_BIDIRECTIONAL); + IPS_DMA_DIR(scb)); if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) { /* Further breakup required */ scb->data_len = ha->max_xfer; - scb->data_busaddr = pci_map_single(ha->pcidev, scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer), scb->data_len, PCI_DMA_BIDIRECTIONAL); + scb->data_busaddr = pci_map_single(ha->pcidev, + scb->scsi_cmd->request_buffer + + (bk_save * ha->max_xfer), + scb->data_len, IPS_DMA_DIR(scb)); scb->breakup = bk_save + 1; } else { scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer); - scb->data_busaddr = pci_map_single(ha->pcidev, scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer), scb->data_len, PCI_DMA_BIDIRECTIONAL); + scb->data_busaddr = pci_map_single(ha->pcidev, + scb->scsi_cmd->request_buffer + + (bk_save * ha->max_xfer), + scb->data_len, IPS_DMA_DIR(scb)); } scb->dcdb.transfer_length = scb->data_len; @@ -4181,9 +4173,7 @@ } /* end if passthru */ if (scb->bus) { - IPS_HA_LOCK(cpu_flags); ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - IPS_HA_UNLOCK(cpu_flags); } scb->scsi_cmd->scsi_done(scb->scsi_cmd); @@ -4197,7 +4187,7 @@ /* */ /* Routine Description: */ /* */ -/* Map ServeRAID error codes to Linux Error Codes */ +/* Map Controller Error codes to Linux Error Codes */ /* */ /****************************************************************************/ static int @@ -4363,6 +4353,7 @@ char *sp; int device_error; IPS_DCDB_TABLE_TAPE *tapeDCDB; + int TimeOut; METHOD_TRACE("ips_send_cmd", 1); @@ -4372,8 +4363,8 @@ /* internal command */ if (scb->bus > 0) { - /* ServeRAID commands can't be issued */ - /* to real devices -- fail them */ + /* Controller commands can't be issued */ + /* to real devices -- fail them */ if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) { ha->waitflag = FALSE; @@ -4383,6 +4374,8 @@ } } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) { /* command to logical bus -- interpret */ + if(ha->scb_waitlist.count + ha->scb_activelist.count > 32) + mod_timer(&scb->scsi_cmd->eh_timeout, jiffies + 120 * HZ); ret = IPS_SUCCESS_IMM; switch (scb->scsi_cmd->cmnd[0]) { @@ -4399,43 +4392,17 @@ case TEST_UNIT_READY: case INQUIRY: - if (scb->target_id == IPS_ADAPTER_ID) { - /* - * Either we have a TUR - * or we have a SCSI inquiry - */ - if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY) - scb->scsi_cmd->result = DID_OK << 16; - - if (scb->scsi_cmd->cmnd[0] == INQUIRY) { - IPS_SCSI_INQ_DATA inquiry; - - memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); - - inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR; - inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; - inquiry.Version = IPS_SCSI_INQ_REV2; - inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; - inquiry.AdditionalLength = 31; - inquiry.Flags[0] = IPS_SCSI_INQ_Address16; - inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; - strncpy(inquiry.VendorId, "IBM ", 8); - strncpy(inquiry.ProductId, "SERVERAID ", 16); - strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - - memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); - - scb->scsi_cmd->result = DID_OK << 16; - } - } else { - scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info)); - scb->cmd.logical_info.reserved = 0; - scb->cmd.logical_info.reserved2 = 0; - ret = IPS_SUCCESS; - } - + scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; + scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.reserved = 0; + scb->cmd.logical_info.reserved2 = 0; + scb->data_len = sizeof(ha->adapt->logical_drive_info); + scb->data_busaddr = pci_map_single(ha->pcidev, + &ha->adapt->logical_drive_info, + scb->data_len, IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.logical_info.buffer_addr = scb->data_busaddr; + ret = IPS_SUCCESS; break; case REQUEST_SENSE: @@ -4523,17 +4490,26 @@ case MODE_SENSE: scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq)); + scb->data_len = sizeof(*ha->enq); + scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, + scb->data_len, IPS_DMA_DIR(scb)); + scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; ret = IPS_SUCCESS; break; case READ_CAPACITY: scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info)); scb->cmd.logical_info.reserved = 0; scb->cmd.logical_info.reserved2 = 0; scb->cmd.logical_info.reserved3 = 0; + scb->data_len = sizeof(ha->adapt->logical_drive_info); + scb->data_busaddr = pci_map_single(ha->pcidev, + &ha->adapt->logical_drive_info, + scb->data_len, IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.logical_info.buffer_addr = scb->data_busaddr; ret = IPS_SUCCESS; break; @@ -4586,10 +4562,14 @@ ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb)); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + + (unsigned long)&scb->dcdb - + (unsigned long)scb); scb->cmd.dcdb.reserved = 0; scb->cmd.dcdb.reserved2 = 0; - scb->cmd.dcdb.reserved3 = 0; + scb->cmd.dcdb.reserved3 = 0; + + TimeOut = scb->scsi_cmd->timeout_per_command; if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ if (!scb->sg_len) @@ -4602,51 +4582,50 @@ tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */ - if (scb->timeout) { - if (scb->timeout <= 10) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; - else if (scb->timeout <= 60) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; - else - tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; + if (TimeOut) { + if (TimeOut < ( 10 * HZ )) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ } - if (!(tapeDCDB->cmd_attribute & IPS_TIMEOUT20M)) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; - - tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info); + tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; + tapeDCDB->reserved_for_LUN = 0; tapeDCDB->transfer_length = scb->data_len; tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr); tapeDCDB->sg_count = scb->sg_len; - tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; - tapeDCDB->reserved_for_LUN = 0; - tapeDCDB->reserved = 0; + tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info); tapeDCDB->scsi_status = 0; + tapeDCDB->reserved = 0; memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); } else { scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id; scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED; - if (scb->timeout) { - if (scb->timeout <= 10) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; - else if (scb->timeout <= 60) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; - else - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; + if (TimeOut) { + if (TimeOut < (10 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ } - - if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; - - scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info); + scb->dcdb.transfer_length = scb->data_len; if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K ) scb->dcdb.transfer_length = 0; scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); - scb->dcdb.sg_count = scb->sg_len; scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; + scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info); + scb->dcdb.sg_count = scb->sg_len; + scb->dcdb.reserved = 0; memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); + scb->dcdb.scsi_status = 0; + scb->dcdb.reserved2[0] = 0; + scb->dcdb.reserved2[1] = 0; + scb->dcdb.reserved2[2] = 0; } } @@ -4660,7 +4639,7 @@ /* Routine Description: */ /* */ /* Check the status of commands to logical drives */ -/* */ +/* Assumed to be called with the HA lock */ /****************************************************************************/ static void ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { @@ -4725,12 +4704,37 @@ break; case TEST_UNIT_READY: + if (scb->target_id == IPS_ADAPTER_ID) + break; + if (!ips_online(ha, scb)) { errcode = DID_TIME_OUT; } break; case INQUIRY: + if (scb->target_id == IPS_ADAPTER_ID) { + IPS_SCSI_INQ_DATA inquiry; + + memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); + + inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR; + inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; + strncpy(inquiry.VendorId, "IBM ", 8); + strncpy(inquiry.ProductId, "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, "1.00", 4); + + memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); + + scb->scsi_cmd->result = DID_OK << 16; + break; + } + if (ips_online(ha, scb)) { ips_inquiry(ha, scb); } else { @@ -5024,7 +5028,8 @@ } if (ha->adapt) { - kfree(ha->adapt); + pci_free_consistent(ha->pcidev,sizeof(IPS_ADAPTER)+ sizeof(IPS_IO_CMD), + ha->adapt, ha->adapt->hw_status_start); ha->adapt = NULL; } @@ -5038,11 +5043,6 @@ ha->subsys = NULL; } - if (ha->dummy) { - kfree(ha->dummy); - ha->dummy = NULL; - } - if (ha->ioctl_data) { free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); ha->ioctl_data = NULL; @@ -5164,7 +5164,8 @@ /* Initialize dummy command bucket */ ha->dummy->op_code = 0xFF; - ha->dummy->ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy)); + ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start + + sizeof(IPS_ADAPTER)); ha->dummy->command_id = IPS_MAX_CMDS; /* set bus address of scb */ @@ -5174,7 +5175,8 @@ /* Neptune Fix */ scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE); - scb->cmd.basic_io.ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy)); + scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start + + sizeof(IPS_ADAPTER)); } /****************************************************************************/ @@ -5191,13 +5193,10 @@ static ips_scb_t * ips_getscb(ips_ha_t *ha) { ips_scb_t *scb; - unsigned long cpu_flags; METHOD_TRACE("ips_getscb", 1); - IPS_SCB_LOCK(cpu_flags); if ((scb = ha->scb_freelist) == NULL) { - IPS_SCB_UNLOCK(cpu_flags); return (NULL); } @@ -5205,8 +5204,6 @@ ha->scb_freelist = scb->q_next; scb->q_next = NULL; - IPS_SCB_UNLOCK(cpu_flags); - ips_init_scb(ha, scb); return (scb); @@ -5225,20 +5222,20 @@ /****************************************************************************/ static void ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { - unsigned long cpu_flags; METHOD_TRACE("ips_freescb", 1); if(scb->flags & IPS_SCB_MAP_SG) - pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg, PCI_DMA_BIDIRECTIONAL); + pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer, + scb->scsi_cmd->use_sg, + IPS_DMA_DIR(scb)); else if(scb->flags & IPS_SCB_MAP_SINGLE) - pci_unmap_single(ha->pcidev,scb->cmd.basic_io.sg_addr, scb->data_len, PCI_DMA_BIDIRECTIONAL); + pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, + IPS_DMA_DIR(scb)); /* check to make sure this is not our "special" scb */ if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { - IPS_SCB_LOCK(cpu_flags); scb->q_next = ha->scb_freelist; ha->scb_freelist = scb; - IPS_SCB_UNLOCK(cpu_flags); } } @@ -5593,6 +5590,29 @@ Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + if (Post == 0x4F00) { /* If Flashing the Battery PIC */ + printk(KERN_WARNING "Flashing Battery PIC, Please wait ...\n" ); + + /* Clear the interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG0I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */ + Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + if (Post != 0x4F00) + break; + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 120) { + printk(KERN_WARNING "(%s%d) timeout waiting for Battery PIC Flash\n", + ips_name, ha->host_num); + return (0); + } + + } + /* Clear the interrupt bit */ Isr = (uint32_t) IPS_BIT_I960_MSG0I; writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); @@ -5635,6 +5655,13 @@ writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); /* if we get here then everything went OK */ + + /* Since we did a RESET, an EraseStripeLock may be needed */ + if (Post == 0xEF10) { + if ( (Config == 0x000F) || (Config == 0x0009) ) + ha->requires_esl = 1; + } + return (1); } @@ -5650,15 +5677,12 @@ static int ips_reset_copperhead(ips_ha_t *ha) { int reset_counter; - unsigned long cpu_flags; METHOD_TRACE("ips_reset_copperhead", 1); DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", ips_name, ha->host_num, ha->io_addr, ha->irq); - IPS_HA_LOCK(cpu_flags); - reset_counter = 0; while (reset_counter < 2) { @@ -5677,14 +5701,11 @@ if ((*ha->func.init)(ha)) break; else if (reset_counter >= 2) { - IPS_HA_UNLOCK(cpu_flags); return (0); } } - IPS_HA_UNLOCK(cpu_flags); - return (1); } @@ -5700,15 +5721,12 @@ static int ips_reset_copperhead_memio(ips_ha_t *ha) { int reset_counter; - unsigned long cpu_flags; METHOD_TRACE("ips_reset_copperhead_memio", 1); DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", ips_name, ha->host_num, ha->mem_addr, ha->irq); - IPS_HA_LOCK(cpu_flags); - reset_counter = 0; while (reset_counter < 2) { @@ -5727,14 +5745,11 @@ if ((*ha->func.init)(ha)) break; else if (reset_counter >= 2) { - IPS_HA_UNLOCK(cpu_flags); return (0); } } - IPS_HA_UNLOCK(cpu_flags); - return (1); } @@ -5751,15 +5766,12 @@ ips_reset_morpheus(ips_ha_t *ha) { int reset_counter; uint8_t junk; - unsigned long cpu_flags; METHOD_TRACE("ips_reset_morpheus", 1); DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", ips_name, ha->host_num, ha->mem_addr, ha->irq); - IPS_HA_LOCK(cpu_flags); - reset_counter = 0; while (reset_counter < 2) { @@ -5776,14 +5788,11 @@ if ((*ha->func.init)(ha)) break; else if (reset_counter >= 2) { - IPS_HA_UNLOCK(cpu_flags); return (0); } } - IPS_HA_UNLOCK(cpu_flags); - return (1); } @@ -5806,13 +5815,12 @@ ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; ha->adapt->p_status_tail = ha->adapt->status; - phys_status_start = VIRT_TO_BUS(ha->adapt->status); + phys_status_start = ha->adapt->hw_status_start; outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER); outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR); outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); - ha->adapt->hw_status_start = phys_status_start; ha->adapt->hw_status_tail = phys_status_start; } @@ -5835,13 +5843,12 @@ ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; ha->adapt->p_status_tail = ha->adapt->status; - phys_status_start = VIRT_TO_BUS(ha->adapt->status); + phys_status_start = ha->adapt->hw_status_start; writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR); writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER); writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR); writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR); - ha->adapt->hw_status_start = phys_status_start; ha->adapt->hw_status_tail = phys_status_start; } @@ -5930,7 +5937,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { uint32_t TimeOut; uint32_t val; - unsigned long cpu_flags; METHOD_TRACE("ips_issue_copperhead", 1); @@ -5950,8 +5956,6 @@ scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - TimeOut = 0; while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { @@ -5966,8 +5970,6 @@ printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", ips_name, ha->host_num); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_FAILURE); } /* end if */ } /* end while */ @@ -5975,8 +5977,6 @@ outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -5993,7 +5993,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { uint32_t TimeOut; uint32_t val; - unsigned long cpu_flags; METHOD_TRACE("ips_issue_copperhead_memio", 1); @@ -6013,8 +6012,6 @@ scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - TimeOut = 0; while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { @@ -6029,8 +6026,6 @@ printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", ips_name, ha->host_num); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_FAILURE); } /* end if */ } /* end while */ @@ -6038,8 +6033,6 @@ writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6054,7 +6047,6 @@ /****************************************************************************/ static int ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { - unsigned long cpu_flags; METHOD_TRACE("ips_issue_i2o", 1); @@ -6074,12 +6066,8 @@ scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6094,7 +6082,6 @@ /****************************************************************************/ static int ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { - unsigned long cpu_flags; METHOD_TRACE("ips_issue_i2o_memio", 1); @@ -6114,12 +6101,8 @@ scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6256,12 +6239,7 @@ * until after we finish. */ - while (test_and_set_bit(IPS_IN_INTR, &ha->flags)) - udelay(1000); - (*ha->func.intr)(ha); - - clear_bit(IPS_IN_INTR, &ha->flags); } /* This looks like a very evil loop, but it only does this during start-up */ @@ -6297,8 +6275,7 @@ if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.", ips_name, ha->host_num, ha->nvram->signature); - - return (1); + ha->nvram->signature = IPS_NVRAM_P5_SIG; } DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", @@ -6321,6 +6298,10 @@ ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */ + /* Save the First Copy of the Adapter Order that BIOS put in Page 5 */ + if ( (InitState == 0) && (AdapterOrder[0] == 0) ) + strncpy((char *) AdapterOrder, (char *) ha->nvram->adapter_order, sizeof(AdapterOrder) ); + /* now update the page */ if (!ips_readwrite_page5(ha, TRUE, intr)) { printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n", @@ -6362,11 +6343,15 @@ scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq)); scb->cmd.basic_io.lba = 0; scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; scb->cmd.basic_io.reserved = 0; + scb->data_len = sizeof(*ha->enq); + scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len, + IPS_DMA_DIR(scb)); + scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; /* send command */ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || @@ -6403,11 +6388,15 @@ scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->subsys)); scb->cmd.basic_io.lba = 0; scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; scb->cmd.basic_io.reserved = 0; + scb->data_len = sizeof(*ha->subsys); + scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys, + scb->data_len, IPS_DMA_DIR(scb)); + scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; /* send command */ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || @@ -6448,7 +6437,11 @@ scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->conf)); + scb->data_len = sizeof(*ha->conf); + scb->data_busaddr = pci_map_single(ha->pcidev, ha->conf, + scb->data_len, IPS_DMA_DIR(scb)); + scb->cmd.basic_io.sg_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; /* send command */ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || @@ -6498,9 +6491,13 @@ scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.nvram.page = 5; scb->cmd.nvram.write = write; - scb->cmd.nvram.buffer_addr = cpu_to_le32(VIRT_TO_BUS(ha->nvram)); scb->cmd.nvram.reserved = 0; scb->cmd.nvram.reserved2 = 0; + scb->data_len = sizeof(*ha->nvram); + scb->data_busaddr = pci_map_single(ha->pcidev, ha->nvram, + scb->data_len, IPS_DMA_DIR(scb)); + scb->cmd.nvram.buffer_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; /* issue the command */ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || @@ -7211,7 +7208,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 available. */ +/* Data is available. */ /* */ /*---------------------------------------------------------------------------*/ static void ips_version_check(ips_ha_t *ha, int intr) { @@ -7220,6 +7217,8 @@ uint8_t BiosVersion[ IPS_COMPAT_ID_LENGTH + 1]; int MatchError; int rc; + char BiosString[10]; + char FirmwareString[10]; METHOD_TRACE("ips_version_check", 1); @@ -7252,28 +7251,30 @@ MatchError = 0; if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0) - { - if (ips_cd_boot == 0) - printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n", - ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]); MatchError = 1; - } if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) - { - if (ips_cd_boot == 0) - printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n", - ha->host_num, BiosVersion, IPS_COMPAT_BIOS); MatchError = 1; - } ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ if (MatchError) { ha->nvram->version_mismatch = 1; - if (ips_cd_boot == 0) + if (ips_cd_boot == 0) + { + strncpy(&BiosString[0], ha->nvram->bios_high, 4); + strncpy(&BiosString[4], ha->nvram->bios_low, 4); + BiosString[8] = 0; + + strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8); + FirmwareString[8] = 0; + printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); + printk(KERN_WARNING "Bios = %s, Firmware = %s, Device Driver = %s%s\n", + BiosString, FirmwareString, IPS_VERSION_HIGH, IPS_VERSION_LOW ); + printk(KERN_WARNING "These levels should match to avoid possible compatibility problems.\n" ); + } } else { @@ -7287,7 +7288,7 @@ /* Routine Name: ips_get_version_info */ /* */ /* Routine Description: */ -/* Issue an internal GETVERSION ServeRAID Command */ +/* Issue an internal GETVERSION Command */ /* */ /* Return Value: */ /* 0 if Successful, else non-zero */ @@ -7309,8 +7310,12 @@ scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.version_info.reserved = 0; scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA); - scb->cmd.version_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(Buffer)); scb->cmd.version_info.reserved2 = 0; + scb->data_len = sizeof(*Buffer); + scb->data_busaddr = pci_map_single(ha->pcidev, Buffer, + scb->data_len, IPS_DMA_DIR(scb)); + scb->cmd.version_info.buffer_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; /* issue command */ rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); @@ -7324,6 +7329,14 @@ #include "scsi_module.c" #endif +static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){ + ha->active = 0; + ips_free(ha); + scsi_unregister(sh); + ips_ha[index] = 0; + ips_sh[index] = 0; + return -1; +} #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) @@ -7367,12 +7380,25 @@ int rc; METHOD_TRACE("ips_insert_device", 1); + + /* If we're still in Init State 0, and we've already found the Adapter */ + /* Ordering Table, there is no reason to continue. */ + if ( (InitState == 0) && (AdapterOrder[0]) ) + return -1; + if (pci_enable_device(pci_dev)) return -1; rc = ips_init_phase1(pci_dev, &index); if (rc == SUCCESS) - rc = ips_init_phase2(index); + rc = ips_init_phase2(index); + + /* If we're in Init State 0, we're done with the device for now. */ + /* Release the device and don't count it. */ + if ( InitState == 0 ) { + ips_remove_device(pci_dev); + return -1; + } if (rc == SUCCESS) ips_num_controllers++; @@ -7407,6 +7433,7 @@ int j; int index; uint32_t count; + dma_addr_t dma_address; char *ioremap_ptr; char *mem_ptr; uint32_t IsDead @@ -7486,6 +7513,10 @@ /* found a controller */ sh = scsi_register(&driver_template, sizeof(ips_ha_t)); +#if LINUX_VERSION_CODE > LinuxVersionCode(2,5,0) + pci_set_dma_mask(pci_dev, (u64)0xffffffff); + scsi_set_pci_device(sh, pci_dev); +#endif if (sh == NULL) { printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" ); return -1; @@ -7493,14 +7524,7 @@ ha = IPS_HA(sh); memset(ha, 0, sizeof(ips_ha_t)); - - /* Initialize spin lock */ - spin_lock_init(&ha->scb_lock); - spin_lock_init(&ha->copp_lock); spin_lock_init(&ha->ips_lock); - spin_lock_init(&ha->copp_waitlist.lock); - spin_lock_init(&ha->scb_waitlist.lock); - spin_lock_init(&ha->scb_activelist.lock); - + ips_sh[index] = sh; ips_ha[index] = ha; ha->active = 1; @@ -7509,72 +7533,37 @@ if (!ha->enq) { printk(KERN_WARNING "Unable to allocate host inquiry structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } - ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL); - + ha->adapt = pci_alloc_consistent(pci_dev, sizeof(IPS_ADAPTER) + + sizeof(IPS_IO_CMD), &dma_address); if (!ha->adapt) { - printk(KERN_WARNING "Unable to allocate host adapt structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n"); + return ips_abort_init(ha, sh, index); } + ha->adapt->hw_status_start = dma_address; + ha->dummy = (void *)(ha->adapt + 1); ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); if (!ha->conf) { printk(KERN_WARNING "Unable to allocate host conf structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); if (!ha->nvram) { printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); if (!ha->subsys) { printk(KERN_WARNING "Unable to allocate host subsystem structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; - } - - ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL); - - if (!ha->dummy) { - printk(KERN_WARNING "Unable to allocate host dummy structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } for (count = PAGE_SIZE, ha->ioctl_order = 0; @@ -7625,55 +7614,9 @@ /* * Setup Functions */ - if (IPS_IS_MORPHEUS(ha)) { - /* morpheus */ - ha->func.isintr = ips_isintr_morpheus; - ha->func.isinit = ips_isinit_morpheus; - ha->func.issue = ips_issue_i2o_memio; - ha->func.init = ips_init_morpheus; - ha->func.statupd = ips_statupd_morpheus; - ha->func.reset = ips_reset_morpheus; - ha->func.intr = ips_intr_morpheus; - ha->func.enableint = ips_enable_int_morpheus; - } else if (IPS_USE_MEMIO(ha)) { - /* copperhead w/MEMIO */ - ha->func.isintr = ips_isintr_copperhead_memio; - ha->func.isinit = ips_isinit_copperhead_memio; - ha->func.init = ips_init_copperhead_memio; - ha->func.statupd = ips_statupd_copperhead_memio; - ha->func.statinit = ips_statinit_memio; - ha->func.reset = ips_reset_copperhead_memio; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios_memio; - ha->func.programbios = ips_program_bios_memio; - ha->func.verifybios = ips_verify_bios_memio; - ha->func.enableint = ips_enable_int_copperhead_memio; - - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o_memio; - else - ha->func.issue = ips_issue_copperhead_memio; - } else { - /* copperhead */ - ha->func.isintr = ips_isintr_copperhead; - ha->func.isinit = ips_isinit_copperhead; - ha->func.init = ips_init_copperhead; - ha->func.statupd = ips_statupd_copperhead; - ha->func.statinit = ips_statinit; - ha->func.reset = ips_reset_copperhead; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios; - ha->func.programbios = ips_program_bios; - ha->func.verifybios = ips_verify_bios; - ha->func.enableint = ips_enable_int_copperhead; - - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o; - else - ha->func.issue = ips_issue_copperhead; - } + ips_setup_funclist(ha); - if ( IPS_IS_MORPHEUS( ha ) ) { + if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) { /* If Morpheus appears dead, reset it */ IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 ); if ( IsDead == 0xDEADBEEF ) { @@ -7691,24 +7634,14 @@ * Initialization failed */ printk(KERN_WARNING "Unable to initialize controller\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } } /* Install the interrupt handler */ if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { printk(KERN_WARNING "Unable to install interrupt handler\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } /* @@ -7717,13 +7650,8 @@ ha->max_cmds = 1; if (!ips_allocatescbs(ha)) { printk(KERN_WARNING "Unable to allocate a CCB\n" ); - ha->active = 0; free_irq(ha->irq, ha); - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } *indexPtr = index; @@ -7759,13 +7687,8 @@ if (!ips_hainit(ha)) { printk(KERN_WARNING "Unable to initialize controller\n" ); - ha->active = 0; - ips_free(ha); free_irq(ha->irq, ha); - scsi_unregister(sh); - ips_ha[index] = NULL; - ips_sh[index] = NULL; - return -1; + return ips_abort_init(ha, sh, index); } /* Free the temporary SCB */ ips_deallocatescbs(ha, 1); @@ -7773,13 +7696,8 @@ /* allocate CCBs */ if (!ips_allocatescbs(ha)) { printk(KERN_WARNING "Unable to allocate CCBs\n" ); - ha->active = 0; - ips_free(ha); free_irq(ha->irq, ha); - scsi_unregister(sh); - ips_ha[index] = NULL; - ips_sh[index] = NULL; - return -1; + return ips_abort_init(ha, sh, index); } /* finish setting values */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/scsi/ips.h linux.21pre5-ac1/drivers/scsi/ips.h --- linux.21pre5/drivers/scsi/ips.h 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/ips.h 2003-03-03 15:41:19.000000000 +0000 @@ -1,11 +1,12 @@ /*****************************************************************************/ -/* ips.h -- driver for the IBM ServeRAID controller */ +/* ips.h -- driver for the Adaptec / IBM ServeRAID controller */ /* */ /* Written By: Keith Mitchell, IBM Corporation */ /* Jack Hammer, Adaptec, Inc. */ /* David Jeffery, Adaptec, Inc. */ /* */ /* Copyright (C) 1999 IBM Corporation */ +/* Copyright (C) 2003 Adaptec, 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 */ @@ -42,7 +43,7 @@ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* */ /* Bugs/Comments/Suggestions should be mailed to: */ -/* ipslinux@adaptec.com */ +/* ipslinux@adaptec.com */ /* */ /*****************************************************************************/ @@ -60,7 +61,6 @@ extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *)); extern int ips_biosparam(Disk *, kdev_t, int *); extern const char * ips_info(struct Scsi_Host *); - extern void do_ips(int, void *, struct pt_regs *); /* * Some handy macros @@ -78,41 +78,19 @@ (ha->revision_id >= IPS_REVID_CLARINETP1) && \ (ha->revision_id <= IPS_REVID_CLARINETP3)) ? 1 : 0) #define IPS_IS_MORPHEUS(ha) (ha->device_id == IPS_DEVICEID_MORPHEUS) + #define IPS_IS_MARCO(ha) (ha->device_id == IPS_DEVICEID_MARCO) #define IPS_USE_I2O_DELIVER(ha) ((IPS_IS_MORPHEUS(ha) || \ (IPS_IS_TROMBONE(ha) && \ (ips_force_i2o))) ? 1 : 0) - #define IPS_USE_I2O_STATUS(ha) (IPS_IS_MORPHEUS(ha)) #define IPS_USE_MEMIO(ha) ((IPS_IS_MORPHEUS(ha) || \ ((IPS_IS_TROMBONE(ha) || IPS_IS_CLARINET(ha)) && \ (ips_force_memio))) ? 1 : 0) - #ifndef VIRT_TO_BUS - #define VIRT_TO_BUS(x) (uint32_t) virt_to_bus((void *) x) - #endif - #ifndef MDELAY #define MDELAY mdelay #endif - - #ifndef verify_area_20 - #define verify_area_20(t,a,sz) (0) /* success */ - #endif - - #ifndef DECLARE_MUTEX_LOCKED - #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED; - #endif /* - * Lock macros - */ - #define IPS_SCB_LOCK(cpu_flags) spin_lock_irqsave(&ha->scb_lock, cpu_flags) - #define IPS_SCB_UNLOCK(cpu_flags) spin_unlock_irqrestore(&ha->scb_lock, cpu_flags) - #define IPS_QUEUE_LOCK(queue) spin_lock_irqsave(&(queue)->lock, (queue)->cpu_flags) - #define IPS_QUEUE_UNLOCK(queue) spin_unlock_irqrestore(&(queue)->lock, (queue)->cpu_flags) - #define IPS_HA_LOCK(cpu_flags) spin_lock_irqsave(&ha->ips_lock, cpu_flags) - #define IPS_HA_UNLOCK(cpu_flags) spin_unlock_irqrestore(&ha->ips_lock, cpu_flags) - - /* * Adapter address map equates */ #define IPS_REG_HISR 0x08 /* Host Interrupt Status Reg */ @@ -171,7 +149,7 @@ #define IPS_CMD_DCDB 0x04 #define IPS_CMD_DCDB_SG 0x84 #define IPS_CMD_EXTENDED_DCDB 0x95 - #define IPS_CMD_EXTENDED_DCDB_SG 0x96 + #define IPS_CMD_EXTENDED_DCDB_SG 0x96 #define IPS_CMD_CONFIG_SYNC 0x58 #define IPS_CMD_ERROR_TABLE 0x17 #define IPS_CMD_DOWNLOAD 0x20 @@ -185,6 +163,7 @@ #define IPS_CSL 0xFF #define IPS_POCL 0x30 #define IPS_NORM_STATE 0x00 + #define IPS_MAX_ADAPTER_TYPES 3 #define IPS_MAX_ADAPTERS 16 #define IPS_MAX_IOCTL 1 #define IPS_MAX_IOCTL_QUEUE 8 @@ -207,15 +186,19 @@ #define IPS_INTR_IORL 1 #define IPS_FFDC 99 #define IPS_ADAPTER_ID 0xF - #define IPS_VENDORID 0x1014 + #define IPS_VENDORID_IBM 0x1014 + #define IPS_VENDORID_ADAPTEC 0x9005 #define IPS_DEVICEID_COPPERHEAD 0x002E #define IPS_DEVICEID_MORPHEUS 0x01BD + #define IPS_DEVICEID_MARCO 0x0250 #define IPS_SUBDEVICEID_4M 0x01BE #define IPS_SUBDEVICEID_4L 0x01BF #define IPS_SUBDEVICEID_4MX 0x0208 #define IPS_SUBDEVICEID_4LX 0x020E #define IPS_SUBDEVICEID_5I2 0x0259 #define IPS_SUBDEVICEID_5I1 0x0258 + #define IPS_SUBDEVICEID_6M 0x0279 + #define IPS_SUBDEVICEID_6I 0x028C #define IPS_IOCTL_SIZE 8192 #define IPS_STATUS_SIZE 4 #define IPS_STATUS_Q_SIZE (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE @@ -298,6 +281,8 @@ #define IPS_ADTYPE_SERVERAID4LX 0x0B #define IPS_ADTYPE_SERVERAID5I2 0x0C #define IPS_ADTYPE_SERVERAID5I1 0x0D + #define IPS_ADTYPE_SERVERAID6M 0x0E + #define IPS_ADTYPE_SERVERAID6I 0x0F /* * Adapter Command/Status Packet Definitions @@ -369,27 +354,8 @@ #define IPS_SCSI_MP3_AllocateSurface 0x08 /* - * Configuration Structure Flags - */ - #define IPS_CFG_USEROPT_UPDATECOUNT(cfg) (((cfg)->UserOpt & 0xffff000) >> 16) - #define IPS_CFG_USEROPT_CONCURSTART(cfg) (((cfg)->UserOpt & 0xf000) >> 12) - #define IPS_CFG_USEROPT_STARTUPDELAY(cfg) (((cfg)->UserOpt & 0xf00) >> 8) - #define IPS_CFG_USEROPT_REARRANGE(cfg) ((cfg)->UserOpt & 0x80) - #define IPS_CFG_USEROPT_CDBOOT(cfg) ((cfg)->UserOpt & 0x40) - #define IPS_CFG_USEROPT_CLUSTER(cfg) ((cfg)->UserOpt & 0x20) - - /* - * Host adapter Flags (bit numbers) - */ - #define IPS_IN_INTR 0 - #define IPS_IN_ABORT 1 - #define IPS_IN_RESET 2 - - /* * SCB Flags */ - #define IPS_SCB_ACTIVE 0x00001 - #define IPS_SCB_WAITING 0x00002 #define IPS_SCB_MAP_SG 0x00008 #define IPS_SCB_MAP_SINGLE 0X00010 @@ -400,7 +366,6 @@ #define IPS_COPPIOCCMD (('C'<<8) | 66) #define IPS_NUMCTRLS (('C'<<8) | 68) #define IPS_CTRLINFO (('C'<<8) | 69) - #define IPS_FLASHBIOS (('C'<<8) | 70) /* flashing defines */ #define IPS_FW_IMAGE 0x00 @@ -455,7 +420,7 @@ use_clustering : ENABLE_CLUSTERING, \ use_new_eh_code : 1 \ } -#else +#elif LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) #define IPS { \ next : NULL, \ module : NULL, \ @@ -484,10 +449,39 @@ use_clustering : ENABLE_CLUSTERING, \ use_new_eh_code : 1 \ } +#else + #define IPS { \ + next : NULL, \ + module : NULL, \ + proc_info : NULL, \ + name : NULL, \ + detect : ips_detect, \ + release : ips_release, \ + info : ips_info, \ + command : NULL, \ + queuecommand : ips_queue, \ + eh_strategy_handler : NULL, \ + eh_abort_handler : ips_eh_abort, \ + eh_device_reset_handler : NULL, \ + eh_bus_reset_handler : NULL, \ + eh_host_reset_handler : ips_eh_reset, \ + abort : NULL, \ + reset : NULL, \ + slave_attach : NULL, \ + bios_param : ips_biosparam, \ + can_queue : 0, \ + this_id: -1, \ + sg_tablesize : IPS_MAX_SG, \ + cmd_per_lun: 16, \ + present : 0, \ + unchecked_isa_dma : 0, \ + use_clustering : ENABLE_CLUSTERING, \ + highmem_io : 1 \ +} #endif /* - * IBM PCI Raid Command Formats + * Raid Command Formats */ typedef struct { uint8_t op_code; @@ -765,7 +759,7 @@ uint16_t usConfigUpdateCount; uint8_t ucBlkFlag; uint8_t reserved; - uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS]; + uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * (IPS_MAX_TARGETS + 1)]; } IPS_ENQ, *PIPS_ENQ; typedef struct { @@ -841,7 +835,8 @@ uint8_t ReservedForOS2[8]; uint8_t bios_high[4]; /* Adapter's Flashed BIOS Version */ uint8_t bios_low[4]; - uint8_t Filler[76]; + uint8_t adapter_order[16]; /* BIOS Telling us the Sort Order */ + uint8_t Filler[60]; } IPS_NVRAM_P5, *PIPS_NVRAM_P5; /*--------------------------------------------------------------------------*/ @@ -1007,19 +1002,6 @@ int option_value; } IPS_OPTION; -typedef struct { - void *userbuffer; - uint32_t usersize; - void *kernbuffer; - uint32_t kernsize; - void *ha; - void *SC; - void *pt; - struct semaphore *sem; - uint32_t offset; - uint32_t retcode; -} IPS_FLASH_DATA; - /* * Status Info */ @@ -1036,8 +1018,6 @@ struct ips_scb *head; struct ips_scb *tail; int count; - unsigned long cpu_flags; - spinlock_t lock; } ips_scb_queue_t; /* @@ -1047,13 +1027,10 @@ Scsi_Cmnd *head; Scsi_Cmnd *tail; int count; - unsigned long cpu_flags; - spinlock_t lock; } ips_wait_queue_t; typedef struct ips_copp_wait_item { Scsi_Cmnd *scsi_cmd; - struct semaphore *sem; struct ips_copp_wait_item *next; } ips_copp_wait_item_t; @@ -1061,8 +1038,6 @@ struct ips_copp_wait_item *head; struct ips_copp_wait_item *tail; int count; - unsigned long cpu_flags; - spinlock_t lock; } ips_copp_queue_t; /* forward decl for host structure */ @@ -1111,7 +1086,6 @@ char *ioctl_data; /* IOCTL data area */ uint32_t ioctl_datasize; /* IOCTL data size */ uint32_t cmd_in_progress; /* Current command in progress*/ - unsigned long flags; /* HA flags */ uint8_t waitflag; /* are we waiting for cmd */ uint8_t active; int ioctl_reset; /* IOCTL Requested Reset Flag */ @@ -1122,7 +1096,6 @@ uint8_t slot_num; /* PCI Slot Number */ uint16_t subdevice_id; /* Subsystem device ID */ uint8_t ioctl_order; /* Number of pages in ioctl */ - uint8_t reserved2; /* Empty */ uint8_t bios_version[8]; /* BIOS Revision */ uint32_t mem_addr; /* Memory mapped address */ uint32_t io_len; /* Size of IO Address */ @@ -1131,14 +1104,10 @@ char *ioremap_ptr; /* ioremapped memory pointer */ ips_hw_func_t func; /* hw function pointers */ struct pci_dev *pcidev; /* PCI device handle */ - spinlock_t scb_lock; - spinlock_t copp_lock; - spinlock_t ips_lock; - struct semaphore ioctl_sem; /* Semaphore for new IOCTL's */ - struct semaphore flash_ioctl_sem; /* Semaphore for Flashing */ char *flash_data; /* Save Area for flash data */ - u8 flash_order; /* Save Area for flash size order */ - u32 flash_datasize; /* Save Area for flash data size */ + u8 flash_order; /* Save Area for flash size order */ + u32 flash_datasize; /* Save Area for flash data size */ + uint8_t requires_esl; /* Requires an EraseStripeLock */ } ips_ha_t; typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *); @@ -1168,7 +1137,6 @@ Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; ips_scb_callback callback; - struct semaphore *sem; uint32_t sg_busaddr; int sg_count; } ips_scb_t; @@ -1224,44 +1192,46 @@ * *************************************************************************/ -#define IPS_VER_MAJOR 5 -#define IPS_VER_MAJOR_STRING "5" -#define IPS_VER_MINOR 10 -#define IPS_VER_MINOR_STRING "10" -#define IPS_VER_BUILD 21 -#define IPS_VER_BUILD_STRING "21" -#define IPS_VER_STRING "5.10.21" -#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." +#define IPS_VER_MAJOR 6 +#define IPS_VER_MAJOR_STRING "6" +#define IPS_VER_MINOR 00 +#define IPS_VER_MINOR_STRING "00" +#define IPS_VER_BUILD 26 +#define IPS_VER_BUILD_STRING "26" +#define IPS_VER_STRING "6.00.26" +#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved." #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved." -#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002." +#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003." /* Version numbers for various adapters */ #define IPS_VER_SERVERAID1 "2.25.01" #define IPS_VER_SERVERAID2 "2.88.13" #define IPS_VER_NAVAJO "2.88.13" -#define IPS_VER_SERVERAID3 "5.10.21" -#define IPS_VER_SERVERAID4H "5.10.21" -#define IPS_VER_SERVERAID4MLx "5.10.21" -#define IPS_VER_SARASOTA "5.10.21" +#define IPS_VER_SERVERAID3 "6.00.26" +#define IPS_VER_SERVERAID4H "6.00.26" +#define IPS_VER_SERVERAID4MLx "6.00.26" +#define IPS_VER_SARASOTA "6.00.26" +#define IPS_VER_MARCO "6.00.26" /* Compatability IDs for various adapters */ #define IPS_COMPAT_UNKNOWN "" -#define IPS_COMPAT_CURRENT "SA510" +#define IPS_COMPAT_CURRENT "MR600" #define IPS_COMPAT_SERVERAID1 "2.25.01" #define IPS_COMPAT_SERVERAID2 "2.88.13" #define IPS_COMPAT_NAVAJO "2.88.13" #define IPS_COMPAT_KIOWA "2.88.13" -#define IPS_COMPAT_SERVERAID3H "SA510" -#define IPS_COMPAT_SERVERAID3L "SA510" -#define IPS_COMPAT_SERVERAID4H "SA510" -#define IPS_COMPAT_SERVERAID4M "SA510" -#define IPS_COMPAT_SERVERAID4L "SA510" -#define IPS_COMPAT_SERVERAID4Mx "SA510" -#define IPS_COMPAT_SERVERAID4Lx "SA510" -#define IPS_COMPAT_SARASOTA "SA510" -#define IPS_COMPAT_BIOS "SA510" +#define IPS_COMPAT_SERVERAID3H "MR600" +#define IPS_COMPAT_SERVERAID3L "MR600" +#define IPS_COMPAT_SERVERAID4H "MR600" +#define IPS_COMPAT_SERVERAID4M "MR600" +#define IPS_COMPAT_SERVERAID4L "MR600" +#define IPS_COMPAT_SERVERAID4Mx "MR600" +#define IPS_COMPAT_SERVERAID4Lx "MR600" +#define IPS_COMPAT_SARASOTA "MR600" +#define IPS_COMPAT_MARCO "MR600" +#define IPS_COMPAT_BIOS "MR600" -#define IPS_COMPAT_MAX_ADAPTER_TYPE 14 +#define IPS_COMPAT_MAX_ADAPTER_TYPE 15 #define IPS_COMPAT_ID_LENGTH 8 #define IPS_DEFINE_COMPAT_TABLE(tablename) \ @@ -1278,8 +1248,9 @@ IPS_COMPAT_SERVERAID4L, \ IPS_COMPAT_SERVERAID4Mx, \ IPS_COMPAT_SERVERAID4Lx, \ - IPS_COMPAT_SARASOTA, \ - IPS_COMPAT_SARASOTA \ + IPS_COMPAT_SARASOTA, /* one-channel variety of SARASOTA */ \ + IPS_COMPAT_SARASOTA, /* two-channel variety of SARASOTA */ \ + IPS_COMPAT_MARCO \ } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/scsi/Makefile linux.21pre5-ac1/drivers/scsi/Makefile --- linux.21pre5/drivers/scsi/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/megaraid.c linux.21pre5-ac1/drivers/scsi/megaraid.c --- linux.21pre5/drivers/scsi/megaraid.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/qlogicfas.c linux.21pre5-ac1/drivers/scsi/qlogicfas.c --- linux.21pre5/drivers/scsi/qlogicfas.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/qlogicfas.c 2003-03-03 15:30:37.000000000 +0000 @@ -147,6 +147,8 @@ static int qlcfg9 = ( ( XTALFREQ + 4 ) / 5 ); static int qlcfgc = ( FASTCLK << 3 ) | ( FASTSCSI << 4 ); +struct Scsi_Host *hreg; /* registered host structure */ + /*----------------------------------------------------------------*/ /* The qlogic card uses two register maps - These macros select which one */ #define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd )) @@ -541,13 +543,24 @@ } #endif +int qlogicfas_release(struct Scsi_Host *hreg) +{ + release_region(qbase, 0x10); + + if (qlirq >= 0) + free_irq(qlirq, hreg); + + scsi_unregister(hreg); + + return 0; +} + /*----------------------------------------------------------------*/ /* look for qlogic card and init if found */ int __QLINIT qlogicfas_detect(Scsi_Host_Template * host) { int i, j; /* these are only used by IRQ detect */ int qltyp; /* type of chip */ -struct Scsi_Host *hreg; /* registered host structure */ unsigned long flags; host->proc_name = "qlogicfas"; @@ -620,16 +633,28 @@ else printk( "Ql: Using preset IRQ %d\n", qlirq ); - if (qlirq >= 0 && !request_irq(qlirq, do_ql_ihandl, 0, "qlogicfas", NULL)) + if (qlirq >= 0) host->can_queue = 1; #endif hreg = scsi_register( host , 0 ); /* no host data */ if (!hreg) goto err_release_mem; + +#if QL_USE_IRQ +#ifdef PCMCIA + if(request_irq(qlirq, do_ql_ihandl, SA_SHIRQ, "qlogicfas", hreg) < 0) +#else + if(request_irq(qlirq, do_ql_ihandl, SA_SHIRQ, "qlogicfas", hreg) < 0) +#endif + { + scsi_unregister(host); + goto err_release_mem; + } +#endif hreg->io_port = qbase; hreg->n_io_port = 16; hreg->dma_channel = -1; - if( qlirq != -1 ) + if( qlirq >= 0 ) hreg->irq = qlirq; sprintf(qinfo, "Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d", @@ -640,8 +665,8 @@ err_release_mem: release_region(qbase, 0x10); - if (host->can_queue) - free_irq(qlirq, do_ql_ihandl); + if (qlirq >= 0) + free_irq(qlirq, hreg); return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/scsi/qlogicfas.h linux.21pre5-ac1/drivers/scsi/qlogicfas.h --- linux.21pre5/drivers/scsi/qlogicfas.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/qlogicfas.h 2003-03-03 15:28:55.000000000 +0000 @@ -2,6 +2,7 @@ #define _QLOGICFAS_H int qlogicfas_detect(Scsi_Host_Template * ); +int qlogicfas_release(struct Scsi_Host *); const char * qlogicfas_info(struct Scsi_Host *); int qlogicfas_command(Scsi_Cmnd *); int qlogicfas_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); @@ -21,6 +22,7 @@ #define QLOGICFAS { \ detect: qlogicfas_detect, \ + release: qlogicfas_release, \ info: qlogicfas_info, \ command: qlogicfas_command, \ queuecommand: qlogicfas_queuecommand, \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/scsi/scsi.c linux.21pre5-ac1/drivers/scsi/scsi.c --- linux.21pre5/drivers/scsi/scsi.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/scsi_error.c linux.21pre5-ac1/drivers/scsi/scsi_error.c --- linux.21pre5/drivers/scsi/scsi_error.c 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/scsi.h linux.21pre5-ac1/drivers/scsi/scsi.h --- linux.21pre5/drivers/scsi/scsi.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/scsi.h 2003-02-28 00:48:06.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.21pre5/drivers/scsi/scsi_lib.c linux.21pre5-ac1/drivers/scsi/scsi_lib.c --- linux.21pre5/drivers/scsi/scsi_lib.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/scsi_lib.c 2003-02-27 20:24:15.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. @@ -722,7 +746,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.21pre5/drivers/scsi/scsi_scan.c linux.21pre5-ac1/drivers/scsi/scsi_scan.c --- linux.21pre5/drivers/scsi/scsi_scan.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/scsi_scan.c 2003-02-25 23:48:29.000000000 +0000 @@ -182,6 +182,8 @@ {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"SUN", "T300", "*", BLIST_SPARSELUN}, + {"SUN", "T4", "*", BLIST_SPARSELUN}, /* * Must be at end of list... @@ -596,6 +598,7 @@ } else { /* assume no peripheral if any other sort of error */ scsi_release_request(SRpnt); + scsi_release_commandblocks(SDpnt); return 0; } } @@ -619,6 +622,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.21pre5/drivers/scsi/sd.c linux.21pre5-ac1/drivers/scsi/sd.c --- linux.21pre5/drivers/scsi/sd.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/sd.c 2003-02-27 20:24:15.000000000 +0000 @@ -850,10 +850,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); @@ -1003,7 +1006,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++) { @@ -1011,9 +1014,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.21pre5/drivers/scsi/sd.h linux.21pre5-ac1/drivers/scsi/sd.h --- linux.21pre5/drivers/scsi/sd.h 2003-02-27 18:39:57.000000000 +0000 +++ linux.21pre5-ac1/drivers/scsi/sd.h 2003-02-28 00:48:06.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.21pre5/drivers/scsi/sim710_d.h linux.21pre5-ac1/drivers/scsi/sim710_d.h --- linux.21pre5/drivers/scsi/sim710_d.h 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/sym53c8xx_2/sym_hipd.c linux.21pre5-ac1/drivers/scsi/sym53c8xx_2/sym_hipd.c --- linux.21pre5/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/scsi/sym53c8xx.c linux.21pre5-ac1/drivers/scsi/sym53c8xx.c --- linux.21pre5/drivers/scsi/sym53c8xx.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/ac97_codec.c linux.21pre5-ac1/drivers/sound/ac97_codec.c --- linux.21pre5/drivers/sound/ac97_codec.c 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/ac97_codec.c 2003-03-01 19:26:15.000000000 +0000 @@ -74,6 +74,8 @@ static int ad1886_init(struct ac97_codec *codec); static int eapd_control(struct ac97_codec *codec, int); static int crystal_digital_control(struct ac97_codec *codec, int mode); +static int cmedia_init(struct ac97_codec * codec); +static int cmedia_digital_control(struct ac97_codec *codec, int mode); /* @@ -104,12 +106,15 @@ static struct ac97_ops sigmatel_9744_ops = { sigmatel_9744_init, NULL, NULL }; static struct ac97_ops crystal_digital_ops = { NULL, eapd_control, crystal_digital_control }; static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL }; +static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL}; +static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control}; /* sorted by vendor/device id */ static const struct { u32 id; char *name; struct ac97_ops *ops; + int flags; } ac97_codec_ids[] = { {0x41445303, "Analog Devices AD1819", &null_ops}, {0x41445340, "Analog Devices AD1881", &null_ops}, @@ -123,6 +128,9 @@ {0x414B4D02, "Asahi Kasei AK4543", &null_ops}, {0x414C4710, "ALC200/200P", &null_ops}, {0x414C4720, "ALC650", &null_ops}, + {0x434D4941, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME }, + {0x434D4942, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME }, + {0x434D4961, "CMedia", &cmedia_digital_ops, AC97_NO_PCM_VOLUME }, {0x43525900, "Cirrus Logic CS4297", &default_ops}, {0x43525903, "Cirrus Logic CS4297", &default_ops}, {0x43525913, "Cirrus Logic CS4297A rev A", &default_ops}, @@ -133,6 +141,8 @@ {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}, + {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM }, + {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}, @@ -679,6 +689,26 @@ } /** + * ac97_check_modem - Check if the Codec is a modem + * @codec: codec to check + * + * Return true if the device is an AC97 1.0 or AC97 2.0 modem + */ + +static int ac97_check_modem(struct ac97_codec *codec) +{ + /* Check for an AC97 1.0 soft modem (ID1) */ + if(codec->codec_read(codec, AC97_RESET) & 2) + return 1; + /* Check for an AC97 2.x soft modem */ + codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); + if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1) + return 1; + return 0; +} + + +/** * ac97_probe_codec - Initialize and setup AC97-compatible codec * @codec: (in/out) Kernel info for a single AC97 codec * @@ -704,7 +734,7 @@ int ac97_probe_codec(struct ac97_codec *codec) { u16 id1, id2; - u16 audio, modem; + u16 audio; int i; char cidbuf[CODEC_ID_BUFSZ]; @@ -730,11 +760,7 @@ } /* probe for Modem Codec */ - codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); - modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1; - modem |= (audio&2); - audio &= ~2; - + codec->modem = ac97_check_modem(codec); codec->name = NULL; codec->codec_ops = &null_ops; @@ -745,13 +771,19 @@ codec->type = ac97_codec_ids[i].id; codec->name = ac97_codec_ids[i].name; codec->codec_ops = ac97_codec_ids[i].ops; + codec->flags = ac97_codec_ids[i].flags; break; } } + + /* A device which thinks its a modem but isnt */ + if(codec->flags & AC97_DELUDED_MODEM) + codec->modem = 0; + if (codec->name == NULL) codec->name = "Unknown"; printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n", - modem ? "Modem" : (audio ? "Audio" : ""), + codec->modem ? "Modem" : (audio ? "Audio" : ""), codec_id(id1, id2, cidbuf), codec->name); return ac97_init_mixer(codec); @@ -773,6 +805,9 @@ if (!(cap & 0x10)) codec->supported_mixers &= ~SOUND_MASK_ALTPCM; + if(codec->flags & AC97_NO_PCM_VOLUME) + codec->supported_mixers &= ~SOUND_MASK_PCM; + /* detect bit resolution */ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020); if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020) @@ -801,6 +836,8 @@ ac97_set_mixer(codec, md->mixer, md->value); } + if(codec->flags & AC97_NO_PCM_VOLUME) + printk(KERN_WARNING "AC97 codec does not have proper volume support.\n"); return 1; } @@ -873,7 +910,29 @@ return 0; } - +static int cmedia_init(struct ac97_codec *codec) +{ + /* Initialise the CMedia 9739 */ + /* + We could set various options here + Register 0x20 bit 0x100 sets mic as center bass + Also do multi_channel_ctrl &=~0x3000 |=0x1000 + + For now we set up the GPIO and PC beep + */ + + u16 v; + + /* MIC */ + codec->codec_write(codec, 0x64, 0x3000); + v = codec->codec_read(codec, 0x64); + v &= ~0x8000; + codec->codec_write(codec, 0x64, v); + codec->codec_write(codec, 0x70, 0x0100); + codec->codec_write(codec, 0x72, 0x0020); + return 0; +} + static int wolfson_init00(struct ac97_codec * codec) { /* This initialization is suspect, but not known to be wrong. @@ -1001,6 +1060,35 @@ return 0; } +/* + * CMedia digital audio control + * Needs more work. + */ + +static int cmedia_digital_control(struct ac97_codec *codec, int mode) +{ + u16 cv; + + switch(mode) + { + case 0: cv = 0x0001; break; /* SPEN off */ + case 1: cv = 0x0009; break; /* 48KHz digital */ + default: + return -1; /* Not supported yet(eg AC3) */ + } + codec->codec_write(codec, 0x2A, 0x05c4); + codec->codec_write(codec, 0x6C, cv); + + /* Switch on mix to surround */ + cv = codec->codec_read(codec, 0x64); + cv &= ~0x0200; + if(mode) + cv |= 0x0200; + codec->codec_write(codec, 0x64, cv); + return 0; +} + + /* copied from drivers/sound/maestro.c */ #if 0 /* there has been 1 person on the planet with a pt101 that we know of. If they care, they can put this back in :) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/Config.in linux.21pre5-ac1/drivers/sound/Config.in --- linux.21pre5/drivers/sound/Config.in 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/cs46xx.c linux.21pre5-ac1/drivers/sound/cs46xx.c --- linux.21pre5/drivers/sound/cs46xx.c 2003-02-27 18:39:59.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/es1371.c linux.21pre5-ac1/drivers/sound/es1371.c --- linux.21pre5/drivers/sound/es1371.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/es1371.c 2003-02-27 20:24:21.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.21pre5/drivers/sound/forte.c linux.21pre5-ac1/drivers/sound/forte.c --- linux.21pre5/drivers/sound/forte.c 2003-02-27 18:40:01.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/gus_midi.c linux.21pre5-ac1/drivers/sound/gus_midi.c --- linux.21pre5/drivers/sound/gus_midi.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/gus_midi.c 2003-03-03 15:20:09.000000000 +0000 @@ -183,7 +183,7 @@ qhead++; } restore_flags(flags); - return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY); + return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY); } #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/gus_wave.c linux.21pre5-ac1/drivers/sound/gus_wave.c --- linux.21pre5/drivers/sound/gus_wave.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/gus_wave.c 2003-03-03 15:20:09.000000000 +0000 @@ -3123,7 +3123,7 @@ gus_initialize(); - if ((gus_mem_size > 0) & !gus_no_wave_dma) + if ((gus_mem_size > 0) && !gus_no_wave_dma) { hw_config->slots[4] = -1; if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/i810_audio.c linux.21pre5-ac1/drivers/sound/i810_audio.c --- linux.21pre5/drivers/sound/i810_audio.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/i810_audio.c 2003-03-01 18:33:49.000000000 +0000 @@ -2927,23 +2927,13 @@ /* Check for an AC97 1.0 soft modem (ID1) */ - if(codec->codec_read(codec, AC97_RESET) & 2) + if(codec->modem) { - printk(KERN_WARNING "i810_audio: codec %d is an AC97 1.0 softmodem - skipping.\n", ac97_id); + printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", ac97_id); kfree(codec); continue; } - /* Check for an AC97 2.x soft modem */ - - codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); - if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1) - { - printk(KERN_WARNING "i810_audio: codec %d is an AC97 2.x softmodem - skipping.\n", ac97_id); - kfree(codec); - continue; - } - card->ac97_features = eid; /* Now check the codec for useful features to make up for diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/kahlua.c linux.21pre5-ac1/drivers/sound/kahlua.c --- linux.21pre5/drivers/sound/kahlua.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/maestro.c linux.21pre5-ac1/drivers/sound/maestro.c --- linux.21pre5/drivers/sound/maestro.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/maestro.c 2003-03-03 15:20:09.000000000 +0000 @@ -3359,7 +3359,7 @@ /* check to see if we have a capabilities list in the config register */ pci_read_config_word(pcidev, PCI_STATUS, &w); - if(! w & PCI_STATUS_CAP_LIST) return 0; + if(!(w & PCI_STATUS_CAP_LIST)) return 0; /* walk the list, starting at the head. */ pci_read_config_byte(pcidev,PCI_CAPABILITY_LIST,&next); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/Makefile linux.21pre5-ac1/drivers/sound/Makefile --- linux.21pre5/drivers/sound/Makefile 2003-02-27 19:13:39.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/mpu401.c linux.21pre5-ac1/drivers/sound/mpu401.c --- linux.21pre5/drivers/sound/mpu401.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/mpu401.c 2003-03-03 15:26:05.000000000 +0000 @@ -1766,8 +1766,8 @@ static struct address_info cfg; -static int __initdata io = -1; -static int __initdata irq = -1; +static int io = -1; +static int irq = -1; MODULE_PARM(irq, "i"); MODULE_PARM(io, "i"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/nec_vrc5477.c linux.21pre5-ac1/drivers/sound/nec_vrc5477.c --- linux.21pre5/drivers/sound/nec_vrc5477.c 2003-02-27 18:39:59.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/sscape.c linux.21pre5-ac1/drivers/sound/sscape.c --- linux.21pre5/drivers/sound/sscape.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/trident.c linux.21pre5-ac1/drivers/sound/trident.c --- linux.21pre5/drivers/sound/trident.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/sound/trident.c 2003-03-01 18:51:40.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 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/sound/via82cxxx_audio.c linux.21pre5-ac1/drivers/sound/via82cxxx_audio.c --- linux.21pre5/drivers/sound/via82cxxx_audio.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/sound/vidc.c linux.21pre5-ac1/drivers/sound/vidc.c --- linux.21pre5/drivers/sound/vidc.c 2003-02-27 18:39:58.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/usb/acm.c linux.21pre5-ac1/drivers/usb/acm.c --- linux.21pre5/drivers/usb/acm.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/acm.c 2003-03-03 15:20:09.000000000 +0000 @@ -240,7 +240,7 @@ if (urb->status) dbg("nonzero read bulk status received: %d", urb->status); - if (!urb->status & !acm->throttle) { + if (!urb->status && !acm->throttle) { for (i = 0; i < urb->actual_length && !acm->throttle; i++) { /* if we insert more than TTY_FLIPBUF_SIZE characters, * we drop them. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/CDCEther.c linux.21pre5-ac1/drivers/usb/CDCEther.c --- linux.21pre5/drivers/usb/CDCEther.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/usb/devio.c linux.21pre5-ac1/drivers/usb/devio.c --- linux.21pre5/drivers/usb/devio.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/usb/hcd/ehci-q.c linux.21pre5-ac1/drivers/usb/hcd/ehci-q.c --- linux.21pre5/drivers/usb/hcd/ehci-q.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/hcd/ehci-q.c 2003-02-21 15:49:41.000000000 +0000 @@ -834,6 +834,7 @@ && !usb_pipecontrol (urb->pipe)) { /* "never happens": drivers do stall cleanup right */ if (qh->qh_state != QH_STATE_IDLE + && !list_empty (&qh->qtd_list) && qh->qh_state != QH_STATE_COMPLETING) ehci_warn (ehci, "clear toggle dev%d " "ep%d%s: not idle\n", @@ -1048,6 +1049,7 @@ scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh; + int unlink_delay = 0; if (!++(ehci->stamp)) ehci->stamp++; @@ -1074,17 +1076,25 @@ } } - /* 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.21pre5/drivers/usb/hcd.c linux.21pre5-ac1/drivers/usb/hcd.c --- linux.21pre5/drivers/usb/hcd.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/usb/hid-core.c linux.21pre5-ac1/drivers/usb/hid-core.c --- linux.21pre5/drivers/usb/hid-core.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/hid-core.c 2003-03-03 15:17:38.000000000 +0000 @@ -1096,6 +1096,9 @@ #define USB_VENDOR_ID_TANGTOP 0x0d3d #define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 +#define USB_VENDOR_ID_OKI 0x070a +#define USB_VENDOR_ID_OKI_MULITI 0x0007 + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1134,6 +1137,7 @@ { 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 }, + { USB_VENDOR_ID_OKI, USB_VENDOR_ID_OKI_MULITI, HID_QUIRK_NOGET }, { 0, 0 } }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/kaweth.c linux.21pre5-ac1/drivers/usb/kaweth.c --- linux.21pre5/drivers/usb/kaweth.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/kaweth.c 2003-03-03 15:18:06.000000000 +0000 @@ -143,6 +143,7 @@ { USB_DEVICE(0x06e1, 0x0008) }, /* ADS USB-10BT */ { USB_DEVICE(0x06e1, 0x0009) }, /* ADS USB-10BT */ { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */ + { USB_DEVICE(0x0785, 0x0002) }, /* NTT-TE MN128 USB-Ethernet Adapter */ { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */ { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */ { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/pegasus.h linux.21pre5-ac1/drivers/usb/pegasus.h --- linux.21pre5/drivers/usb/pegasus.h 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/pegasus.h 2003-03-03 15:17:04.000000000 +0000 @@ -232,6 +232,8 @@ DEFAULT_GPIO_RESET ) PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202, LINKSYS_GPIO_RESET ) PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/storage/transport.c linux.21pre5-ac1/drivers/usb/storage/transport.c --- linux.21pre5/drivers/usb/storage/transport.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/storage/transport.c 2003-03-01 18:59:05.000000000 +0000 @@ -1054,7 +1054,7 @@ US_BULK_GET_MAX_LUN, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, us->ifnum, data, sizeof(data), HZ); + 0, us->ifnum, data, sizeof(*data), HZ); US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", result, *data); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/storage/unusual_devs.h linux.21pre5-ac1/drivers/usb/storage/unusual_devs.h --- linux.21pre5/drivers/usb/storage/unusual_devs.h 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/drivers/usb/storage/unusual_devs.h 2003-03-03 15:18:32.000000000 +0000 @@ -255,6 +255,12 @@ US_SC_UFI, US_PR_CB, NULL, US_FL_SINGLE_LUN | US_FL_START_STOP ), +UNUSUAL_DEV( 0x054c, 0x0069, 0x0000, 0x9999, + "Sony", + "Memorystick MSC-U03", + US_SC_UFI, US_PR_CB, NULL, + US_FL_SINGLE_LUN | US_FL_START_STOP ), + /* Submitted by Nathan Babb */ UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999, "Sony", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/usb.c linux.21pre5-ac1/drivers/usb/usb.c --- linux.21pre5/drivers/usb/usb.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/usb/usb-ohci.c linux.21pre5-ac1/drivers/usb/usb-ohci.c --- linux.21pre5/drivers/usb/usb-ohci.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/usb/usb-uhci.c linux.21pre5-ac1/drivers/usb/usb-uhci.c --- linux.21pre5/drivers/usb/usb-uhci.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/atafb.c linux.21pre5-ac1/drivers/video/atafb.c --- linux.21pre5/drivers/video/atafb.c 2003-02-27 18:40:02.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/aty/atyfb_base.c linux.21pre5-ac1/drivers/video/aty/atyfb_base.c --- linux.21pre5/drivers/video/aty/atyfb_base.c 2003-02-27 18:40:03.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/aty/mach64_ct.c linux.21pre5-ac1/drivers/video/aty/mach64_ct.c --- linux.21pre5/drivers/video/aty/mach64_ct.c 2003-02-27 18:40:03.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/aty/mach64.h linux.21pre5-ac1/drivers/video/aty/mach64.h --- linux.21pre5/drivers/video/aty/mach64.h 2003-02-27 18:40:03.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/aty128fb.c linux.21pre5-ac1/drivers/video/aty128fb.c --- linux.21pre5/drivers/video/aty128fb.c 2003-02-27 18:40:02.000000000 +0000 +++ linux.21pre5-ac1/drivers/video/aty128fb.c 2003-03-03 15:20:09.000000000 +0000 @@ -2531,7 +2531,7 @@ reg |= LVDS_BL_MOD_EN | LVDS_BLON; if (on && level > BACKLIGHT_OFF) { reg |= LVDS_DIGION; - if (!reg & LVDS_ON) { + if ((reg & LVDS_ON) == 0) { reg &= ~LVDS_BLON; aty_st_le32(LVDS_GEN_CNTL, reg); (void)aty_ld_le32(LVDS_GEN_CNTL); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21pre5/drivers/video/Config.in linux.21pre5-ac1/drivers/video/Config.in --- linux.21pre5/drivers/video/Config.in 2003-02-27 18:40:02.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/fbmem.c linux.21pre5-ac1/drivers/video/fbmem.c --- linux.21pre5/drivers/video/fbmem.c 2003-02-27 19:13:40.000000000 +0000 +++ linux.21pre5-ac1/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.21pre5/drivers/video/intel/builtinmodes.c linux.21pre5-ac1/drivers/video/intel/builtinmodes.c --- linux.21pre5/drivers/video/intel/builtinmodes.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/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.21pre5/drivers/video/intel/intelfbdrv.c linux.21pre5-ac1/drivers/video/intel/intelfbdrv.c --- linux.21pre5/drivers/video/intel/intelfbdrv.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.21pre5-ac1/drivers/video/intel/intelfbdrv.c 2003-02-27 00:06:47.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