## Automatically generated incremental diff ## From: linux-2.4.22-bk27 ## To: linux-2.4.22-bk28 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.4.22-bk27/Documentation/Configure.help linux-2.4.22-bk28/Documentation/Configure.help --- linux-2.4.22-bk27/Documentation/Configure.help 2003-10-02 02:49:28.000000000 -0700 +++ linux-2.4.22-bk28/Documentation/Configure.help 2003-10-02 02:49:33.000000000 -0700 @@ -19654,6 +19654,9 @@ display brightness and output, switching the LCD backlight on and off, and most importantly, allows you to blink those fancy LEDs intended for reporting mail and wireless status. + + Note: the display switching code is currently considered EXPERIMENTAL, + toying with these values may even lock your machine. All settings are changed via /proc/acpi/asus directory entries. Owner and group for these entries can be set with asus_uid and asus_gid diff -urN linux-2.4.22-bk27/MAINTAINERS linux-2.4.22-bk28/MAINTAINERS --- linux-2.4.22-bk27/MAINTAINERS 2003-10-02 02:49:28.000000000 -0700 +++ linux-2.4.22-bk28/MAINTAINERS 2003-10-02 02:49:33.000000000 -0700 @@ -266,6 +266,16 @@ L: linux-net@vger.kernel.org S: Maintained +ASUS ACPI EXTRAS DRIVER +P: Karol Kozimor +M: sziwan@users.sourceforge.net +P: Julien Lerouge +M: julien.lerouge@free.fr +L: acpi4asus-user@lists.sourceforge.net +W: http://sourceforge.net/projects/acpi4asus +W: http://julien.lerouge.free.fr +S: Maintained + ATM P: Chas Williams M: chas@cmf.nrl.navy.mil diff -urN linux-2.4.22-bk27/Makefile linux-2.4.22-bk28/Makefile --- linux-2.4.22-bk27/Makefile 2003-10-02 02:49:28.000000000 -0700 +++ linux-2.4.22-bk28/Makefile 2003-10-02 02:49:33.000000000 -0700 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 22 -EXTRAVERSION = -bk27 +EXTRAVERSION = -bk28 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.22-bk27/arch/i386/kernel/setup.c linux-2.4.22-bk28/arch/i386/kernel/setup.c --- linux-2.4.22-bk27/arch/i386/kernel/setup.c 2003-10-02 02:49:29.000000000 -0700 +++ linux-2.4.22-bk28/arch/i386/kernel/setup.c 2003-10-02 02:49:33.000000000 -0700 @@ -2269,6 +2269,8 @@ { 0x23, LVL_3, 1024 }, { 0x25, LVL_3, 2048 }, { 0x29, LVL_3, 4096 }, + { 0x2c, LVL_1_DATA, 32 }, + { 0x30, LVL_1_INST, 32 }, { 0x39, LVL_2, 128 }, { 0x3b, LVL_2, 128 }, { 0x3C, LVL_2, 256 }, @@ -2291,6 +2293,8 @@ { 0x83, LVL_2, 512 }, { 0x84, LVL_2, 1024 }, { 0x85, LVL_2, 2048 }, + { 0x86, LVL_2, 512 }, + { 0x87, LVL_2, 1024 }, { 0x00, 0, 0} }; diff -urN linux-2.4.22-bk27/drivers/acpi/Config.in linux-2.4.22-bk28/drivers/acpi/Config.in --- linux-2.4.22-bk27/drivers/acpi/Config.in 2003-10-02 02:49:29.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/Config.in 2003-10-02 02:49:34.000000000 -0700 @@ -10,36 +10,30 @@ if [ "$CONFIG_ACPI" = "y" ]; then define_bool CONFIG_ACPI_BOOT y - - if [ "$CONFIG_SMP" = "y" ]; then - bool 'CPU Enumeration Only' CONFIG_ACPI_HT_ONLY - else - define_bool CONFIG_ACPI_HT_ONLY n + define_bool CONFIG_ACPI_BUS y + define_bool CONFIG_ACPI_INTERPRETER y + define_bool CONFIG_ACPI_EC y + define_bool CONFIG_ACPI_POWER y + if [ "$CONFIG_PCI" = "y" ]; then + define_bool CONFIG_ACPI_PCI y fi - - if [ "$CONFIG_ACPI_HT_ONLY" = "n" ]; then - define_bool CONFIG_ACPI_BUS y - define_bool CONFIG_ACPI_INTERPRETER y - define_bool CONFIG_ACPI_EC y - define_bool CONFIG_ACPI_POWER y - if [ "$CONFIG_PCI" = "y" ]; then - define_bool CONFIG_ACPI_PCI y - fi - define_bool CONFIG_ACPI_SLEEP y - define_bool CONFIG_ACPI_SYSTEM y - tristate ' AC Adapter' CONFIG_ACPI_AC - tristate ' Battery' CONFIG_ACPI_BATTERY - tristate ' Button' CONFIG_ACPI_BUTTON - tristate ' Fan' CONFIG_ACPI_FAN - tristate ' Processor' CONFIG_ACPI_PROCESSOR - dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR - if [ "$CONFIG_NUMA" = "y" -a "$CONFIG_X86_64" != "y" ]; then - dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA - fi - tristate ' ASUS Laptop Extras' CONFIG_ACPI_ASUS - tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA - bool ' Debug Statements' CONFIG_ACPI_DEBUG - bool ' Relaxed AML Checking' CONFIG_ACPI_RELAXED_AML + define_bool CONFIG_ACPI_SLEEP y + define_bool CONFIG_ACPI_SYSTEM y + tristate ' AC Adapter' CONFIG_ACPI_AC + tristate ' Battery' CONFIG_ACPI_BATTERY + tristate ' Button' CONFIG_ACPI_BUTTON + tristate ' Fan' CONFIG_ACPI_FAN + tristate ' Processor' CONFIG_ACPI_PROCESSOR + dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR + if [ "$CONFIG_NUMA" = "y" -a "$CONFIG_X86_64" != "y" ]; then + dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA + fi + tristate ' ASUS Laptop Extras' CONFIG_ACPI_ASUS + tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA + bool ' Debug Statements' CONFIG_ACPI_DEBUG + bool ' Relaxed AML Checking' CONFIG_ACPI_RELAXED_AML + else if [ "$CONFIG_SMP" = "y" ]; then + define_bool CONFIG_ACPI_BOOT y fi fi diff -urN linux-2.4.22-bk27/drivers/acpi/asus_acpi.c linux-2.4.22-bk28/drivers/acpi/asus_acpi.c --- linux-2.4.22-bk27/drivers/acpi/asus_acpi.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/asus_acpi.c 2003-10-02 02:49:34.000000000 -0700 @@ -26,13 +26,17 @@ * Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. * - * TODO + * TODO: * add Fn key status - * Add mode selection on module loading (parameter) -> still necessary ? + * Add mode selection on module loading (parameter) -> still necessary? * Complete display switching -- may require dirty hacks? - * */ +#include +#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) && defined (MODULE) +#include +#endif + #include #include #include @@ -41,7 +45,7 @@ #include #include -#define ASUS_ACPI_VERSION "0.24a" +#define ASUS_ACPI_VERSION "0.26" #define PROC_ASUS "asus" //the directory #define PROC_MLED "mled" @@ -73,7 +77,6 @@ MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; - static uid_t asus_uid = 0; static gid_t asus_gid = 0; MODULE_PARM(asus_uid, "i"); @@ -111,20 +114,24 @@ struct model_data *methods; //methods available on the laptop u8 brightness; //brighness level enum { - L2X = 0, //L200D -> TODO check Q11 (Fn+F8) - // Calling this method simply hang the + A1X=0, //A1340D, A1300F + A2X, //A2500H + D1X, //D1 + L1X, //L1400B + L2X, //L2000D -> TODO check Q11 (Fn+F8) + // Calling this method simply hangs the // computer, ISMI method hangs the laptop. - L3X, //L3C L3D, //L3400D + L3X, //L3C + L5X, //L5C TODO this model seems to have one more + // LED, add support M2X, //M2400E + M3N, //M3700N, but also S1300N -> TODO WLED S1X, //S1300A -> TODO special keys do not work ? - D1X, //D1 - L1X, //L1400B - A1X, //A1340D, A1300F - J1X, //S200 (J1) - //TODO A1370D does not seems to have a ATK device + S2X, //S200 (J1 reported), Victor MP-XP7210 + //TODO A1370D does not seem to have an ATK device // L8400 model doesn't have ATK - END_MODEL, + END_MODEL } model; //Models currently supported u16 event_count[128]; //count for each event TODO make this better }; @@ -134,7 +141,8 @@ #define S1X_PREFIX "\\_SB.PCI0.PX40." #define L1X_PREFIX S1X_PREFIX #define A1X_PREFIX "\\_SB.PCI0.ISA.EC0." -#define J1X_PREFIX A1X_PREFIX +#define S2X_PREFIX A1X_PREFIX +#define M3N_PREFIX "\\_SB.PCI0.SBRG.EC0." static struct model_data model_conf[END_MODEL] = { /* @@ -148,33 +156,43 @@ * it seems to be a kind of switch, but what for ? * */ + {"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI", + A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL}, + + {"A2X", "MLED", NULL, "WLED", "\\SG66", "\\Q10", "\\BAOF", + "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\CMOD", "SDSP", "\\INFB"}, + + {"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", + "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"}, + + {"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", + L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, + {"L2X", "MLED", "\\SGP6", "WLED", "\\RCP3", "\\Q10", "\\SGP0", "\\Q0E", "\\Q0F", NULL, NULL, NULL, "SDSP", "\\INFB"}, + {"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG", + "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"}, + {"L3X", "MLED", NULL, "WLED", NULL, L3X_PREFIX "_Q10", "\\GL32", L3X_PREFIX "_Q0F", L3X_PREFIX "_Q0E", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\_SB.PCI0.PCI1.VGAC.NMAP"}, - {"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG", - "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"}, - + {"L5X", "MLED", NULL, "WLED", "WRED", "\\Q0D", "\\BAOF", + "\\Q0C","\\Q0B", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"}, + {"M2X", "MLED", NULL, "WLED", NULL, "\\Q10", "\\GP06", "\\Q0E","\\Q0F", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"}, + + {"M3N", "MLED", NULL, "WLED", "\\PO33", M3N_PREFIX "_Q10", "\\BKLT", + M3N_PREFIX "_Q0F", M3N_PREFIX "_Q0E", "SPLV", "GPLV", "\\LBTN", "SDSP", + "\\ADVG"}, {"S1X", "MLED", "\\EMLE", "WLED", NULL, S1X_PREFIX "Q10", "\\PNOF", S1X_PREFIX "Q0F", S1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, - {"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", - "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"}, - - {"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", - L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, - - {"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI", - A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL}, - - {"J1X", "MLED", "\\MAIL", NULL, NULL, J1X_PREFIX "_Q10", "\\BKLI", - J1X_PREFIX "_Q0B", J1X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL} + {"S2X", "MLED", "\\MAIL", NULL, NULL, S2X_PREFIX "_Q10", "\\BKLI", + S2X_PREFIX "_Q0B", S2X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL} }; /* procdir we use */ @@ -235,7 +253,7 @@ output.length = sizeof(out_obj); output.pointer = &out_obj; - status = acpi_evaluate_object(handle, (char*) method, NULL, &output); + status = acpi_evaluate_object(handle, (char *) method, NULL, &output); *val = out_obj.integer.value; return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); } @@ -250,6 +268,7 @@ void *data) { int len = 0; + int sfun; struct asus_hotk *hotk = (struct asus_hotk *) data; char buf[16]; //enough for all info /* @@ -258,28 +277,27 @@ */ len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); - len += - sprintf(page + len, "Model reference : %s\n", - hotk->methods->name); + len += sprintf(page + len, "Model reference : %s\n", + hotk->methods->name); + if(read_acpi_int(hotk->handle, "SFUN", &sfun)) + len += sprintf(page + len, "SFUN value : 0x%04x\n", sfun); if (asus_info) { - snprintf(buf, 5, "%s", asus_info->signature); - len += sprintf(page + len, "ACPI signature : %s\n", buf); snprintf(buf, 16, "%d", asus_info->length); - len += sprintf(page + len, "Table length : %s\n", buf); - snprintf(buf, 16, "%d", asus_info->revision); - len += sprintf(page + len, "ACPI minor version : %s\n", buf); + len += sprintf(page + len, "DSDT length : %s\n", buf); snprintf(buf, 16, "%d", asus_info->checksum); - len += sprintf(page + len, "Checksum : %s\n", buf); + len += sprintf(page + len, "DSDT checksum : %s\n", buf); + snprintf(buf, 16, "%d", asus_info->revision); + len += sprintf(page + len, "DSDT revision : %s\n", buf); snprintf(buf, 7, "%s", asus_info->oem_id); - len += sprintf(page + len, "OEM identification : %s\n", buf); + len += sprintf(page + len, "OEM id : %s\n", buf); snprintf(buf, 9, "%s", asus_info->oem_table_id); len += sprintf(page + len, "OEM table id : %s\n", buf); snprintf(buf, 16, "%x", asus_info->oem_revision); - len += sprintf(page + len, "OEM rev number : 0x%s\n", buf); + len += sprintf(page + len, "OEM revision : 0x%s\n", buf); snprintf(buf, 5, "%s", asus_info->asl_compiler_id); - len += sprintf(page + len, "ASL comp vendor ID : %s\n", buf); + len += sprintf(page + len, "ASL comp vendor id : %s\n", buf); snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); - len += sprintf(page + len, "ASL comp rev number: 0x%s\n", buf); + len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf); } return len; @@ -305,7 +323,7 @@ &led_status)) len = sprintf(page, "%d\n", led_status); else - printk(KERN_NOTICE "Asus ACPI: Error reading MLED " + printk(KERN_WARNING "Asus ACPI: Error reading MLED " "status\n"); } else { len = sprintf(page, "%d\n", (hotk->status & MLED_ON) ? 1 : 0); @@ -335,7 +353,7 @@ /* We don't have to check mt_mled exists if we are here :) */ if (!write_acpi_int(hotk->handle, hotk->methods->mt_mled, led_out, NULL)) - printk(KERN_NOTICE "Asus ACPI: MLED write failed\n"); + printk(KERN_WARNING "Asus ACPI: MLED write failed\n"); @@ -356,11 +374,11 @@ int led_status; if (hotk->methods->wled_status) { - if (read_acpi_int(NULL, hotk->methods->mled_status, + if (read_acpi_int(NULL, hotk->methods->wled_status, &led_status)) len = sprintf(page, "%d\n", led_status); else - printk(KERN_NOTICE "Asus ACPI: Error reading WLED " + printk(KERN_WARNING "Asus ACPI: Error reading WLED " "status\n"); } else { len = sprintf(page, "%d\n", (hotk->status & WLED_ON) ? 1 : 0); @@ -387,7 +405,7 @@ /* We don't have to check if mt_wled exists if we are here :) */ if (!write_acpi_int(hotk->handle, hotk->methods->mt_wled, led_out, NULL)) - printk(KERN_NOTICE "Asus ACPI: WLED write failed\n"); + printk(KERN_WARNING "Asus ACPI: WLED write failed\n"); return count; @@ -400,7 +418,7 @@ /* We don't have to check anything, if we are here */ if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) - printk(KERN_NOTICE "Asus ACPI: Error reading LCD status\n"); + printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n"); if (hotk->model == L2X) lcd = ~lcd; @@ -439,7 +457,7 @@ acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch, NULL, NULL); if (ACPI_FAILURE(status)) - printk(KERN_NOTICE "Asus ACPI: Error switching LCD\n"); + printk(KERN_WARNING "Asus ACPI: Error switching LCD\n"); } return count; @@ -453,15 +471,15 @@ { acpi_status status = 0; - /* ATKD laptop */ + /* SPLV laptop */ if(hotk->methods->brightness_set) { if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, value, NULL)) - printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n"); + printk(KERN_WARNING "Asus ACPI: Error changing brightness\n"); return; } - /* HOTK laptop if we are here, act as appropriate */ + /* No SPLV method if we are here, act as appropriate */ value -= hotk->brightness; while (value != 0) { status = acpi_evaluate_object(NULL, (value > 0) ? @@ -470,7 +488,7 @@ NULL, NULL); (value > 0) ? value-- : value++; if (ACPI_FAILURE(status)) - printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n"); + printk(KERN_WARNING "Asus ACPI: Error changing brightness\n"); } return; } @@ -479,15 +497,15 @@ { int value; - if(hotk->methods->brightness_get) { /* ATKD laptop */ + if(hotk->methods->brightness_get) { /* SPLV/GPLV laptop */ if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, &value)) - printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n"); + printk(KERN_WARNING "Asus ACPI: Error reading brightness\n"); } else if (hotk->methods->brightness_status) { /* For D1 for example */ if (!read_acpi_int(NULL, hotk->methods->brightness_status, &value)) - printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n"); - } else /* HOTK laptop */ + printk(KERN_WARNING "Asus ACPI: Error reading brightness\n"); + } else /* No GPLV method */ value = hotk->brightness; return value; } @@ -513,7 +531,7 @@ /* 0 <= value <= 15 */ set_brightness(value, hotk); } else { - printk(KERN_NOTICE "Asus ACPI: Error reading user input\n"); + printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); } return count; @@ -524,7 +542,7 @@ /* no sanity check needed for now */ if (!write_acpi_int(hotk->handle, hotk->methods->display_set, value, NULL)) - printk(KERN_NOTICE "Asus ACPI: Error setting display\n"); + printk(KERN_WARNING "Asus ACPI: Error setting display\n"); return; } @@ -541,12 +559,12 @@ struct asus_hotk *hotk = (struct asus_hotk *) data; if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) - printk(KERN_NOTICE "Asus ACPI: Error reading display status\n"); + printk(KERN_WARNING "Asus ACPI: Error reading display status\n"); return sprintf(page, "%d\n", value); } /* - * Preliminary support for display switching. As of now: 0x01 should activate + * Experimental support for display switching. As of now: 0x01 should activate * the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination * (bitwise) of these will suffice. I never actually tested 3 displays hooked up * simultaneously, so be warned. @@ -563,13 +581,13 @@ if (sscanf(buffer, "%d", &value) == 1) set_display(value, hotk); else { - printk(KERN_NOTICE "Asus ACPI: Error reading user input\n"); + printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); } return count; } -static int asus_hotk_add_fs(struct acpi_device *device) +static int __init asus_hotk_add_fs(struct acpi_device *device) { struct proc_dir_entry *proc; struct asus_hotk *hotk = acpi_driver_data(device); @@ -583,7 +601,7 @@ if ((asus_uid == 0) && (asus_gid == 0)){ mode = S_IFREG | S_IRUGO | S_IWUGO; - }else{ + } else { mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; } @@ -599,7 +617,7 @@ proc->uid = asus_uid; proc->gid = asus_gid;; } else { - printk(KERN_NOTICE " Unable to create " PROC_INFOS + printk(KERN_WARNING " Unable to create " PROC_INFOS " fs entry\n"); } @@ -613,7 +631,7 @@ proc->uid = asus_uid; proc->gid = asus_gid;; } else { - printk(KERN_NOTICE " Unable to create " PROC_WLED + printk(KERN_WARNING " Unable to create " PROC_WLED " fs entry\n"); } } @@ -628,7 +646,7 @@ proc->uid = asus_uid; proc->gid = asus_gid;; } else { - printk(KERN_NOTICE " Unable to create " PROC_MLED + printk(KERN_WARNING " Unable to create " PROC_MLED " fs entry\n"); } } @@ -647,7 +665,7 @@ proc->uid = asus_uid; proc->gid = asus_gid;; } else { - printk(KERN_NOTICE " Unable to create " PROC_LCD + printk(KERN_WARNING " Unable to create " PROC_LCD " fs entry\n"); } } @@ -663,7 +681,7 @@ proc->uid = asus_uid; proc->gid = asus_gid;; } else { - printk(KERN_NOTICE " Unable to create " PROC_BRN + printk(KERN_WARNING " Unable to create " PROC_BRN " fs entry\n"); } } @@ -678,19 +696,19 @@ proc->uid = asus_uid; proc->gid = asus_gid;; } else { - printk(KERN_NOTICE " Unable to create " PROC_DISP + printk(KERN_WARNING " Unable to create " PROC_DISP " fs entry\n"); } } - return (AE_OK); + return 0; } static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) { /* TODO Find a better way to handle events count. Here, in data, we receive - * the hotk, so we can make anything !! + * the hotk, so we can do anything! */ struct asus_hotk *hotk = (struct asus_hotk *) data; @@ -713,19 +731,40 @@ * This function is used to initialize the hotk with right values. In this * method, we can make all the detection we want, and modify the hotk struct */ -static int asus_hotk_get_info(struct asus_hotk *hotk) +static int __init asus_hotk_get_info(struct asus_hotk *hotk) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; + int bsts_result; + acpi_status status; - /* - * We have to write 0 on init this far for all ASUS models + /* + * Get DSDT headers early enough to allow for differentiating between + * models, but late enough to allow acpi_bus_register_driver() to fail + * before doing anything ACPI-specific. Should we encounter a machine, + * which needs special handling (i.e. its hotkey device has a different + * HID), this bit will be moved. A global variable asus_info contains + * the DSDT header. */ + status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); + if (ACPI_FAILURE(status)) + printk(KERN_WARNING " Couldn't get the DSDT table header\n"); + else + asus_info = (struct acpi_table_header *) dsdt.pointer; + + /* We have to write 0 on init this far for all ASUS models */ if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { - printk(KERN_NOTICE " Hotkey initialization failed\n"); + printk(KERN_ERR " Hotkey initialization failed\n"); return -ENODEV; } + /* For testing purposes */ + if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result)) + printk(KERN_WARNING " Error calling BSTS\n"); + else if (bsts_result) + printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", bsts_result); + /* * Here, we also use asus_info to make decision. For example, on INIT * method, S1X and L1X models both reports to be L84F, but they don't @@ -750,26 +789,34 @@ hotk->model = L3X; else if (strncmp(model->string.pointer, "M2", 2) == 0) hotk->model = M2X; + else if (strncmp(model->string.pointer, "M3N", 3) == 0 || + strncmp(model->string.pointer, "S1N", 3) == 0) + hotk->model = M3N; /* S1300N is similar enough */ else if (strncmp(model->string.pointer, "L2", 2) == 0) hotk->model = L2X; - else if (strncmp(model->string.pointer, "L8", 2) == 0) + else if (strncmp(model->string.pointer, "L8", 2) == 0) { /* S1300A reports L84F, but L1400B too */ - if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) - hotk->model = L1X; - else + if (asus_info) { + if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) + hotk->model = L1X; + } else hotk->model = S1X; + } else if (strncmp(model->string.pointer, "D1", 2) == 0) hotk->model = D1X; else if (strncmp(model->string.pointer, "A1", 2) == 0) hotk->model = A1X; + else if (strncmp(model->string.pointer, "A2", 2) == 0) + hotk->model = A2X; else if (strncmp(model->string.pointer, "J1", 2) == 0) - hotk->model = J1X; - + hotk->model = S2X; + else if (strncmp(model->string.pointer, "L5", 2) == 0) + hotk->model = L5X; if (hotk->model == END_MODEL) { /* By default use the same values, as I don't know others */ - printk("unsupported, trying default values, contact the " - "developers\n"); + printk("unsupported, trying default values, supply the " + "developers with your DSDT\n"); hotk->model = L2X; } else { printk("supported\n"); @@ -784,7 +831,7 @@ -static int asus_hotk_check(struct asus_hotk *hotk) +static int __init asus_hotk_check(struct asus_hotk *hotk) { int result = 0; @@ -798,7 +845,7 @@ if (hotk->device->status.present) { result = asus_hotk_get_info(hotk); } else { - printk(KERN_NOTICE " Hotkey device not present, aborting\n"); + printk(KERN_ERR " Hotkey device not present, aborting\n"); return(-EINVAL); } @@ -807,7 +854,7 @@ -static int asus_hotk_add(struct acpi_device *device) +static int __init asus_hotk_add(struct acpi_device *device) { struct asus_hotk *hotk = NULL; acpi_status status = AE_OK; @@ -816,6 +863,9 @@ if (!device) return(-EINVAL); + printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", + ASUS_ACPI_VERSION); + hotk = (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) @@ -843,25 +893,23 @@ */ status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, asus_hotk_notify, hotk); - if (ACPI_FAILURE(status)) { - printk(KERN_NOTICE - " Error installing notify handler\n"); - } else { - printk(KERN_DEBUG - " Notify Handler installed successfully\n"); - } + if (ACPI_FAILURE(status)) + printk(KERN_ERR " Error installing notify handler\n"); - /* For HOTK laptops: init the hotk->brightness value */ + /* For laptops without GPLV: init the hotk->brightness value */ if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) && (hotk->methods->brightness_up && hotk->methods->brightness_down)) { status = acpi_evaluate_object(NULL, hotk->methods->brightness_down, NULL, NULL); if (ACPI_FAILURE(status)) - printk(KERN_NOTICE " Error changing brightness\n"); - status = acpi_evaluate_object(NULL, hotk->methods->brightness_up, - NULL, NULL); - if (ACPI_FAILURE(status)) - printk(KERN_NOTICE " Error changing brightness\n"); + printk(KERN_WARNING " Error changing brightness\n"); + else { + status = acpi_evaluate_object(NULL, hotk->methods->brightness_up, + NULL, NULL); + if (ACPI_FAILURE(status)) + printk(KERN_WARNING " Strange, error changing" + " brightness\n"); + } } end: @@ -888,7 +936,7 @@ status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, asus_hotk_notify); if (ACPI_FAILURE(status)) - printk(KERN_NOTICE "Error removing notify handler\n"); + printk(KERN_ERR "Asus ACPI: Error removing notify handler\n"); kfree(hotk); @@ -900,35 +948,17 @@ static int __init asus_acpi_init(void) { - int result = 0; - acpi_status status = 0; - struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; - - printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", - ASUS_ACPI_VERSION); - /* - * Here is the code to know the model we are running on. We need to - * know this before calling the acpi_bus_register_driver function, in - * case the HID for the laptop we are running on is different from - * ACPI_HOTK_HID, which I have never seen yet :) - * - * This information is then available in the global var asus_info - */ - status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); - if (ACPI_FAILURE(status)) { - printk(KERN_NOTICE " Couldn't get the DSDT table header\n"); - } else { - asus_info = (struct acpi_table_header *) dsdt.pointer; - } + int result; asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); - if (!asus_proc_dir) + if (!asus_proc_dir) { + printk(KERN_ERR "Asus ACPI: Unable to create /proc entry"); return(-ENODEV); + } asus_proc_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&asus_hotk_driver); if (result < 0) { - printk(KERN_NOTICE " Error registering " ACPI_HOTK_NAME " \n"); remove_proc_entry(PROC_ASUS, acpi_root_dir); return(-ENODEV); } diff -urN linux-2.4.22-bk27/drivers/acpi/bus.c linux-2.4.22-bk28/drivers/acpi/bus.c --- linux-2.4.22-bk27/drivers/acpi/bus.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/bus.c 2003-10-02 02:49:34.000000000 -0700 @@ -1898,9 +1898,7 @@ * of that. */ result = acpi_ec_ecdt_probe(); - if (result) { - goto error1; - } + /* Ignore result. Not having an ECDT is not fatal. */ #endif status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dsfield.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dsfield.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dsfield.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dsfield.c 2003-10-02 02:49:34.000000000 -0700 @@ -105,27 +105,33 @@ return_ACPI_STATUS (AE_AML_NO_OPERAND); } - /* - * During the load phase, we want to enter the name of the field into - * the namespace. During the execute phase (when we evaluate the size - * operand), we want to lookup the name - */ - if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) { - flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; + if (walk_state->deferred_node) { + node = walk_state->deferred_node; + status = AE_OK; } else { - flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; - } + /* + * During the load phase, we want to enter the name of the field into + * the namespace. During the execute phase (when we evaluate the size + * operand), we want to lookup the name + */ + if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) { + flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; + } + else { + flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; + } - /* - * Enter the name_string into the namespace - */ - status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, - ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, - flags, walk_state, &(node)); - if (ACPI_FAILURE (status)) { - ACPI_REPORT_NSERROR (arg->common.value.string, status); - return_ACPI_STATUS (status); + /* + * Enter the name_string into the namespace + */ + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, + flags, walk_state, &(node)); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.string, status); + return_ACPI_STATUS (status); + } } /* We could put the returned object (Node) on the object stack for later, but diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dsinit.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dsinit.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dsinit.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dsinit.c 2003-10-02 02:49:34.000000000 -0700 @@ -135,7 +135,7 @@ } /* - * Always parse methods to detect errors, we may delete + * Always parse methods to detect errors, we will delete * the parse tree below */ status = acpi_ds_parse_method (obj_handle); @@ -150,7 +150,7 @@ } /* - * Delete the parse tree. We simple re-parse the method + * Delete the parse tree. We simply re-parse the method * for every execution since there isn't much overhead */ acpi_ns_delete_namespace_subtree (obj_handle); diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dsopcode.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dsopcode.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dsopcode.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dsopcode.c 2003-10-02 02:49:34.000000000 -0700 @@ -65,7 +65,7 @@ * * RETURN: Status. * - * DESCRIPTION: Late execution of region or field arguments + * DESCRIPTION: Late (deferred) execution of region or field arguments * ****************************************************************************/ @@ -111,7 +111,10 @@ return_ACPI_STATUS (status); } + /* Mark this parse as a deferred opcode */ + walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; + walk_state->deferred_node = node; /* Pass1: Parse the entire declaration */ @@ -128,7 +131,7 @@ arg->common.node = node; acpi_ps_delete_parse_tree (op); - /* Evaluate the address and length arguments for the Buffer Field */ + /* Evaluate the deferred arguments */ op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); if (!op) { @@ -144,6 +147,8 @@ return_ACPI_STATUS (AE_NO_MEMORY); } + /* Execute the opcode and arguments */ + status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, aml_length, NULL, NULL, 3); if (ACPI_FAILURE (status)) { @@ -151,6 +156,9 @@ return_ACPI_STATUS (status); } + /* Mark this execution as a deferred opcode */ + + walk_state->deferred_node = node; status = acpi_ps_parse_aml (walk_state); acpi_ps_delete_parse_tree (op); return_ACPI_STATUS (status); @@ -192,7 +200,7 @@ node = obj_desc->buffer_field.node; ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL)); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field JIT Init\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n", node->name.ascii)); /* Execute the AML code for the term_arg arguments */ @@ -207,7 +215,7 @@ * * FUNCTION: acpi_ds_get_buffer_arguments * - * PARAMETERS: obj_desc - A valid Bufferobject + * PARAMETERS: obj_desc - A valid Buffer object * * RETURN: Status. * @@ -240,7 +248,7 @@ return_ACPI_STATUS (AE_AML_INTERNAL); } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer JIT Init\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n")); /* Execute the AML code for the term_arg arguments */ @@ -254,7 +262,7 @@ * * FUNCTION: acpi_ds_get_package_arguments * - * PARAMETERS: obj_desc - A valid Packageobject + * PARAMETERS: obj_desc - A valid Package object * * RETURN: Status. * @@ -287,7 +295,7 @@ return_ACPI_STATUS (AE_AML_INTERNAL); } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package JIT Init\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n")); /* Execute the AML code for the term_arg arguments */ @@ -335,11 +343,12 @@ node = obj_desc->region.node; - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); + ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Init at AML %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n", node->name.ascii, extra_desc->extra.aml_start)); + /* Execute the argument AML */ status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), extra_desc->extra.aml_length, extra_desc->extra.aml_start); @@ -505,14 +514,16 @@ goto cleanup; } - /* Entire field must fit within the current length of the buffer */ if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Field size %d exceeds Buffer size %d (bits)\n", - bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length)); + "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", + ((struct acpi_namespace_node *) result_desc)->name.ascii, + bit_offset + bit_count, + buffer_desc->buffer.node->name.ascii, + 8 * (u32) buffer_desc->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dsutils.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dsutils.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dsutils.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dsutils.c 2003-10-02 02:49:34.000000000 -0700 @@ -53,6 +53,7 @@ #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsutils") + #ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* @@ -196,7 +197,6 @@ acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op)); return_VALUE (FALSE); - } @@ -239,7 +239,6 @@ return_VOID; } - if (!acpi_ds_is_result_used (op, walk_state)) { /* * Must pop the result stack (obj_desc should be equal to result_obj) @@ -389,61 +388,77 @@ * in name_string */ + /* - * Differentiate between a namespace "create" operation - * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. - * IMODE_EXECUTE) in order to support the creation of - * namespace objects during the execution of control methods. + * Special handling for buffer_field declarations. This is a deferred + * opcode that unfortunately defines the field name as the last + * parameter instead of the first. We get here when we are performing + * the deferred execution, so the actual name of the field is already + * in the namespace. We don't want to attempt to look it up again + * because we may be executing in a different scope than where the + * actual opcode exists. */ - parent_op = arg->common.parent; - op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode); - if ((op_info->flags & AML_NSNODE) && - (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) && - (parent_op->common.aml_opcode != AML_REGION_OP) && - (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) { - /* Enter name into namespace if not found */ - - interpreter_mode = ACPI_IMODE_LOAD_PASS2; + if ((walk_state->deferred_node) && + (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) && + (arg_index != 0)) { + obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node); + status = AE_OK; } + else /* All other opcodes */ { + /* + * Differentiate between a namespace "create" operation + * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. + * IMODE_EXECUTE) in order to support the creation of + * namespace objects during the execution of control methods. + */ + parent_op = arg->common.parent; + op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode); + if ((op_info->flags & AML_NSNODE) && + (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) && + (parent_op->common.aml_opcode != AML_REGION_OP) && + (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) { + /* Enter name into namespace if not found */ - else { - /* Return a failure if name not found */ - - interpreter_mode = ACPI_IMODE_EXECUTE; - } + interpreter_mode = ACPI_IMODE_LOAD_PASS2; + } + else { + /* Return a failure if name not found */ - status = acpi_ns_lookup (walk_state->scope_info, name_string, - ACPI_TYPE_ANY, interpreter_mode, - ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, - walk_state, - ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc)); - /* - * The only case where we pass through (ignore) a NOT_FOUND - * error is for the cond_ref_of opcode. - */ - if (status == AE_NOT_FOUND) { - if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) { - /* - * For the Conditional Reference op, it's OK if - * the name is not found; We just need a way to - * indicate this to the interpreter, set the - * object to the root - */ - obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node); - status = AE_OK; + interpreter_mode = ACPI_IMODE_EXECUTE; } - else { - /* - * We just plain didn't find it -- which is a - * very serious error at this point - */ - status = AE_AML_NAME_NOT_FOUND; + status = acpi_ns_lookup (walk_state->scope_info, name_string, + ACPI_TYPE_ANY, interpreter_mode, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, + walk_state, + ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc)); + /* + * The only case where we pass through (ignore) a NOT_FOUND + * error is for the cond_ref_of opcode. + */ + if (status == AE_NOT_FOUND) { + if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) { + /* + * For the Conditional Reference op, it's OK if + * the name is not found; We just need a way to + * indicate this to the interpreter, set the + * object to the root + */ + obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node); + status = AE_OK; + } + else { + /* + * We just plain didn't find it -- which is a + * very serious error at this point + */ + status = AE_AML_NAME_NOT_FOUND; + } } - } - if (ACPI_FAILURE (status)) { - ACPI_REPORT_NSERROR (name_string, status); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (name_string, status); + } } /* Free the namestring created above */ @@ -464,8 +479,6 @@ } ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state)); } - - else { /* Check for null name case */ @@ -480,7 +493,6 @@ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg)); } - else { opcode = arg->common.aml_opcode; } diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dswload.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dswload.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dswload.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dswload.c 2003-10-02 02:49:34.000000000 -0700 @@ -248,6 +248,14 @@ * buffer_field, or Package), the name of the object is already * in the namespace. */ + if (walk_state->deferred_node) { + /* This name is already in the namespace, get the node */ + + node = walk_state->deferred_node; + status = AE_OK; + break; + } + flags = ACPI_NS_NO_UPSEARCH; if ((walk_state->opcode != AML_SCOPE_OP) && (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { @@ -589,7 +597,17 @@ * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve * arguments to the opcode must be created as we go back up the parse tree later. + * + * Note: Name may already exist if we are executing a deferred opcode. */ + if (walk_state->deferred_node) { + /* This name is already in the namespace, get the node */ + + node = walk_state->deferred_node; + status = AE_OK; + break; + } + status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node)); break; diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dswscope.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dswscope.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dswscope.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dswscope.c 2003-10-02 02:49:34.000000000 -0700 @@ -121,10 +121,9 @@ /* Make sure object type is valid */ if (!acpi_ut_valid_object_type (type)) { - ACPI_REPORT_WARNING (("ds_scope_stack_push: type code out of range\n")); + ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type)); } - /* Allocate a new scope object */ scope_info = acpi_ut_create_generic_state (); @@ -146,13 +145,13 @@ old_scope_info = walk_state->scope_info; if (old_scope_info) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, - "[%4.4s] (%10s)", + "[%4.4s] (%s)", old_scope_info->scope.node->name.ascii, acpi_ut_get_type_name (old_scope_info->common.value))); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, - "[\\___] (%10s)", "ROOT")); + "[\\___] (%s)", "ROOT")); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, @@ -163,7 +162,6 @@ /* Push new scope object onto stack */ acpi_ut_push_generic_state (&walk_state->scope_info, scope_info); - return_ACPI_STATUS (AE_OK); } @@ -207,7 +205,7 @@ walk_state->scope_depth--; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "[%.2d] Popped scope [%4.4s] (%10s), New scope -> ", + "[%.2d] Popped scope [%4.4s] (%s), New scope -> ", (u32) walk_state->scope_depth, scope_info->scope.node->name.ascii, acpi_ut_get_type_name (scope_info->common.value))); @@ -225,7 +223,6 @@ } acpi_ut_delete_generic_state (scope_info); - return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.22-bk27/drivers/acpi/dispatcher/dswstate.c linux-2.4.22-bk28/drivers/acpi/dispatcher/dswstate.c --- linux-2.4.22-bk27/drivers/acpi/dispatcher/dswstate.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/dispatcher/dswstate.c 2003-10-02 02:49:34.000000000 -0700 @@ -56,11 +56,12 @@ * FUNCTION: acpi_ds_result_insert * * PARAMETERS: Object - Object to push + * Index - Where to insert the object * walk_state - Current Walk state * * RETURN: Status * - * DESCRIPTION: Push an object onto this walk's result stack + * DESCRIPTION: Insert an object onto this walk's result stack * ******************************************************************************/ @@ -114,6 +115,7 @@ * FUNCTION: acpi_ds_result_remove * * PARAMETERS: Object - Where to return the popped object + * Index - Where to extract the object * walk_state - Current Walk state * * RETURN: Status @@ -233,6 +235,7 @@ return (AE_AML_NO_RETURN_VALUE); } + /******************************************************************************* * * FUNCTION: acpi_ds_result_pop_from_bottom @@ -295,7 +298,6 @@ *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL", state, walk_state)); - return (AE_OK); } @@ -358,8 +360,7 @@ * * FUNCTION: acpi_ds_result_stack_push * - * PARAMETERS: Object - Object to push - * walk_state - Current Walk state + * PARAMETERS: walk_state - Current Walk state * * RETURN: Status * @@ -420,7 +421,6 @@ return (AE_AML_NO_OPERAND); } - state = acpi_ut_pop_generic_state (&walk_state->results); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, @@ -572,6 +572,7 @@ } #endif + /******************************************************************************* * * FUNCTION: acpi_ds_obj_stack_pop @@ -641,6 +642,7 @@ u32 i; union acpi_operand_object *obj_desc; + ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete"); @@ -883,8 +885,15 @@ * FUNCTION: acpi_ds_init_aml_walk * * PARAMETERS: walk_state - New state to be initialized + * Op - Current parse op + * method_node - Control method NS node, if any + * aml_start - Start of AML + * aml_length - Length of AML + * Params - Method args, if any + * return_obj_desc - Where to store a return object, if any + * pass_number - 1, 2, or 3 * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk * @@ -927,9 +936,9 @@ if (method_node) { walk_state->parser_state.start_node = method_node; - walk_state->walk_type = ACPI_WALK_METHOD; - walk_state->method_node = method_node; - walk_state->method_desc = acpi_ns_get_attached_object (method_node); + walk_state->walk_type = ACPI_WALK_METHOD; + walk_state->method_node = method_node; + walk_state->method_desc = acpi_ns_get_attached_object (method_node); /* Push start scope on scope stack and make it current */ @@ -956,6 +965,7 @@ while (extra_op && !extra_op->common.node) { extra_op = extra_op->common.parent; } + if (!extra_op) { parser_state->start_node = NULL; } @@ -1014,7 +1024,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state)); } - /* Always must free any linked control states */ + /* Always must free any linked control states */ while (walk_state->control_state) { state = walk_state->control_state; diff -urN linux-2.4.22-bk27/drivers/acpi/executer/excreate.c linux-2.4.22-bk28/drivers/acpi/executer/excreate.c --- linux-2.4.22-bk27/drivers/acpi/executer/excreate.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/executer/excreate.c 2003-10-02 02:49:34.000000000 -0700 @@ -286,7 +286,7 @@ ACPI_FUNCTION_TRACE ("ex_create_region"); - /* Get the Node from the object stack */ + /* Get the Namespace Node */ node = walk_state->op->common.node; @@ -311,7 +311,6 @@ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n", acpi_ut_get_region_name (region_space), region_space)); - /* Create the region descriptor */ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION); @@ -375,6 +374,7 @@ ACPI_FUNCTION_TRACE ("ex_create_table_region"); + /* Get the Node from the object stack */ node = walk_state->op->common.node; @@ -392,7 +392,6 @@ status = acpi_tb_find_table (operand[1]->string.pointer, operand[2]->string.pointer, operand[3]->string.pointer, &table); - if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -489,7 +488,6 @@ status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0], obj_desc, ACPI_TYPE_PROCESSOR); - /* Remove local reference to the object */ acpi_ut_remove_reference (obj_desc); @@ -540,7 +538,6 @@ status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0], obj_desc, ACPI_TYPE_POWER); - /* Remove local reference to the object */ acpi_ut_remove_reference (obj_desc); @@ -609,7 +606,6 @@ obj_desc->method.concurrency = (u8) (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1); } - else { obj_desc->method.concurrency = INFINITE_CONCURRENCY; } diff -urN linux-2.4.22-bk27/drivers/acpi/namespace/nsdump.c linux-2.4.22-bk28/drivers/acpi/namespace/nsdump.c --- linux-2.4.22-bk27/drivers/acpi/namespace/nsdump.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/namespace/nsdump.c 2003-10-02 02:49:34.000000000 -0700 @@ -234,7 +234,7 @@ case ACPI_TYPE_DEVICE: - acpi_os_printf ("Notify object: %p", obj_desc); + acpi_os_printf ("Notify Object: %p\n", obj_desc); break; @@ -371,7 +371,7 @@ case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_os_printf (" Off %.2X Len %.2X Acc %.2hd\n", + acpi_os_printf ("Off %.2X Len %.2X Acc %.2hd\n", (obj_desc->common_field.base_byte_offset * 8) + obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.bit_length, diff -urN linux-2.4.22-bk27/drivers/acpi/namespace/nssearch.c linux-2.4.22-bk28/drivers/acpi/namespace/nssearch.c --- linux-2.4.22-bk27/drivers/acpi/namespace/nssearch.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/namespace/nssearch.c 2003-10-02 02:49:34.000000000 -0700 @@ -96,7 +96,7 @@ scope_name = acpi_ns_get_external_pathname (node); if (scope_name) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s [%p] For %4.4s (%s)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s (%p) For [%4.4s] (%s)\n", scope_name, node, (char *) &target_name, acpi_ut_get_type_name (type))); ACPI_MEM_FREE (scope_name); @@ -117,9 +117,9 @@ * Found matching entry. */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Name %4.4s Type [%s] found in scope [%4.4s] %p\n", + "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", (char *) &target_name, acpi_ut_get_type_name (next_node->type), - next_node->name.ascii, next_node)); + next_node, node->name.ascii, node)); *return_node = next_node; return_ACPI_STATUS (AE_OK); @@ -143,7 +143,7 @@ /* Searched entire namespace level, not found */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Name %4.4s Type [%s] not found in search in scope [%4.4s] %p first child %p\n", + "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", (char *) &target_name, acpi_ut_get_type_name (type), node->name.ascii, node, node->child)); diff -urN linux-2.4.22-bk27/drivers/acpi/namespace/nsutils.c linux-2.4.22-bk28/drivers/acpi/namespace/nsutils.c --- linux-2.4.22-bk27/drivers/acpi/namespace/nsutils.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/namespace/nsutils.c 2003-10-02 02:49:34.000000000 -0700 @@ -175,6 +175,11 @@ acpi_status status; + if (!node) { + acpi_os_printf ("[NULL NAME]"); + return; + } + /* Convert handle to a full pathname and print it (with supplied message) */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; @@ -470,11 +475,11 @@ *result = 0; if (info->fully_qualified) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (abs) \"\\%s\"\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", internal_name, internal_name)); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (rel) \"%s\"\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", internal_name, internal_name)); } diff -urN linux-2.4.22-bk27/drivers/acpi/parser/psparse.c linux-2.4.22-bk28/drivers/acpi/parser/psparse.c --- linux-2.4.22-bk27/drivers/acpi/parser/psparse.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/parser/psparse.c 2003-10-02 02:49:34.000000000 -0700 @@ -437,7 +437,6 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - parser_state = &walk_state->parser_state; walk_state->arg_types = 0; @@ -705,10 +704,9 @@ walk_state->arg_types = 0; break; - default: - /* Op is not a constant or string, append each argument */ + /* Op is not a constant or string, append each argument to the Op */ while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) { @@ -727,23 +725,23 @@ INCREMENT_ARG_LIST (walk_state->arg_types); } + /* Special processing for certain opcodes */ + switch (op->common.aml_opcode) { case AML_METHOD_OP: - /* For a method, save the length and address of the body */ - /* - * Skip parsing of control method or opregion body, + * Skip parsing of control method * because we don't have enough info in the first pass - * to parse them correctly. + * to parse it correctly. + * + * Save the length and address of the body */ op->named.data = parser_state->aml; op->named.length = (u32) (parser_state->pkg_end - parser_state->aml); - /* - * Skip body of method. For op_regions, we must continue - * parsing because the opregion is not a standalone - * package (We don't know where the end is). - */ + + /* Skip body of method */ + parser_state->aml = parser_state->pkg_end; walk_state->arg_count = 0; break; @@ -756,15 +754,15 @@ (op->common.parent->common.aml_opcode == AML_NAME_OP) && (walk_state->descending_callback != acpi_ds_exec_begin_op)) { /* - * Skip parsing of + * Skip parsing of Buffers and Packages * because we don't have enough info in the first pass * to parse them correctly. */ op->named.data = aml_op_start; op->named.length = (u32) (parser_state->pkg_end - aml_op_start); - /* - * Skip body - */ + + /* Skip body */ + parser_state->aml = parser_state->pkg_end; walk_state->arg_count = 0; } @@ -778,6 +776,7 @@ break; default: + /* No action for all other opcodes */ break; } diff -urN linux-2.4.22-bk27/drivers/acpi/pci_irq.c linux-2.4.22-bk28/drivers/acpi/pci_irq.c --- linux-2.4.22-bk27/drivers/acpi/pci_irq.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/pci_irq.c 2003-10-02 02:49:34.000000000 -0700 @@ -73,6 +73,9 @@ ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry"); + if (!acpi_prt.count) + return_PTR(NULL); + /* * Parse through all PRT entries looking for a match on the specified * PCI device's segment, bus, device, and pin (don't care about func). diff -urN linux-2.4.22-bk27/drivers/acpi/pci_link.c linux-2.4.22-bk28/drivers/acpi/pci_link.c --- linux-2.4.22-bk27/drivers/acpi/pci_link.c 2003-10-02 02:49:29.000000000 -0700 +++ linux-2.4.22-bk28/drivers/acpi/pci_link.c 2003-10-02 02:49:34.000000000 -0700 @@ -499,16 +499,16 @@ irq = link->irq.active; } else { irq = link->irq.possible[0]; - } - /* - * Select the best IRQ. This is done in reverse to promote + /* + * Select the best IRQ. This is done in reverse to promote * the use of IRQs 9, 10, 11, and >15. */ for (i=(link->irq.possible_count-1); i>0; i--) { if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]]) irq = link->irq.possible[i]; } + } /* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set(link, irq)) { diff -urN linux-2.4.22-bk27/drivers/char/Config.in linux-2.4.22-bk28/drivers/char/Config.in --- linux-2.4.22-bk27/drivers/char/Config.in 2003-10-02 02:49:29.000000000 -0700 +++ linux-2.4.22-bk28/drivers/char/Config.in 2003-10-02 02:49:34.000000000 -0700 @@ -104,11 +104,14 @@ fi fi fi -fi -if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then - bool 'SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL - if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then - bool ' SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE + if [ "$CONFIG_IA64" = "y" ]; then + bool ' SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL + if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then + bool ' SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE + fi + if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then + bool ' SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL + fi fi fi if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then diff -urN linux-2.4.22-bk27/drivers/char/agp/agpgart_be.c linux-2.4.22-bk28/drivers/char/agp/agpgart_be.c --- linux-2.4.22-bk27/drivers/char/agp/agpgart_be.c 2003-10-02 02:49:29.000000000 -0700 +++ linux-2.4.22-bk28/drivers/char/agp/agpgart_be.c 2003-10-02 02:49:34.000000000 -0700 @@ -49,7 +49,6 @@ #include #include #include -#include #include #include "agp.h" @@ -4810,52 +4809,6 @@ return 0; } -#define SYSCFG 0xC0010010 -#define IORR_BASE0 0xC0010016 -#define IORR_MASK0 0xC0010017 -#define AMD_K7_NUM_IORR 2 - -static int nvidia_init_iorr(u32 base, u32 size) -{ - u32 base_hi, base_lo; - u32 mask_hi, mask_lo; - u32 sys_hi, sys_lo; - u32 iorr_addr, free_iorr_addr; - - /* Find the iorr that is already used for the base */ - /* If not found, determine the uppermost available iorr */ - free_iorr_addr = AMD_K7_NUM_IORR; - for(iorr_addr = 0; iorr_addr < AMD_K7_NUM_IORR; iorr_addr++) { - rdmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi); - rdmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi); - - if ((base_lo & 0xfffff000) == (base & 0xfffff000)) - break; - - if ((mask_lo & 0x00000800) == 0) - free_iorr_addr = iorr_addr; - } - - if (iorr_addr >= AMD_K7_NUM_IORR) { - iorr_addr = free_iorr_addr; - if (iorr_addr >= AMD_K7_NUM_IORR) - return -EINVAL; - } - - base_hi = 0x0; - base_lo = (base & ~0xfff) | 0x18; - mask_hi = 0xf; - mask_lo = ((~(size - 1)) & 0xfffff000) | 0x800; - wrmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi); - wrmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi); - - rdmsr(SYSCFG, sys_lo, sys_hi); - sys_lo |= 0x00100000; - wrmsr(SYSCFG, sys_lo, sys_hi); - - return 0; -} - static int nvidia_configure(void) { int i, rc, num_dirs; @@ -4869,7 +4822,7 @@ pci_write_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE, current_size->size_value); - /* address to map to */ + /* address to map to */ pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APBASE, &apbase); apbase &= PCI_BASE_ADDRESS_MEM_MASK; agp_bridge.gart_bus_addr = apbase; @@ -4878,8 +4831,9 @@ pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APLIMIT, aplimit); pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APBASE, apbase); pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APLIMIT, aplimit); - if (0 != (rc = nvidia_init_iorr(apbase, current_size->size * 1024 * 1024))) - return rc; + + /* The original driver changed the IORR. We don't do that + because this should be handled by the BIOS. */ /* directory size is 64k */ num_dirs = current_size->size / 64; @@ -4937,10 +4891,6 @@ previous_size = A_SIZE_8(agp_bridge.previous_size); pci_write_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE, previous_size->size_value); - - /* restore iorr for previous aperture size */ - nvidia_init_iorr(agp_bridge.gart_bus_addr, - previous_size->size * 1024 * 1024); } static void nvidia_tlbflush(agp_memory * mem) diff -urN linux-2.4.22-bk27/drivers/char/sn_serial.c linux-2.4.22-bk28/drivers/char/sn_serial.c --- linux-2.4.22-bk27/drivers/char/sn_serial.c 2003-10-02 02:49:30.000000000 -0700 +++ linux-2.4.22-bk28/drivers/char/sn_serial.c 2003-10-02 02:49:34.000000000 -0700 @@ -38,27 +38,19 @@ */ #include -#include #include #include #include #include #include -#ifdef CONFIG_MAGIC_SYSRQ #include -#endif -#include #include #include -#include -#include -#include +#include #include -#include +#include /* this is needed for get_console_nasid */ #include -#include #include -#include #if defined(CONFIG_SGI_L1_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) static char sysrq_serial_str[] = "\eSYS"; @@ -66,60 +58,53 @@ static unsigned long sysrq_requested; #endif /* CONFIG_SGI_L1_SERIAL_CONSOLE && CONFIG_MAGIC_SYSRQ */ -static char *serial_revdate = "2003-07-31"; - -/* driver subtype - what does this mean? */ -#define SN_SAL_SUBTYPE 1 - /* minor device number */ #define SN_SAL_MINOR 64 +#define SN_SAL_SUBTYPE 1 + /* number of characters left in xmit buffer before we ask for more */ #define WAKEUP_CHARS 128 /* number of characters we can transmit to the SAL console at a time */ #define SN_SAL_MAX_CHARS 120 -/* event types for our task queue -- so far just one */ #define SN_SAL_EVENT_WRITE_WAKEUP 0 #define CONSOLE_RESTART 1 + /* 64K, when we're asynch, it must be at least printk's LOG_BUF_LEN to * avoid losing chars, (always has to be a power of 2) */ -#if 1 #define SN_SAL_BUFFER_SIZE (64 * (1 << 10)) -#else -#define SN_SAL_BUFFER_SIZE (64) -#endif #define SN_SAL_UART_FIFO_DEPTH 16 #define SN_SAL_UART_FIFO_SPEED_CPS 9600/10 /* we don't kmalloc/get_free_page these as we want them available * before either of those are initialized */ -static volatile char xmit_buff_mem[SN_SAL_BUFFER_SIZE]; +static char sn_xmit_buff_mem[SN_SAL_BUFFER_SIZE]; struct volatile_circ_buf { - volatile char *buf; - int head; - int tail; + char *cb_buf; + int cb_head; + int cb_tail; }; -static volatile struct volatile_circ_buf xmit = { .buf = xmit_buff_mem }; -static char sal_tmp_buffer[SN_SAL_BUFFER_SIZE]; +static struct volatile_circ_buf xmit = { .cb_buf = sn_xmit_buff_mem }; +static char sn_tmp_buffer[SN_SAL_BUFFER_SIZE]; -static volatile struct tty_struct *sn_sal_tty; +static struct tty_struct *sn_sal_tty; static struct timer_list sn_sal_timer; static int sn_sal_event; /* event type for task queue */ static int sn_sal_refcount; -static volatile int sn_sal_is_asynch; -static volatile int sn_sal_irq; +static int sn_sal_is_asynch; +static int sn_sal_irq; static spinlock_t sn_sal_lock = SPIN_LOCK_UNLOCKED; -static volatile int tx_count; -static volatile int rx_count; +static int sn_total_tx_count; +static int sn_total_rx_count; static struct tty_struct *sn_sal_table; static struct termios *sn_sal_termios; @@ -128,32 +113,63 @@ static void sn_sal_tasklet_action(unsigned long data); static DECLARE_TASKLET(sn_sal_tasklet, sn_sal_tasklet_action, 0); -static volatile unsigned long interrupt_timeout; +static unsigned long sn_interrupt_timeout; extern u64 master_node_bedrock_address; -int debug_printf(const char *fmt, ...); +static int sn_debug_printf(const char *fmt, ...); #undef DEBUG #ifdef DEBUG -#define DPRINTF(x...) debug_printf(x) +#define DPRINTF(x...) sn_debug_printf(x) #else #define DPRINTF(x...) do { } while (0) #endif -static void intr_transmit_chars(void); -static void poll_transmit_chars(void); -static int sn_sal_write(struct tty_struct *tty, int from_user, - const unsigned char *buf, int count); - struct sn_sal_ops { - int (*puts)(const char *s, int len); - int (*getc)(void); - int (*input_pending)(void); - void (*wakeup_transmit)(void); + int (*sal_puts)(const char *s, int len); + int (*sal_getc)(void); + int (*sal_input_pending)(void); + void (*sal_wakeup_transmit)(void); }; -static volatile struct sn_sal_ops *sn_sal_ops; +/* This is the pointer used. It is assigned to point to one of + * the tables below. + */ +static struct sn_sal_ops *sn_func; + +/* Prototypes */ +static int snt_hw_puts(const char *, int); +static int snt_poll_getc(void); +static int snt_poll_input_pending(void); +static int snt_sim_puts(const char *, int); +static int snt_sim_getc(void); +static int snt_sim_input_pending(void); +static int snt_intr_getc(void); +static int snt_intr_input_pending(void); +static void sn_intr_transmit_chars(void); + +/* A table for polling */ +static struct sn_sal_ops poll_ops = { + .sal_puts = snt_hw_puts, + .sal_getc = snt_poll_getc, + .sal_input_pending = snt_poll_input_pending +}; + +/* A table for the simulator */ +static struct sn_sal_ops sim_ops = { + .sal_puts = snt_sim_puts, + .sal_getc = snt_sim_getc, + .sal_input_pending = snt_sim_input_pending +}; + +/* A table for interrupts enabled */ +static struct sn_sal_ops intr_ops = { + .sal_puts = snt_hw_puts, + .sal_getc = snt_intr_getc, + .sal_input_pending = snt_intr_input_pending, + .sal_wakeup_transmit = sn_intr_transmit_chars +}; /* the console does output in two distinctly different ways: @@ -170,7 +186,8 @@ /* routines for running the console in polling mode */ -static int hw_puts(const char *s, int len) +static int +snt_hw_puts(const char *s, int len) { /* looking at the PROM source code, putb calls the flush * routine, so if we send characters in FIFO sized chunks, it @@ -178,14 +195,16 @@ return ia64_sn_console_putb(s, len); } -static int poll_getc(void) +static int +snt_poll_getc(void) { int ch; ia64_sn_console_getc(&ch); return ch; } -static int poll_input_pending(void) +static int +snt_poll_input_pending(void) { int status, input; @@ -193,16 +212,11 @@ return !status && input; } -static struct sn_sal_ops poll_ops = { - .puts = hw_puts, - .getc = poll_getc, - .input_pending = poll_input_pending -}; - /* routines for running the console on the simulator */ -static int sim_puts(const char *str, int count) +static int +snt_sim_puts(const char *str, int count) { int counter = count; @@ -223,65 +237,64 @@ return count; } -static int sim_getc(void) +static int +snt_sim_getc(void) { return readb(master_node_bedrock_address + (UART_RX << 3)); } -static int sim_input_pending(void) +static int +snt_sim_input_pending(void) { return readb(master_node_bedrock_address + (UART_LSR << 3)) & UART_LSR_DR; } -static struct sn_sal_ops sim_ops = { - .puts = sim_puts, - .getc = sim_getc, - .input_pending = sim_input_pending -}; - /* routines for an interrupt driven console (normal) */ -static int intr_getc(void) +static int +snt_intr_getc(void) { return ia64_sn_console_readc(); } -static int intr_input_pending(void) +static int +snt_intr_input_pending(void) { return ia64_sn_console_intr_status() & SAL_CONSOLE_INTR_RECV; } -static struct sn_sal_ops intr_ops = { - .puts = hw_puts, - .getc = intr_getc, - .input_pending = intr_input_pending, - .wakeup_transmit = intr_transmit_chars -}; - -extern void early_sn_setup(void); +/* The early printk (possible setup) and function call */ void early_printk_sn_sal(const char *s, unsigned count) { - if (!sn_sal_ops) { +#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM) + extern void early_sn_setup(void); +#endif + + if (!sn_func) { if (IS_RUNNING_ON_SIMULATOR()) - sn_sal_ops = &sim_ops; + sn_func = &sim_ops; else - sn_sal_ops = &poll_ops; + sn_func = &poll_ops; +#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM) early_sn_setup(); +#endif } - sn_sal_ops->puts(s, count); + sn_func->sal_puts(s, count); } /* this is as "close to the metal" as we can get, used when the driver * itself may be broken */ -int debug_printf(const char *fmt, ...) +static int +sn_debug_printf(const char *fmt, ...) { static char printk_buf[1024]; int printed_len; va_list args; + va_start(args, fmt); printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args); early_printk_sn_sal(printk_buf, printed_len); @@ -289,7 +302,7 @@ return printed_len; } -/********************************************************************* +/* * Interrupt handling routines. */ @@ -300,29 +313,29 @@ tasklet_schedule(&sn_sal_tasklet); } -/* receive_chars can be called before sn_sal_tty is initialized. in +/* sn_receive_chars can be called before sn_sal_tty is initialized. in * that case, its only use is to trigger sysrq and kdb */ static void -receive_chars(struct pt_regs *regs) +sn_receive_chars(struct pt_regs *regs, unsigned long *flags) { int ch; - while (sn_sal_ops->input_pending()) { - ch = sn_sal_ops->getc(); + while (sn_func->sal_input_pending()) { + ch = sn_func->sal_getc(); if (ch < 0) { printk(KERN_ERR "sn_serial: An error occured while " "obtaining data from the console (0x%0x)\n", ch); break; } - #if defined(CONFIG_SGI_L1_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) if (sysrq_requested) { unsigned long sysrq_timeout = sysrq_requested + HZ*5; + sysrq_requested = 0; if (ch && time_before(jiffies, sysrq_timeout)) { - spin_unlock(&sn_sal_lock); + spin_unlock_irqrestore(&sn_sal_lock, *flags); handle_sysrq(ch, regs, NULL, NULL); - spin_lock(&sn_sal_lock); + spin_lock_irqsave(&sn_sal_lock, *flags); /* don't record this char */ continue; } @@ -344,11 +357,11 @@ if (sn_sal_tty->flip.count == TTY_FLIPBUF_SIZE) break; } - rx_count++; + sn_total_rx_count++; } if (sn_sal_tty) - tty_flip_buffer_push(sn_sal_tty); + tty_flip_buffer_push((struct tty_struct *)sn_sal_tty); } @@ -360,43 +373,40 @@ int result; char *start; - if (xmit.head == xmit.tail) - /* Nothing to do. */ - return; + if (xmit.cb_head == xmit.cb_tail) + return; /* Nothing to do. */ - head = xmit.head; - tail = xmit.tail; - start = &xmit.buf[tail]; + head = xmit.cb_head; + tail = xmit.cb_tail; + start = &xmit.cb_buf[tail]; /* twice around gets the tail to the end of the buffer and * then to the head, if needed */ loops = (head < tail) ? 2 : 1; for (ii = 0; ii < loops; ii++) { - xmit_count = (head < tail) ? - (SN_SAL_BUFFER_SIZE - tail) : (head - tail); + xmit_count = (head < tail) ? (SN_SAL_BUFFER_SIZE - tail) : (head - tail); if (xmit_count > 0) { - result = sn_sal_ops->puts(start, xmit_count); + result = sn_func->sal_puts((char *)start, xmit_count); if (!result) - debug_printf("\n*** synch_flush_xmit failed to flush\n"); + sn_debug_printf("\n*** synch_flush_xmit failed to flush\n"); if (result > 0) { xmit_count -= result; - tx_count += result; + sn_total_tx_count += result; tail += result; tail &= SN_SAL_BUFFER_SIZE - 1; - xmit.tail = tail; - start = &xmit.buf[tail]; + xmit.cb_tail = tail; + start = (char *)&xmit.cb_buf[tail]; } } } - } /* must be called with a lock protecting the circular buffer and * sn_sal_tty */ static void -poll_transmit_chars(void) +sn_poll_transmit_chars(void) { int xmit_count, tail, head; int result; @@ -404,44 +414,40 @@ BUG_ON(!sn_sal_is_asynch); - if (xmit.head == xmit.tail || + if (xmit.cb_head == xmit.cb_tail || (sn_sal_tty && (sn_sal_tty->stopped || sn_sal_tty->hw_stopped))) { /* Nothing to do. */ return; } - head = xmit.head; - tail = xmit.tail; - start = &xmit.buf[tail]; + head = xmit.cb_head; + tail = xmit.cb_tail; + start = &xmit.cb_buf[tail]; - xmit_count = (head < tail) ? - (SN_SAL_BUFFER_SIZE - tail) : (head - tail); + xmit_count = (head < tail) ? (SN_SAL_BUFFER_SIZE - tail) : (head - tail); if (xmit_count == 0) - debug_printf("\n*** empty xmit_count\n"); + sn_debug_printf("\n*** empty xmit_count\n"); - if (xmit_count > SN_SAL_UART_FIFO_DEPTH) - xmit_count = SN_SAL_UART_FIFO_DEPTH; - /* use the ops, as we could be on the simulator */ - result = sn_sal_ops->puts(start, xmit_count); + result = sn_func->sal_puts((char *)start, xmit_count); if (!result) - debug_printf("\n*** error in synchronous puts\n"); + sn_debug_printf("\n*** error in synchronous sal_puts\n"); /* XXX chadt clean this up */ if (result > 0) { xmit_count -= result; - tx_count += result; + sn_total_tx_count += result; tail += result; tail &= SN_SAL_BUFFER_SIZE - 1; - xmit.tail = tail; - start = &xmit.buf[tail]; + xmit.cb_tail = tail; + start = &xmit.cb_buf[tail]; } /* if there's few enough characters left in the xmit buffer * that we could stand for the upper layer to send us some * more, ask for it. */ if (sn_sal_tty) - if (CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS) + if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS) sn_sal_sched_event(SN_SAL_EVENT_WRITE_WAKEUP); } @@ -449,7 +455,7 @@ /* must be called with a lock protecting the circular buffer and * sn_sal_tty */ static void -intr_transmit_chars(void) +sn_intr_transmit_chars(void) { int xmit_count, tail, head, loops, ii; int result; @@ -457,15 +463,15 @@ BUG_ON(!sn_sal_is_asynch); - if (xmit.head == xmit.tail || + if (xmit.cb_head == xmit.cb_tail || (sn_sal_tty && (sn_sal_tty->stopped || sn_sal_tty->hw_stopped))) { /* Nothing to do. */ return; } - head = xmit.head; - tail = xmit.tail; - start = &xmit.buf[tail]; + head = xmit.cb_head; + tail = xmit.cb_tail; + start = &xmit.cb_buf[tail]; /* twice around gets the tail to the end of the buffer and * then to the head, if needed */ @@ -476,18 +482,18 @@ (SN_SAL_BUFFER_SIZE - tail) : (head - tail); if (xmit_count > 0) { - result = ia64_sn_console_xmit_chars(start, xmit_count); + result = ia64_sn_console_xmit_chars((char *)start, xmit_count); #ifdef DEBUG if (!result) - debug_printf("`"); + sn_debug_printf("`"); #endif if (result > 0) { xmit_count -= result; - tx_count += result; + sn_total_tx_count += result; tail += result; tail &= SN_SAL_BUFFER_SIZE - 1; - xmit.tail = tail; - start = &xmit.buf[tail]; + xmit.cb_tail = tail; + start = &xmit.cb_buf[tail]; } } } @@ -496,7 +502,7 @@ * that we could stand for the upper layer to send us some * more, ask for it. */ if (sn_sal_tty) - if (CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS) + if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS) sn_sal_sched_event(SN_SAL_EVENT_WRITE_WAKEUP); } @@ -508,13 +514,14 @@ * SAL, since it doesn't intercept the UART interrupts * itself */ int status = ia64_sn_console_intr_status(); + unsigned long flags; - spin_lock(&sn_sal_lock); + spin_lock_irqsave(&sn_sal_lock, flags); if (status & SAL_CONSOLE_INTR_RECV) - receive_chars(regs); + sn_receive_chars(regs, &flags); if (status & SAL_CONSOLE_INTR_XMIT) - intr_transmit_chars(); - spin_unlock(&sn_sal_lock); + sn_intr_transmit_chars(); + spin_unlock_irqrestore(&sn_sal_lock, flags); } @@ -539,17 +546,15 @@ } console_nasid = ia64_sn_get_console_nasid(); - intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid)) - ->node_first_cpu; + intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu; intr_cpuloc = cpu_physical_id(intr_cpuid); console_irq = CPU_VECTOR_TO_IRQ(intr_cpuloc, SGI_UART_VECTOR); - result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR, - 0 /*not used*/, 0 /*not used*/); + result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR, 0 /*not used*/, 0 /*not used*/); BUG_ON(result != SGI_UART_VECTOR); - result = request_irq(console_irq, sn_sal_interrupt, - SA_INTERRUPT, "SAL console driver", &sn_sal_tty); + result = request_irq(console_irq, sn_sal_interrupt, SA_INTERRUPT, + "SAL console driver", &sn_sal_tty); if (result >= 0) return console_irq; @@ -557,11 +562,6 @@ return 0; } -/* - * End of the interrupt routines. - *********************************************************************/ - - static void sn_sal_tasklet_action(unsigned long data) { @@ -569,13 +569,14 @@ if (sn_sal_tty) { spin_lock_irqsave(&sn_sal_lock, flags); - if (sn_sal_tty) + if (sn_sal_tty) { if (test_and_clear_bit(SN_SAL_EVENT_WRITE_WAKEUP, &sn_sal_event)) { - if ((sn_sal_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - sn_sal_tty->ldisc.write_wakeup) - (sn_sal_tty->ldisc.write_wakeup)(sn_sal_tty); - wake_up_interruptible(&sn_sal_tty->write_wait); + if ((sn_sal_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) + && sn_sal_tty->ldisc.write_wakeup) + (sn_sal_tty->ldisc.write_wakeup)((struct tty_struct *)sn_sal_tty); + wake_up_interruptible((wait_queue_head_t *)&sn_sal_tty->write_wait); } + } spin_unlock_irqrestore(&sn_sal_lock, flags); } } @@ -587,12 +588,14 @@ static void sn_sal_timer_poll(unsigned long dummy) { + unsigned long flags; + if (!sn_sal_irq) { - spin_lock(&sn_sal_lock); - receive_chars(NULL); - poll_transmit_chars(); - spin_unlock(&sn_sal_lock); - mod_timer(&sn_sal_timer, jiffies + interrupt_timeout); + spin_lock_irqsave(&sn_sal_lock, flags); + sn_receive_chars(NULL, &flags); + sn_poll_transmit_chars(); + spin_unlock_irqrestore(&sn_sal_lock, flags); + mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout); } } @@ -604,15 +607,10 @@ local_irq_save(flags); sn_sal_interrupt(0, NULL, NULL); local_irq_restore(flags); - mod_timer(&sn_sal_timer, jiffies + interrupt_timeout); + mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout); } /* - * End of "sofware interrupt" routines. - *********************************************************************/ - - -/********************************************************************* * User-level console routines */ @@ -639,7 +637,7 @@ static void sn_sal_close(struct tty_struct *tty, struct file * filp) { - if (atomic_read(&tty->count) == 1) { + if (tty->count == 1) { unsigned long flags; tty->closing = 1; if (tty->driver.flush_buffer) @@ -664,7 +662,7 @@ if (from_user) { while (1) { int c1; - c = CIRC_SPACE_TO_END(xmit.head, xmit.tail, + c = CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE); if (count < c) @@ -672,7 +670,7 @@ if (c <= 0) break; - c -= copy_from_user(sal_tmp_buffer, buf, c); + c -= copy_from_user(sn_tmp_buffer, buf, c); if (!c) { if (!ret) ret = -EFAULT; @@ -683,14 +681,13 @@ * moved since the last time we looked. */ spin_lock_irqsave(&sn_sal_lock, flags); - c1 = CIRC_SPACE_TO_END(xmit.head, xmit.tail, - SN_SAL_BUFFER_SIZE); + c1 = CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE); if (c1 < c) c = c1; - memcpy(xmit.buf + xmit.head, sal_tmp_buffer, c); - xmit.head = ((xmit.head + c) & (SN_SAL_BUFFER_SIZE - 1)); + memcpy(xmit.cb_buf + xmit.cb_head, sn_tmp_buffer, c); + xmit.cb_head = ((xmit.cb_head + c) & (SN_SAL_BUFFER_SIZE - 1)); spin_unlock_irqrestore(&sn_sal_lock, flags); buf += c; @@ -699,20 +696,19 @@ } } else { /* The buffer passed in isn't coming from userland, - * so cut out the middleman (sal_tmp_buffer). + * so cut out the middleman (sn_tmp_buffer). */ spin_lock_irqsave(&sn_sal_lock, flags); while (1) { - c = CIRC_SPACE_TO_END(xmit.head, xmit.tail, - SN_SAL_BUFFER_SIZE); + c = CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE); if (count < c) c = count; if (c <= 0) { break; } - memcpy(xmit.buf + xmit.head, buf, c); - xmit.head = ((xmit.head + c) & (SN_SAL_BUFFER_SIZE - 1)); + memcpy(xmit.cb_buf + xmit.cb_head, buf, c); + xmit.cb_head = ((xmit.cb_head + c) & (SN_SAL_BUFFER_SIZE - 1)); buf += c; count -= c; ret += c; @@ -721,10 +717,9 @@ } spin_lock_irqsave(&sn_sal_lock, flags); - if (xmit.head != xmit.tail && - !(tty && (tty->stopped || tty->hw_stopped))) - if (sn_sal_ops->wakeup_transmit) - sn_sal_ops->wakeup_transmit(); + if (xmit.cb_head != xmit.cb_tail && !(tty && (tty->stopped || tty->hw_stopped))) + if (sn_func->sal_wakeup_transmit) + sn_func->sal_wakeup_transmit(); spin_unlock_irqrestore(&sn_sal_lock, flags); return ret; @@ -737,10 +732,11 @@ unsigned long flags; spin_lock_irqsave(&sn_sal_lock, flags); - if (CIRC_SPACE(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE) != 0) { - xmit.buf[xmit.head] = ch; - xmit.head = (xmit.head + 1) & (SN_SAL_BUFFER_SIZE-1); - sn_sal_ops->wakeup_transmit(); + if (CIRC_SPACE(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) != 0) { + xmit.cb_buf[xmit.cb_head] = ch; + xmit.cb_head = (xmit.cb_head + 1) & (SN_SAL_BUFFER_SIZE-1); + if ( sn_func->sal_wakeup_transmit ) + sn_func->sal_wakeup_transmit(); } spin_unlock_irqrestore(&sn_sal_lock, flags); } @@ -752,9 +748,9 @@ unsigned long flags; spin_lock_irqsave(&sn_sal_lock, flags); - if (CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE)) - if (sn_sal_ops->wakeup_transmit) - sn_sal_ops->wakeup_transmit(); + if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE)) + if (sn_func->sal_wakeup_transmit) + sn_func->sal_wakeup_transmit(); spin_unlock_irqrestore(&sn_sal_lock, flags); } @@ -766,7 +762,7 @@ int space; spin_lock_irqsave(&sn_sal_lock, flags); - space = CIRC_SPACE(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE); + space = CIRC_SPACE(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE); spin_unlock_irqrestore(&sn_sal_lock, flags); return space; } @@ -779,23 +775,13 @@ int space; spin_lock_irqsave(&sn_sal_lock, flags); - space = CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE); + space = CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE); DPRINTF("<%d>", space); spin_unlock_irqrestore(&sn_sal_lock, flags); return space; } -static int -sn_sal_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - /* nothing supported */ - - return -ENOIOCTLCMD; -} - - static void sn_sal_flush_buffer(struct tty_struct *tty) { @@ -803,13 +789,12 @@ /* drop everything */ spin_lock_irqsave(&sn_sal_lock, flags); - xmit.head = xmit.tail = 0; + xmit.cb_head = xmit.cb_tail = 0; spin_unlock_irqrestore(&sn_sal_lock, flags); /* wake up tty level */ wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); } @@ -841,11 +826,10 @@ { int len = 0; off_t begin = 0; - extern nasid_t get_console_nasid(void); - len += sprintf(page, "sn_serial: revision:%s nasid:%d irq:%d tx:%d rx:%d\n", - serial_revdate, get_console_nasid(), sn_sal_irq, - tx_count, rx_count); + len += sprintf(page, "sn_serial: nasid:%d irq:%d tx:%d rx:%d\n", + snia_get_console_nasid(), sn_sal_irq, + sn_total_tx_count, sn_total_rx_count); *eof = 1; if (off >= len+begin) @@ -857,39 +841,38 @@ static struct tty_driver sn_sal_driver = { - .magic = TTY_DRIVER_MAGIC, - .driver_name = "sn_serial", + .magic = TTY_DRIVER_MAGIC, + .driver_name = "sn_serial", #if defined(CONFIG_DEVFS_FS) - .name = "tts/%d", + .name = "tts/%d", #else - .name = "ttyS", + .name = "ttyS", #endif - .major = TTY_MAJOR, - .minor_start = SN_SAL_MINOR, - .num = 1, - .type = TTY_DRIVER_TYPE_SERIAL, - .subtype = SN_SAL_SUBTYPE, - .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, - .refcount = &sn_sal_refcount, - .table = &sn_sal_table, - .termios = &sn_sal_termios, + .major = TTY_MAJOR, + .minor_start = SN_SAL_MINOR, + .num = 1, + .type = TTY_DRIVER_TYPE_SERIAL, + .subtype = SN_SAL_SUBTYPE, + .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, + .refcount = &sn_sal_refcount, + .table = &sn_sal_table, + .termios = &sn_sal_termios, .termios_locked = &sn_sal_termios_locked, - .open = sn_sal_open, - .close = sn_sal_close, - .write = sn_sal_write, - .put_char = sn_sal_put_char, - .flush_chars = sn_sal_flush_chars, - .write_room = sn_sal_write_room, + .open = sn_sal_open, + .close = sn_sal_close, + .write = sn_sal_write, + .put_char = sn_sal_put_char, + .flush_chars = sn_sal_flush_chars, + .write_room = sn_sal_write_room, .chars_in_buffer = sn_sal_chars_in_buffer, - .ioctl = sn_sal_ioctl, - .hangup = sn_sal_hangup, + .hangup = sn_sal_hangup, .wait_until_sent = sn_sal_wait_until_sent, - .read_proc = sn_sal_read_proc, + .read_proc = sn_sal_read_proc, }; /* sn_sal_init wishlist: - * - allocate sal_tmp_buffer + * - allocate sn_tmp_buffer * - fix up the tty_driver struct * - turn on receive interrupts * - do any termios twiddling once and for all @@ -902,19 +885,21 @@ static void __init sn_sal_switch_to_asynch(void) { - debug_printf("sn_serial: about to switch to asynchronous console\n"); + unsigned long flags; + + sn_debug_printf("sn_serial: about to switch to asynchronous console\n"); /* without early_printk, we may be invoked late enough to race * with other cpus doing console IO at this point, however * console interrupts will never be enabled */ - spin_lock(&sn_sal_lock); + spin_lock_irqsave(&sn_sal_lock, flags); /* early_printk invocation may have done this for us */ - if (!sn_sal_ops) { + if (!sn_func) { if (IS_RUNNING_ON_SIMULATOR()) - sn_sal_ops = &sim_ops; + sn_func = &sim_ops; else - sn_sal_ops = &poll_ops; + sn_func = &poll_ops; } /* we can't turn on the console interrupt (as request_irq @@ -926,17 +911,17 @@ sn_sal_timer.function = sn_sal_timer_poll; if (IS_RUNNING_ON_SIMULATOR()) - interrupt_timeout = 6; - else + sn_interrupt_timeout = 6; + else { /* 960cps / 16 char FIFO = 60HZ - HZ / (SN_SAL_FIFO_SPEED_CPS / SN_SAL_FIFO_DEPTH) */ - interrupt_timeout = HZ * SN_SAL_UART_FIFO_DEPTH / - SN_SAL_UART_FIFO_SPEED_CPS; - - mod_timer(&sn_sal_timer, jiffies + interrupt_timeout); + * HZ / (SN_SAL_FIFO_SPEED_CPS / SN_SAL_FIFO_DEPTH) */ + sn_interrupt_timeout = HZ * SN_SAL_UART_FIFO_DEPTH + / SN_SAL_UART_FIFO_SPEED_CPS; + } + mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout); sn_sal_is_asynch = 1; - spin_unlock(&sn_sal_lock); + spin_unlock_irqrestore(&sn_sal_lock, flags); } static void __init @@ -944,17 +929,19 @@ { int irq; - debug_printf("sn_serial: switching to interrupt driven console\n"); + sn_debug_printf("sn_serial: switching to interrupt driven console\n"); irq = sn_sal_connect_interrupt(); if (irq) { unsigned long flags; spin_lock_irqsave(&sn_sal_lock, flags); + /* sn_sal_irq is a global variable. When it's set to * a non-zero value, we stop polling for input (since * interrupts should now be enabled). */ sn_sal_irq = irq; - sn_sal_ops = &intr_ops; + sn_func = &intr_ops; + /* turn on receive interrupts */ ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV); @@ -965,9 +952,9 @@ if (CONSOLE_RESTART) { /* kick the console every once in a while in * case we miss an interrupt */ - interrupt_timeout = 20*HZ; + sn_interrupt_timeout = 20*HZ; sn_sal_timer.function = sn_sal_timer_restart; - mod_timer(&sn_sal_timer, jiffies + interrupt_timeout); + mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout); } spin_unlock_irqrestore(&sn_sal_lock, flags); } @@ -989,8 +976,7 @@ if (!sn_sal_is_asynch) sn_sal_switch_to_asynch(); - /* at this point (module_init) we can try to turn on - * interrupts */ + /* at this point (module_init) we can try to turn on interrupts */ if (!IS_RUNNING_ON_SIMULATOR()) sn_sal_switch_to_interrupts(); @@ -1011,26 +997,14 @@ static void __exit sn_sal_module_exit(void) { - unsigned long flags; - int e; - del_timer_sync(&sn_sal_timer); - spin_lock_irqsave(&sn_sal_lock, flags); - if ((e = tty_unregister_driver(&sn_sal_driver))) - printk(KERN_ERR "sn_serial: failed to unregister driver (%d)\n", e); - - spin_unlock_irqrestore(&sn_sal_lock, flags); + tty_unregister_driver(&sn_sal_driver); } module_init(sn_sal_module_init); module_exit(sn_sal_module_exit); /* - * End of user-level console routines. - *********************************************************************/ - - -/********************************************************************* * Kernel console definitions */ @@ -1042,24 +1016,33 @@ static void sn_sal_console_write(struct console *co, const char *s, unsigned count) { - BUG_ON(!sn_sal_is_asynch); + unsigned long flags; - if (count > CIRC_SPACE_TO_END(xmit.head, xmit.tail, + if (count > CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE)) - debug_printf("\n*** SN_SAL_BUFFER_SIZE too small, lost chars\n"); + sn_debug_printf("\n*** SN_SAL_BUFFER_SIZE too small, lost chars\n"); /* somebody really wants this output, might be an * oops, kdb, panic, etc. make sure they get it. */ +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) if (spin_is_locked(&sn_sal_lock)) { synch_flush_xmit(); - sn_sal_ops->puts(s, count); - } else if (in_interrupt()) { - spin_lock(&sn_sal_lock); - synch_flush_xmit(); - spin_unlock(&sn_sal_lock); - sn_sal_ops->puts(s, count); + sn_func->sal_puts(s, count); } else +#endif + if (in_interrupt()) { + spin_lock_irqsave(&sn_sal_lock, flags); + synch_flush_xmit(); + spin_unlock_irqrestore(&sn_sal_lock, flags); + sn_func->sal_puts(s, count); + } else { +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) sn_sal_write(NULL, 0, s, count); +#else + synch_flush_xmit(); + sn_func->sal_puts(s, count); +#endif + } } static kdev_t @@ -1076,18 +1059,13 @@ static struct console sal_console = { - .name = "ttyS", - .write = sn_sal_console_write, - .device = sn_sal_console_device, - .setup = sn_sal_console_setup, - .index = -1 + .name = "ttyS", + .write = sn_sal_console_write, + .device = sn_sal_console_device, + .setup = sn_sal_console_setup, + .index = -1 }; -/* - * End of kernel console definitions. - *********************************************************************/ - - void __init sn_sal_serial_console_init(void) { diff -urN linux-2.4.22-bk27/drivers/scsi/megaraid.c linux-2.4.22-bk28/drivers/scsi/megaraid.c --- linux-2.4.22-bk27/drivers/scsi/megaraid.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.22-bk28/drivers/scsi/megaraid.c 2003-10-02 02:49:34.000000000 -0700 @@ -9,7 +9,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version : v1.18f (Dec 10, 2002) + * Version : v1.18k (Aug 28, 2003) * * Description: Linux device driver for LSI Logic MegaRAID controller * @@ -512,6 +512,54 @@ * * remove GFP_DMA flag for ioctl. This was causing overrun of DMA buffers. * + * Version 1.18g + * Fri Jan 31 18:29:25 EST 2003 - Atul Mukker + * + * Write the interrupt valid signature 0x10001234 as soon as reading it to + * flush memory caches. + * + * While sending back the inquiry information, check if the original request + * had an associated scatter-gather list and tranfer data from bounce buffer + * accordingly. + * + * Version 1.18h + * Thu Feb 6 17:18:48 EST 2003 - Atul Mukker + * + * Reduce the number of sectors per command to 128 from original value of + * 1024. Big IO sizes along with certain other operation going on in parallel, + * e.g., check consistency and rebuild put a heavy constraint on fW resources + * resulting in aborted commands. + * + * Version 1.18i + * Fri Jun 20 07:39:05 EDT 2003 - Atul Mukker + * + * Request and reserve memory/IO regions. Otherwise a panic occurs if 2.00.x + * driver is loaded on top of 1.18x driver + * + * Prevent memory leak in cases when data transfer from/to application fails + * and ioctl is failing. + * + * Set the PCI dma_mask to default value of 0xFFFFFFFF when we get a handle to + * it. The previous value of 64-bit might be sticky and would cause the memory + * for mailbox and scatter lists to be allocated beyond 4GB. This was observed + * on an Itenium + * + * Version 1.18j + * Mon Jul 7 14:39:55 EDT 2003 - Atul Mukker + * + * Disable /proc/megaraid/stat file to prevent buffer overflow error during + * read of this file. + * + * Add support for ioctls on AMD-64 bit platforms + * - Sreenivas Bagalkote + * + * Version 1.18k + * Thu Aug 28 10:05:11 EDT 2003 - Atul Mukker + * + * Make sure to read the correct status and command ids while in ISR. The + * numstatus and command id array is invalidated before issuing the commands. + * The ISR busy-waits till the correct values are updated in host memory. + * * BUGS: * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that * fails to detect the controller as a pci device on the system. @@ -575,12 +623,27 @@ #include #include +#ifdef __x86_64__ +#include +#endif + #include "sd.h" #include "scsi.h" #include "hosts.h" #include "megaraid.h" +#ifdef __x86_64__ +/* + * The IOCTL cmd received from 32 bit compiled applications + */ + +extern int register_ioctl32_conversion( unsigned int cmd, + int(*handler)(unsigned int, unsigned int, unsigned long, + struct file* )); +extern int unregister_ioctl32_conversion( unsigned int cmd ); +#endif + /* *================================================================ * #Defines @@ -1141,8 +1204,14 @@ switch (SCpnt->cmnd[0]) { case INQUIRY: case READ_CAPACITY: - memcpy (SCpnt->request_buffer, - pScb->bounce_buffer, SCpnt->request_bufflen); + if ( SCpnt->use_sg ) { + sgList = (struct scatterlist *)SCpnt->request_buffer; + memcpy(sgList[0].address, pScb->bounce_buffer, + SCpnt->request_bufflen); + } else { + memcpy (SCpnt->request_buffer, pScb->bounce_buffer, + SCpnt->request_bufflen); + } break; } #endif @@ -2202,30 +2271,22 @@ megaCfg = (mega_host_config *) devp; mbox = (mega_mailbox *) tmpBox; - if (megaCfg->host->irq == irq) { - if (megaCfg->flag & IN_ISR) { - TRACE (("ISR called reentrantly!!\n")); - printk ("ISR called reentrantly!!\n"); - } - megaCfg->flag |= IN_ISR; - - if (mega_busyWaitMbox (megaCfg)) { - printk (KERN_WARNING "Error: mailbox busy in isr!\n"); - } + IO_LOCK; /* Check if a valid interrupt is pending */ if (megaCfg->flag & BOARD_QUARTZ) { dword = RDOUTDOOR (megaCfg); if (dword != 0x10001234) { /* Spurious interrupt */ - megaCfg->flag &= ~IN_ISR; + IO_UNLOCK; return; } + WROUTDOOR (megaCfg, 0x10001234); } else { byte = READ_PORT (megaCfg->host->io_port, INTR_PORT); if ((byte & VALID_INTR_BYTE) == 0) { /* Spurious interrupt */ - megaCfg->flag &= ~IN_ISR; + IO_UNLOCK; return; } WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte); @@ -2234,58 +2295,27 @@ for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++) completed[idx] = 0; - IO_LOCK; megaCfg->nInterrupts++; - qCnt = 0xff; while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ; - - qStatus = 0xff; - while ((qStatus = megaCfg->mbox->status) == 0xFF) ; + megaCfg->mbox->numstatus = 0xFF; /* Get list of completed requests */ for (idx = 0; idx < qCnt; idx++) { - while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) { - printk ("p"); - } - completed[idx] = sIdx; - sIdx = 0xFF; + while ((completed[idx] = megaCfg->mbox->completed[idx]) == 0xFF); + megaCfg->mbox->completed[idx] = 0xFF; } + qStatus = megaCfg->mbox->status; + if (megaCfg->flag & BOARD_QUARTZ) { - WROUTDOOR (megaCfg, dword); /* Acknowledge interrupt */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - /* In this case mbox contains physical address */ -#if 0 - WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2); -#else - WRINDOOR (megaCfg, 0x2); -#endif - -#else - -#if 0 - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2); -#else WRINDOOR (megaCfg, 0x2); -#endif - -#endif - -#if 0 while (RDINDOOR (megaCfg) & 0x02) ; -#endif } else { CLEAR_INTR (megaCfg->host->io_port); } -#if DEBUG - if (qCnt >= MAX_FIRMWARE_STATUS) { - printk ("megaraid_isr: cmplt=%d ", qCnt); - } -#endif - for (idx = 0; idx < qCnt; idx++) { sIdx = completed[idx]; if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) { @@ -2355,26 +2385,24 @@ mega_runpendq (megaCfg); IO_UNLOCK; - } - } /*==================================================*/ /* Wait until the controller's mailbox is available */ /*==================================================*/ -static int mega_busyWaitMbox (mega_host_config * megaCfg) +static inline int mega_busyWaitMbox (mega_host_config * megaCfg) { mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox; long counter; - for (counter = 0; counter < 10000; counter++) { + for (counter = 0; counter < 10; counter++) { if (!mbox->busy) { return 0; } - udelay (100); + udelay (1); } - return -1; /* give up after 1 second */ + return -1; /* give up after 10 usecs */ } /*===================================================== @@ -2409,6 +2437,7 @@ u32 phys_mbox; #endif u8 retval = -1; + int i; mboxData[0x1] = (pScb ? pScb->idx + 1 : 0xFE); /* Set cmdid */ mboxData[0xF] = 1; /* Set busy */ @@ -2420,25 +2449,8 @@ phys_mbox = virt_to_bus (megaCfg->mbox); #endif -#if DEBUG - ShowMbox (pScb); -#endif - /* Wait until mailbox is free */ if (mega_busyWaitMbox (megaCfg)) { - printk ("Blocked mailbox......!!\n"); - udelay (1000); - -#if DEBUG - showMbox (pLastScb); -#endif - - /* Abort command */ - if (pScb == NULL) { - TRACE (("NULL pScb in megaIssue\n")); - printk ("NULL pScb in megaIssue\n"); - } - mega_cmd_done (megaCfg, pScb, 0x08); return -1; } @@ -2486,13 +2498,10 @@ WRINDOOR (megaCfg, phys_mbox | 0x1); while (mbox->numstatus == 0xFF) ; - while (mbox->status == 0xFF) ; while (mbox->mraid_poll != 0x77) ; mbox->mraid_poll = 0; mbox->mraid_ack = 0x77; - - /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234); - WROUTDOOR (megaCfg, cmdDone); */ + mbox->numstatus = 0xFF; if (pScb) { mega_cmd_done (megaCfg, pScb, mbox->status); @@ -2520,15 +2529,14 @@ TRACE (("Error: NULL pScb!\n")); } } + + for (i = 0; i < MAX_FIRMWARE_STATUS; i++) { + mbox->completed[i] = 0xFF; + } + enable_irq (megaCfg->host->irq); retval = mbox->status; } -#if DEBUG - while (mega_busyWaitMbox (megaCfg)) { - printk(KERN_ERR "Blocked mailbox on exit......!\n"); - udelay (1000); - } -#endif return retval; } @@ -2964,15 +2972,15 @@ int i, j; -#if BITS_PER_LONG==64 - u64 megaBase; -#else - u32 megaBase; -#endif + unsigned long megaBase; + unsigned long tbase; u16 pciIdx = 0; u16 numFound = 0; u16 subsysid, subsysvid; + u8 did_mem_map_f = 0; + u8 did_io_map_f = 0; + u8 did_scsi_register_f = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) /* 0x20100 */ while (!pcibios_find_device @@ -2991,6 +2999,17 @@ pciBus = pdev->bus->number; pciDevFun = pdev->devfn; #endif + + /* + * Set the dma_mask to default value. It might be sticky from previous + * insmod-rmmod sequence + */ + pdev->dma_mask = 0xFFFFFFFF; + + did_mem_map_f = 0; + did_io_map_f = 0; + did_scsi_register_f = 0; + if ((flag & BOARD_QUARTZ) && (skip_id == -1)) { if( (pciVendor == PCI_VENDOR_ID_PERC4_DI_YSTONE && pciDev == PCI_DEVICE_ID_PERC4_DI_YSTONE) || @@ -3041,6 +3060,7 @@ if( (subsysvid != AMI_SUBSYS_ID) && (subsysvid != DELL_SUBSYS_ID) && (subsysvid != LSI_SUBSYS_ID) && + (subsysvid != INTEL_SUBSYS_ID) && (subsysvid != HP_SUBSYS_ID) ) continue; } @@ -3065,22 +3085,55 @@ megaIrq = pdev->irq; #endif + tbase = megaBase; + pciIdx++; if (flag & BOARD_QUARTZ) { + megaBase &= PCI_BASE_ADDRESS_MEM_MASK; + + if( ! request_mem_region(megaBase, 128, + "MegaRAID: LSI Logic Corporation" ) ) { + + printk(KERN_WARNING "megaraid: mem region busy!\n"); + + continue; + } + megaBase = (long) ioremap (megaBase, 128); - if (!megaBase) + + if (!megaBase) { + + printk(KERN_WARNING "megaraid: could not map hba memory!\n"); + + release_mem_region(tbase, 128); + continue; + } + did_mem_map_f = 1; + } else { megaBase &= PCI_BASE_ADDRESS_IO_MASK; megaBase += 0x10; + + if( ! request_region(megaBase, 16, + "MegaRAID: LSI Logic Corporation") ) { + + printk(KERN_WARNING "megaraid: region busy.\n"); + + continue; + } + did_io_map_f = 1; + } /* Initialize SCSI Host structure */ host = scsi_register (pHostTmpl, sizeof (mega_host_config)); if (!host) - goto err_unmap; + goto fail_attach; + + did_scsi_register_f = 1; /* * Comment the following initialization if you know 'max_sectors' is @@ -3088,7 +3141,7 @@ * This field was introduced in Linus's kernel 2.4.7pre3 and it * greatly increases the IO performance - AM */ - host->max_sectors = 1024; + host->max_sectors = 128; scsi_set_pci_device(host, pdev); megaCfg = (mega_host_config *) host->hostdata; @@ -3130,11 +3183,8 @@ megaCfg->host->unique_id = (pciBus << 8) | pciDevFun; megaCtlrs[numCtlrs] = megaCfg; - if (!(flag & BOARD_QUARTZ)) { - - /* Request our IO Range */ - if( !request_region(megaBase, 16, "megaraid") ) - goto err_unregister; + if (flag & BOARD_QUARTZ) { + megaCfg->host->base = tbase; } /* Request our IRQ */ @@ -3143,7 +3193,7 @@ printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!\n", megaIrq); - goto err_release; + goto fail_attach; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) @@ -3265,8 +3315,7 @@ sizeof (mega_mailbox64), (void *) megaCfg->mailbox64ptr, megaCfg->dma_handle64); - scsi_unregister (host); - continue; + goto fail_attach; } /* @@ -3301,14 +3350,17 @@ #endif #endif continue; - err_release: - if (flag & BOARD_QUARTZ) - release_region (megaBase, 16); - err_unregister: - scsi_unregister (host); - err_unmap: - if (flag & BOARD_QUARTZ) - iounmap ((void *) megaBase); +fail_attach: + if( did_mem_map_f ) { + iounmap((void *)megaBase); + release_mem_region(tbase, 128); + } + if( did_io_map_f ) { + release_region(megaBase, 16); + } + if( did_scsi_register_f ) { + scsi_unregister (host); + } } return numFound; } @@ -3408,6 +3460,12 @@ } init_MUTEX (&mimd_entry_mtx); +#ifdef __x86_64__ + /* + * Register the 32-bit ioctl conversion + */ + register_ioctl32_conversion( MEGAIOCCMD, sys_ioctl ); +#endif } return count; @@ -3439,6 +3497,7 @@ /* Free our resources */ if (megaCfg->flag & BOARD_QUARTZ) { iounmap ((void *) megaCfg->base); + release_mem_region(megaCfg->host->base, 128); } else { release_region (megaCfg->host->io_port, 16); } @@ -3485,6 +3544,9 @@ unregister_chrdev (major, "megadev"); unregister_reboot_notifier (&mega_notifier); +#ifdef __x86_64__ + unregister_ioctl32_conversion( MEGAIOCCMD ); +#endif return 0; } @@ -4235,7 +4297,6 @@ static int proc_read_stat (char *page, char **start, off_t offset, int count, int *eof, void *data) { - int i; mega_host_config *megaCfg = (mega_host_config *) data; *start = page; @@ -4244,6 +4305,11 @@ proc_printf (megaCfg, "Interrupts Collected = %lu\n", megaCfg->nInterrupts); + proc_printf (megaCfg, "INTERFACE DISABLED\n"); + COPY_BACK; + return count; + +#if 0 // can cause buffer overrun with 40 logical drives and IO information for (i = 0; i < megaCfg->numldrv; i++) { proc_printf (megaCfg, "Logical Drive %d:\n", i); @@ -4259,6 +4325,7 @@ COPY_BACK; return count; +#endif } static int proc_read_status (char *page, char **start, off_t offset, @@ -4896,16 +4963,16 @@ if( kvaddr == NULL ) { printk(KERN_WARNING "megaraid:allocation failed\n"); ret = -ENOMEM; - goto out; + goto out_ioctl_cmd_new; } ioc.ui.fcs.buffer = kvaddr; if (inlen) { /* copyin the user data */ - if (copy_from_user(kvaddr, (char *)uaddr, length )) { - ret = -EFAULT; - goto out; + if( copy_from_user(kvaddr, (char *)uaddr, length ) ) { + ret = -EFAULT; + goto out_ioctl_cmd_new; } } } @@ -4923,10 +4990,9 @@ down(&mimd_ioctl_sem); if( !scsicmd->result && outlen ) { - if (copy_to_user(uaddr, kvaddr, length)) - { - ret = -EFAULT; - goto out; + if (copy_to_user(uaddr, kvaddr, length)) { + return -EFAULT; + goto out_ioctl_cmd_new; } } @@ -4946,7 +5012,8 @@ put_user (scsicmd->result, &uioc->mbox[17]); } -out: +out_ioctl_cmd_new: + if (kvaddr) { dma_free_consistent(pdevp, length, kvaddr, dma_addr); } @@ -5047,12 +5114,8 @@ if( kvaddr == NULL ) { printk (KERN_WARNING "megaraid:allocation failed\n"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */ - kfree(scsicmd); -#else - scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd)); -#endif - return -ENOMEM; + ret = -ENOMEM; + goto out_ioctl_cmd; } ioc.data = kvaddr; @@ -5060,9 +5123,15 @@ if (inlen) { if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) { /* copyin the user data */ - copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen); + if( copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen)){ + ret = -EFAULT; + goto out_ioctl_cmd; + } } else { - copy_from_user (kvaddr, uaddr, inlen); + if( copy_from_user (kvaddr, uaddr, inlen) ) { + ret = -EFAULT; + goto out_ioctl_cmd; + } } } } @@ -5080,11 +5149,15 @@ if (!scsicmd->result && outlen) { if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) { - if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) + if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) { ret = -EFAULT; + goto out_ioctl_cmd; + } } else { - if (copy_to_user (uaddr, kvaddr, outlen)) + if (copy_to_user (uaddr, kvaddr, outlen)) { ret = -EFAULT; + goto out_ioctl_cmd; + } } } @@ -5109,6 +5182,8 @@ put_user (scsicmd->result, &uioc->mbox[17]); /* status */ } +out_ioctl_cmd: + if (kvaddr) { dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr ); } diff -urN linux-2.4.22-bk27/drivers/scsi/megaraid.h linux-2.4.22-bk28/drivers/scsi/megaraid.h --- linux-2.4.22-bk27/drivers/scsi/megaraid.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22-bk28/drivers/scsi/megaraid.h 2003-10-02 02:49:34.000000000 -0700 @@ -30,7 +30,8 @@ #define M_RD_IOCTL_CMD_NEW 0x81 #define M_RD_DRIVER_IOCTL_INTERFACE 0x82 -#define MEGARAID_VERSION "v1.18f (Release Date: Tue Dec 10 09:54:39 EST 2002)\n" +#define MEGARAID_VERSION "v1.18k (Release Date: Thu Aug 28 10:05:11 EDT 2003)\n" + #define MEGARAID_IOCTL_VERSION 114 @@ -190,6 +191,7 @@ #define AMI_SUBSYS_ID 0x101E #define DELL_SUBSYS_ID 0x1028 #define HP_SUBSYS_ID 0x103C +#define INTEL_SUBSYS_ID 0x8086 #define AMI_SIGNATURE 0x3344 #define AMI_SIGNATURE_471 0xCCCC @@ -899,7 +901,9 @@ * Defines for Driver IOCTL interface, Op-code:M_RD_DRIVER_IOCTL_INTERFACE */ #define MEGAIOC_MAGIC 'm' -#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0) /* Mega IOCTL command */ + +/* Mega IOCTL command */ +#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t) #define MEGAIOC_QNADAP 'm' /* Query # of adapters */ #define MEGAIOC_QDRVRVER 'e' /* Query driver version */ diff -urN linux-2.4.22-bk27/include/acpi/acconfig.h linux-2.4.22-bk28/include/acpi/acconfig.h --- linux-2.4.22-bk27/include/acpi/acconfig.h 2003-10-02 02:49:31.000000000 -0700 +++ linux-2.4.22-bk28/include/acpi/acconfig.h 2003-10-02 02:49:34.000000000 -0700 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20030916 +#define ACPI_CA_VERSION 0x20030918 /* Maximum objects in the various object caches */ diff -urN linux-2.4.22-bk27/include/acpi/acdisasm.h linux-2.4.22-bk28/include/acpi/acdisasm.h --- linux-2.4.22-bk27/include/acpi/acdisasm.h 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.22-bk28/include/acpi/acdisasm.h 2003-10-02 02:49:34.000000000 -0700 @@ -152,10 +152,6 @@ acpi_dm_decode_internal_object ( union acpi_operand_object *obj_desc); -void -acpi_dm_decode_node ( - struct acpi_namespace_node *node); - u32 acpi_dm_block_type ( union acpi_parse_object *op); diff -urN linux-2.4.22-bk27/include/acpi/acstruct.h linux-2.4.22-bk28/include/acpi/acstruct.h --- linux-2.4.22-bk27/include/acpi/acstruct.h 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.22-bk28/include/acpi/acstruct.h 2003-10-02 02:49:34.000000000 -0700 @@ -91,11 +91,12 @@ struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */ union acpi_operand_object **caller_return_desc; union acpi_generic_state *control_state; /* List of control states (nested IFs) */ + struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */ struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */ struct acpi_namespace_node *method_call_node; /* Called method Node*/ union acpi_parse_object *method_call_op; /* method_call Op if running a method */ union acpi_operand_object *method_desc; /* Method descriptor if running a method */ - struct acpi_namespace_node *method_node; /* Method Node if running a method */ + struct acpi_namespace_node *method_node; /* Method node if running a method. */ union acpi_parse_object *op; /* Current parser op */ union acpi_operand_object *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */ const struct acpi_opcode_info *op_info; /* Info on current opcode */ diff -urN linux-2.4.22-bk27/mm/mmap.c linux-2.4.22-bk28/mm/mmap.c --- linux-2.4.22-bk27/mm/mmap.c 2003-10-02 02:49:32.000000000 -0700 +++ linux-2.4.22-bk28/mm/mmap.c 2003-10-02 02:49:35.000000000 -0700 @@ -1041,6 +1041,9 @@ if (!len) return addr; + if ((addr + len) > TASK_SIZE || (addr + len) < addr) + return -EINVAL; + /* * mlock MCL_FUTURE? */ diff -urN linux-2.4.22-bk27/net/core/dev.c linux-2.4.22-bk28/net/core/dev.c --- linux-2.4.22-bk27/net/core/dev.c 2003-10-02 02:49:32.000000000 -0700 +++ linux-2.4.22-bk28/net/core/dev.c 2003-10-02 02:49:35.000000000 -0700 @@ -1570,8 +1570,8 @@ #ifdef CONFIG_NET_HW_FLOWCONTROL if (queue->throttle && queue->input_pkt_queue.qlen < no_cong_thresh ) { + queue->throttle = 0; if (atomic_dec_and_test(&netdev_dropping)) { - queue->throttle = 0; netdev_wakeup(); break; } diff -urN linux-2.4.22-bk27/net/ipv4/arp.c linux-2.4.22-bk28/net/ipv4/arp.c --- linux-2.4.22-bk27/net/ipv4/arp.c 2003-10-02 02:49:32.000000000 -0700 +++ linux-2.4.22-bk28/net/ipv4/arp.c 2003-10-02 02:49:35.000000000 -0700 @@ -852,8 +852,15 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) { - struct arphdr *arp = skb->nh.arph; + struct arphdr *arp; + /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ + if (!pskb_may_pull(skb, (sizeof(struct arphdr) + + (2 * dev->addr_len) + + (2 * sizeof(u32))))) + goto freeskb; + + arp = skb->nh.arph; if (arp->ar_hln != dev->addr_len || dev->flags & IFF_NOARP || skb->pkt_type == PACKET_OTHERHOST || @@ -864,11 +871,6 @@ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) goto out_of_mem; - if (skb_is_nonlinear(skb)) { - if (skb_linearize(skb, GFP_ATOMIC) != 0) - goto freeskb; - } - return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process); freeskb: diff -urN linux-2.4.22-bk27/net/sched/sch_generic.c linux-2.4.22-bk28/net/sched/sch_generic.c --- linux-2.4.22-bk27/net/sched/sch_generic.c 2003-10-02 02:49:32.000000000 -0700 +++ linux-2.4.22-bk28/net/sched/sch_generic.c 2003-10-02 02:49:35.000000000 -0700 @@ -427,7 +427,6 @@ dev = qdisc->dev; -#ifdef CONFIG_NET_SCHED if (dev) { struct Qdisc *q, **qp; for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) { @@ -440,7 +439,6 @@ #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&qdisc->stats); #endif -#endif if (ops->reset) ops->reset(qdisc); if (ops->destroy)